[M120 Migration][Gamepad]Add gamepad event latency Test code
[platform/framework/web/chromium-efl.git] / build / gn_helpers_unittest.py
old mode 100644 (file)
new mode 100755 (executable)
index 43c084b..6e305d7
@@ -1,15 +1,84 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
+#!/usr/bin/env python3
+# Copyright 2016 The Chromium Authors
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import gn_helpers
+import os
+import pathlib
+import shutil
+import sys
+import tempfile
+import textwrap
 import unittest
+from unittest import mock
+
+import gn_helpers
+
 
 class UnitTest(unittest.TestCase):
   def test_ToGNString(self):
-    self.assertEqual(
-        gn_helpers.ToGNString([1, 'two', [ '"thr$\\', True, False, [] ]]),
-        '[ 1, "two", [ "\\"thr\\$\\\\", true, false, [  ] ] ]')
+    test_cases = [
+        (42, '42', '42'), ('foo', '"foo"', '"foo"'), (True, 'true', 'true'),
+        (False, 'false', 'false'), ('', '""', '""'),
+        ('\\$"$\\', '"\\\\\\$\\"\\$\\\\"', '"\\\\\\$\\"\\$\\\\"'),
+        (' \t\r\n', '" $0x09$0x0D$0x0A"', '" $0x09$0x0D$0x0A"'),
+        (u'\u2713', '"$0xE2$0x9C$0x93"', '"$0xE2$0x9C$0x93"'),
+        ([], '[  ]', '[]'), ([1], '[ 1 ]', '[\n  1\n]\n'),
+        ([3, 1, 4, 1], '[ 3, 1, 4, 1 ]', '[\n  3,\n  1,\n  4,\n  1\n]\n'),
+        (['a', True, 2], '[ "a", true, 2 ]', '[\n  "a",\n  true,\n  2\n]\n'),
+        ({
+            'single': 'item'
+        }, 'single = "item"\n', 'single = "item"\n'),
+        ({
+            'kEy': 137,
+            '_42A_Zaz_': [False, True]
+        }, '_42A_Zaz_ = [ false, true ]\nkEy = 137\n',
+         '_42A_Zaz_ = [\n  false,\n  true\n]\nkEy = 137\n'),
+        ([1, 'two',
+          ['"thr,.$\\', True, False, [],
+           u'(\u2713)']], '[ 1, "two", [ "\\"thr,.\\$\\\\", true, false, ' +
+         '[  ], "($0xE2$0x9C$0x93)" ] ]', '''[
+  1,
+  "two",
+  [
+    "\\"thr,.\\$\\\\",
+    true,
+    false,
+    [],
+    "($0xE2$0x9C$0x93)"
+  ]
+]
+'''),
+        ({
+            's': 'foo',
+            'n': 42,
+            'b': True,
+            'a': [3, 'x']
+        }, 'a = [ 3, "x" ]\nb = true\nn = 42\ns = "foo"\n',
+         'a = [\n  3,\n  "x"\n]\nb = true\nn = 42\ns = "foo"\n'),
+        (
+            [[[], [[]]], []],
+            '[ [ [  ], [ [  ] ] ], [  ] ]',
+            '[\n  [\n    [],\n    [\n      []\n    ]\n  ],\n  []\n]\n',
+        ),
+        (
+            [{
+                'a': 1,
+                'c': {
+                    'z': 8
+                },
+                'b': []
+            }],
+            '[ { a = 1\nb = [  ]\nc = { z = 8 } } ]\n',
+            '[\n  {\n    a = 1\n    b = []\n    c = {\n' +
+            '      z = 8\n    }\n  }\n]\n',
+        )
+    ]
+    for obj, exp_ugly, exp_pretty in test_cases:
+      out_ugly = gn_helpers.ToGNString(obj)
+      self.assertEqual(exp_ugly, out_ugly)
+      out_pretty = gn_helpers.ToGNString(obj, pretty=True)
+      self.assertEqual(exp_pretty, out_pretty)
 
   def test_UnescapeGNString(self):
     # Backslash followed by a \, $, or " means the folling character without
@@ -23,7 +92,7 @@ class UnitTest(unittest.TestCase):
         gn_helpers.FromGNString('[1, -20, true, false,["as\\"", []]]'),
         [ 1, -20, True, False, [ 'as"', [] ] ])
 
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('123 456')
       parser.Parse()
 
@@ -38,10 +107,10 @@ class UnitTest(unittest.TestCase):
     parser = gn_helpers.GNValueParser('123')
     self.assertEqual(parser.ParseNumber(), 123)
 
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('')
       parser.ParseNumber()
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('a123')
       parser.ParseNumber()
 
@@ -49,13 +118,13 @@ class UnitTest(unittest.TestCase):
     parser = gn_helpers.GNValueParser('"asdf"')
     self.assertEqual(parser.ParseString(), 'asdf')
 
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('')  # Empty.
       parser.ParseString()
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('asdf')  # Unquoted.
       parser.ParseString()
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('"trailing')  # Unterminated.
       parser.ParseString()
 
@@ -63,19 +132,39 @@ class UnitTest(unittest.TestCase):
     parser = gn_helpers.GNValueParser('[1,]')  # Optional end comma OK.
     self.assertEqual(parser.ParseList(), [ 1 ])
 
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('')  # Empty.
       parser.ParseList()
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('asdf')  # No [].
       parser.ParseList()
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('[1, 2')  # Unterminated
       parser.ParseList()
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       parser = gn_helpers.GNValueParser('[1 2]')  # No separating comma.
       parser.ParseList()
 
+  def test_ParseScope(self):
+    parser = gn_helpers.GNValueParser('{a = 1}')
+    self.assertEqual(parser.ParseScope(), {'a': 1})
+
+    with self.assertRaises(gn_helpers.GNError):
+      parser = gn_helpers.GNValueParser('')  # Empty.
+      parser.ParseScope()
+    with self.assertRaises(gn_helpers.GNError):
+      parser = gn_helpers.GNValueParser('asdf')  # No {}.
+      parser.ParseScope()
+    with self.assertRaises(gn_helpers.GNError):
+      parser = gn_helpers.GNValueParser('{a = 1')  # Unterminated.
+      parser.ParseScope()
+    with self.assertRaises(gn_helpers.GNError):
+      parser = gn_helpers.GNValueParser('{"a" = 1}')  # Not identifier.
+      parser.ParseScope()
+    with self.assertRaises(gn_helpers.GNError):
+      parser = gn_helpers.GNValueParser('{a = }')  # No value.
+      parser.ParseScope()
+
   def test_FromGNArgs(self):
     # Booleans and numbers should work; whitespace is allowed works.
     self.assertEqual(gn_helpers.FromGNArgs('foo = true\nbar = 1\n'),
@@ -89,10 +178,15 @@ class UnitTest(unittest.TestCase):
     gn_args_lines = [
         '# Top-level comment.',
         'foo = true',
-        'bar = 1  # In-line comment.',
+        'bar = 1  # In-line comment followed by whitespace.',
+        ' ',
+        'baz = false',
     ]
-    self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)),
-                     {'foo': True, 'bar': 1})
+    self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)), {
+        'foo': True,
+        'bar': 1,
+        'baz': False
+    })
 
     # Lists should work.
     self.assertEqual(gn_helpers.FromGNArgs('foo=[1, 2, 3]'),
@@ -102,16 +196,61 @@ class UnitTest(unittest.TestCase):
     self.assertEqual(gn_helpers.FromGNArgs(''), {})
     self.assertEqual(gn_helpers.FromGNArgs(' \n '), {})
 
+    # Comments should work everywhere (and be ignored).
+    gn_args_lines = [
+        '# Top-level comment.',
+        '',
+        '# Variable comment.',
+        'foo = true',
+        'bar = [',
+        '    # Value comment in list.',
+        '    1,',
+        '    2,',
+        ']',
+        '',
+        'baz # Comment anywhere, really',
+        '  = # also here',
+        '    4',
+    ]
+    self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)), {
+        'foo': True,
+        'bar': [1, 2],
+        'baz': 4
+    })
+
+    # Scope should be parsed, even empty ones.
+    gn_args_lines = [
+        'foo = {',
+        '  a = 1',
+        '  b = [',
+        '    { },',
+        '    {',
+        '      c = 1',
+        '    },',
+        '  ]',
+        '}',
+    ]
+    self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)),
+                     {'foo': {
+                         'a': 1,
+                         'b': [
+                             {},
+                             {
+                                 'c': 1,
+                             },
+                         ]
+                     }})
+
     # Non-identifiers should raise an exception.
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       gn_helpers.FromGNArgs('123 = true')
 
     # References to other variables should raise an exception.
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       gn_helpers.FromGNArgs('foo = bar')
 
     # References to functions should raise an exception.
-    with self.assertRaises(gn_helpers.GNException):
+    with self.assertRaises(gn_helpers.GNError):
       gn_helpers.FromGNArgs('foo = exec_script("//build/baz.py")')
 
     # Underscores in identifiers should work.
@@ -122,5 +261,93 @@ class UnitTest(unittest.TestCase):
     self.assertEqual(gn_helpers.FromGNArgs('foo_=true'),
                      {'foo_': True})
 
+  def test_ReplaceImports(self):
+    # Should be a no-op on args inputs without any imports.
+    parser = gn_helpers.GNValueParser(
+        textwrap.dedent("""
+        some_arg1 = "val1"
+        some_arg2 = "val2"
+    """))
+    parser.ReplaceImports()
+    self.assertEqual(
+        parser.input,
+        textwrap.dedent("""
+        some_arg1 = "val1"
+        some_arg2 = "val2"
+    """))
+
+    # A single "import(...)" line should be replaced with the contents of the
+    # file being imported.
+    parser = gn_helpers.GNValueParser(
+        textwrap.dedent("""
+        some_arg1 = "val1"
+        import("//some/args/file.gni")
+        some_arg2 = "val2"
+    """))
+    fake_import = 'some_imported_arg = "imported_val"'
+    builtin_var = '__builtin__' if sys.version_info.major < 3 else 'builtins'
+    open_fun = '{}.open'.format(builtin_var)
+    with mock.patch(open_fun, mock.mock_open(read_data=fake_import)):
+      parser.ReplaceImports()
+    self.assertEqual(
+        parser.input,
+        textwrap.dedent("""
+        some_arg1 = "val1"
+        some_imported_arg = "imported_val"
+        some_arg2 = "val2"
+    """))
+
+    # No trailing parenthesis should raise an exception.
+    with self.assertRaises(gn_helpers.GNError):
+      parser = gn_helpers.GNValueParser(
+          textwrap.dedent('import("//some/args/file.gni"'))
+      parser.ReplaceImports()
+
+    # No double quotes should raise an exception.
+    with self.assertRaises(gn_helpers.GNError):
+      parser = gn_helpers.GNValueParser(
+          textwrap.dedent('import(//some/args/file.gni)'))
+      parser.ReplaceImports()
+
+    # A path that's not source absolute should raise an exception.
+    with self.assertRaises(gn_helpers.GNError):
+      parser = gn_helpers.GNValueParser(
+          textwrap.dedent('import("some/relative/args/file.gni")'))
+      parser.ReplaceImports()
+
+  def test_CreateBuildCommand(self):
+    with tempfile.TemporaryDirectory() as temp_dir:
+      suffix = '.bat' if sys.platform.startswith('win32') else ''
+      self.assertEqual(f'autoninja{suffix}',
+                       gn_helpers.CreateBuildCommand(temp_dir)[0])
+
+      siso_deps = pathlib.Path(temp_dir) / '.siso_deps'
+      siso_deps.touch()
+      self.assertEqual(f'autosiso{suffix}',
+                       gn_helpers.CreateBuildCommand(temp_dir)[0])
+
+      with mock.patch('shutil.which', lambda x: None):
+        cmd = gn_helpers.CreateBuildCommand(temp_dir)
+        self.assertIn('third_party', cmd[0])
+        self.assertIn(f'{os.sep}siso', cmd[0])
+        self.assertEqual(['ninja', '-C', temp_dir], cmd[1:])
+
+      ninja_deps = pathlib.Path(temp_dir) / '.ninja_deps'
+      ninja_deps.touch()
+
+      with self.assertRaisesRegex(Exception, 'Found both'):
+        gn_helpers.CreateBuildCommand(temp_dir)
+
+      siso_deps.unlink()
+      self.assertEqual(f'autoninja{suffix}',
+                       gn_helpers.CreateBuildCommand(temp_dir)[0])
+
+      with mock.patch('shutil.which', lambda x: None):
+        cmd = gn_helpers.CreateBuildCommand(temp_dir)
+        self.assertIn('third_party', cmd[0])
+        self.assertIn(f'{os.sep}ninja', cmd[0])
+        self.assertEqual(['-C', temp_dir], cmd[1:])
+
+
 if __name__ == '__main__':
   unittest.main()