Upload upstream chromium 85.0.4183.84
[platform/framework/web/chromium-efl.git] / build / gn_helpers_unittest.py
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import mock
6 import sys
7 import textwrap
8 import unittest
9
10 import gn_helpers
11
12
13 class UnitTest(unittest.TestCase):
14   def test_ToGNString(self):
15     test_cases = [
16         (42, '42', '42'), ('foo', '"foo"', '"foo"'), (True, 'true', 'true'),
17         (False, 'false', 'false'), ('', '""', '""'),
18         ('\\$"$\\', '"\\\\\\$\\"\\$\\\\"', '"\\\\\\$\\"\\$\\\\"'),
19         (' \t\r\n', '" $0x09$0x0D$0x0A"', '" $0x09$0x0D$0x0A"'),
20         (u'\u2713', '"$0xE2$0x9C$0x93"', '"$0xE2$0x9C$0x93"'),
21         ([], '[  ]', '[]'), ([1], '[ 1 ]', '[\n  1\n]\n'),
22         ([3, 1, 4, 1], '[ 3, 1, 4, 1 ]', '[\n  3,\n  1,\n  4,\n  1\n]\n'),
23         (['a', True, 2], '[ "a", true, 2 ]', '[\n  "a",\n  true,\n  2\n]\n'),
24         ({
25             'single': 'item'
26         }, 'single = "item"\n', 'single = "item"\n'),
27         ({
28             'kEy': 137,
29             '_42A_Zaz_': [False, True]
30         }, '_42A_Zaz_ = [ false, true ]\nkEy = 137\n',
31          '_42A_Zaz_ = [\n  false,\n  true\n]\nkEy = 137\n'),
32         ([1, 'two',
33           ['"thr,.$\\', True, False, [],
34            u'(\u2713)']], '[ 1, "two", [ "\\"thr,.\\$\\\\", true, false, ' +
35          '[  ], "($0xE2$0x9C$0x93)" ] ]', '''[
36   1,
37   "two",
38   [
39     "\\"thr,.\\$\\\\",
40     true,
41     false,
42     [],
43     "($0xE2$0x9C$0x93)"
44   ]
45 ]
46 '''),
47         ({
48             's': 'foo',
49             'n': 42,
50             'b': True,
51             'a': [3, 'x']
52         }, 'a = [ 3, "x" ]\nb = true\nn = 42\ns = "foo"\n',
53          'a = [\n  3,\n  "x"\n]\nb = true\nn = 42\ns = "foo"\n'),
54         (
55             [[[], [[]]], []],
56             '[ [ [  ], [ [  ] ] ], [  ] ]',
57             '[\n  [\n    [],\n    [\n      []\n    ]\n  ],\n  []\n]\n',
58         )
59     ]
60     for obj, exp_ugly, exp_pretty in test_cases:
61       out_ugly = gn_helpers.ToGNString(obj)
62       self.assertEqual(exp_ugly, out_ugly)
63       out_pretty = gn_helpers.ToGNString(obj, pretty=True)
64       self.assertEqual(exp_pretty, out_pretty)
65
66   def test_UnescapeGNString(self):
67     # Backslash followed by a \, $, or " means the folling character without
68     # the special meaning. Backslash followed by everything else is a literal.
69     self.assertEqual(
70         gn_helpers.UnescapeGNString('\\as\\$\\\\asd\\"'),
71         '\\as$\\asd"')
72
73   def test_FromGNString(self):
74     self.assertEqual(
75         gn_helpers.FromGNString('[1, -20, true, false,["as\\"", []]]'),
76         [ 1, -20, True, False, [ 'as"', [] ] ])
77
78     with self.assertRaises(gn_helpers.GNError):
79       parser = gn_helpers.GNValueParser('123 456')
80       parser.Parse()
81
82   def test_ParseBool(self):
83     parser = gn_helpers.GNValueParser('true')
84     self.assertEqual(parser.Parse(), True)
85
86     parser = gn_helpers.GNValueParser('false')
87     self.assertEqual(parser.Parse(), False)
88
89   def test_ParseNumber(self):
90     parser = gn_helpers.GNValueParser('123')
91     self.assertEqual(parser.ParseNumber(), 123)
92
93     with self.assertRaises(gn_helpers.GNError):
94       parser = gn_helpers.GNValueParser('')
95       parser.ParseNumber()
96     with self.assertRaises(gn_helpers.GNError):
97       parser = gn_helpers.GNValueParser('a123')
98       parser.ParseNumber()
99
100   def test_ParseString(self):
101     parser = gn_helpers.GNValueParser('"asdf"')
102     self.assertEqual(parser.ParseString(), 'asdf')
103
104     with self.assertRaises(gn_helpers.GNError):
105       parser = gn_helpers.GNValueParser('')  # Empty.
106       parser.ParseString()
107     with self.assertRaises(gn_helpers.GNError):
108       parser = gn_helpers.GNValueParser('asdf')  # Unquoted.
109       parser.ParseString()
110     with self.assertRaises(gn_helpers.GNError):
111       parser = gn_helpers.GNValueParser('"trailing')  # Unterminated.
112       parser.ParseString()
113
114   def test_ParseList(self):
115     parser = gn_helpers.GNValueParser('[1,]')  # Optional end comma OK.
116     self.assertEqual(parser.ParseList(), [ 1 ])
117
118     with self.assertRaises(gn_helpers.GNError):
119       parser = gn_helpers.GNValueParser('')  # Empty.
120       parser.ParseList()
121     with self.assertRaises(gn_helpers.GNError):
122       parser = gn_helpers.GNValueParser('asdf')  # No [].
123       parser.ParseList()
124     with self.assertRaises(gn_helpers.GNError):
125       parser = gn_helpers.GNValueParser('[1, 2')  # Unterminated
126       parser.ParseList()
127     with self.assertRaises(gn_helpers.GNError):
128       parser = gn_helpers.GNValueParser('[1 2]')  # No separating comma.
129       parser.ParseList()
130
131   def test_FromGNArgs(self):
132     # Booleans and numbers should work; whitespace is allowed works.
133     self.assertEqual(gn_helpers.FromGNArgs('foo = true\nbar = 1\n'),
134                      {'foo': True, 'bar': 1})
135
136     # Whitespace is not required; strings should also work.
137     self.assertEqual(gn_helpers.FromGNArgs('foo="bar baz"'),
138                      {'foo': 'bar baz'})
139
140     # Comments should work (and be ignored).
141     gn_args_lines = [
142         '# Top-level comment.',
143         'foo = true',
144         'bar = 1  # In-line comment followed by whitespace.',
145         ' ',
146         'baz = false',
147     ]
148     self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)), {
149         'foo': True,
150         'bar': 1,
151         'baz': False
152     })
153
154     # Lists should work.
155     self.assertEqual(gn_helpers.FromGNArgs('foo=[1, 2, 3]'),
156                      {'foo': [1, 2, 3]})
157
158     # Empty strings should return an empty dict.
159     self.assertEqual(gn_helpers.FromGNArgs(''), {})
160     self.assertEqual(gn_helpers.FromGNArgs(' \n '), {})
161
162     # Non-identifiers should raise an exception.
163     with self.assertRaises(gn_helpers.GNError):
164       gn_helpers.FromGNArgs('123 = true')
165
166     # References to other variables should raise an exception.
167     with self.assertRaises(gn_helpers.GNError):
168       gn_helpers.FromGNArgs('foo = bar')
169
170     # References to functions should raise an exception.
171     with self.assertRaises(gn_helpers.GNError):
172       gn_helpers.FromGNArgs('foo = exec_script("//build/baz.py")')
173
174     # Underscores in identifiers should work.
175     self.assertEqual(gn_helpers.FromGNArgs('_foo = true'),
176                      {'_foo': True})
177     self.assertEqual(gn_helpers.FromGNArgs('foo_bar = true'),
178                      {'foo_bar': True})
179     self.assertEqual(gn_helpers.FromGNArgs('foo_=true'),
180                      {'foo_': True})
181
182   def test_ReplaceImports(self):
183     # Should be a no-op on args inputs without any imports.
184     parser = gn_helpers.GNValueParser(
185         textwrap.dedent("""
186         some_arg1 = "val1"
187         some_arg2 = "val2"
188     """))
189     parser.ReplaceImports()
190     self.assertEqual(
191         parser.input,
192         textwrap.dedent("""
193         some_arg1 = "val1"
194         some_arg2 = "val2"
195     """))
196
197     # A single "import(...)" line should be replaced with the contents of the
198     # file being imported.
199     parser = gn_helpers.GNValueParser(
200         textwrap.dedent("""
201         some_arg1 = "val1"
202         import("//some/args/file.gni")
203         some_arg2 = "val2"
204     """))
205     fake_import = 'some_imported_arg = "imported_val"'
206     builtin_var = '__builtin__' if sys.version_info.major < 3 else 'builtins'
207     open_fun = '{}.open'.format(builtin_var)
208     with mock.patch(open_fun, mock.mock_open(read_data=fake_import)):
209       parser.ReplaceImports()
210     self.assertEqual(
211         parser.input,
212         textwrap.dedent("""
213         some_arg1 = "val1"
214         some_imported_arg = "imported_val"
215         some_arg2 = "val2"
216     """))
217
218     # No trailing parenthesis should raise an exception.
219     with self.assertRaises(gn_helpers.GNError):
220       parser = gn_helpers.GNValueParser(
221           textwrap.dedent('import("//some/args/file.gni"'))
222       parser.ReplaceImports()
223
224     # No double quotes should raise an exception.
225     with self.assertRaises(gn_helpers.GNError):
226       parser = gn_helpers.GNValueParser(
227           textwrap.dedent('import(//some/args/file.gni)'))
228       parser.ReplaceImports()
229
230     # A path that's not source absolute should raise an exception.
231     with self.assertRaises(gn_helpers.GNError):
232       parser = gn_helpers.GNValueParser(
233           textwrap.dedent('import("some/relative/args/file.gni")'))
234       parser.ReplaceImports()
235
236
237 if __name__ == '__main__':
238   unittest.main()