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.
13 class UnitTest(unittest.TestCase):
14 def test_ToGNString(self):
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'),
26 }, 'single = "item"\n', 'single = "item"\n'),
29 '_42A_Zaz_': [False, True]
30 }, '_42A_Zaz_ = [ false, true ]\nkEy = 137\n',
31 '_42A_Zaz_ = [\n false,\n true\n]\nkEy = 137\n'),
33 ['"thr,.$\\', True, False, [],
34 u'(\u2713)']], '[ 1, "two", [ "\\"thr,.\\$\\\\", true, false, ' +
35 '[ ], "($0xE2$0x9C$0x93)" ] ]', '''[
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'),
56 '[ [ [ ], [ [ ] ] ], [ ] ]',
57 '[\n [\n [],\n [\n []\n ]\n ],\n []\n]\n',
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)
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.
70 gn_helpers.UnescapeGNString('\\as\\$\\\\asd\\"'),
73 def test_FromGNString(self):
75 gn_helpers.FromGNString('[1, -20, true, false,["as\\"", []]]'),
76 [ 1, -20, True, False, [ 'as"', [] ] ])
78 with self.assertRaises(gn_helpers.GNError):
79 parser = gn_helpers.GNValueParser('123 456')
82 def test_ParseBool(self):
83 parser = gn_helpers.GNValueParser('true')
84 self.assertEqual(parser.Parse(), True)
86 parser = gn_helpers.GNValueParser('false')
87 self.assertEqual(parser.Parse(), False)
89 def test_ParseNumber(self):
90 parser = gn_helpers.GNValueParser('123')
91 self.assertEqual(parser.ParseNumber(), 123)
93 with self.assertRaises(gn_helpers.GNError):
94 parser = gn_helpers.GNValueParser('')
96 with self.assertRaises(gn_helpers.GNError):
97 parser = gn_helpers.GNValueParser('a123')
100 def test_ParseString(self):
101 parser = gn_helpers.GNValueParser('"asdf"')
102 self.assertEqual(parser.ParseString(), 'asdf')
104 with self.assertRaises(gn_helpers.GNError):
105 parser = gn_helpers.GNValueParser('') # Empty.
107 with self.assertRaises(gn_helpers.GNError):
108 parser = gn_helpers.GNValueParser('asdf') # Unquoted.
110 with self.assertRaises(gn_helpers.GNError):
111 parser = gn_helpers.GNValueParser('"trailing') # Unterminated.
114 def test_ParseList(self):
115 parser = gn_helpers.GNValueParser('[1,]') # Optional end comma OK.
116 self.assertEqual(parser.ParseList(), [ 1 ])
118 with self.assertRaises(gn_helpers.GNError):
119 parser = gn_helpers.GNValueParser('') # Empty.
121 with self.assertRaises(gn_helpers.GNError):
122 parser = gn_helpers.GNValueParser('asdf') # No [].
124 with self.assertRaises(gn_helpers.GNError):
125 parser = gn_helpers.GNValueParser('[1, 2') # Unterminated
127 with self.assertRaises(gn_helpers.GNError):
128 parser = gn_helpers.GNValueParser('[1 2]') # No separating comma.
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})
136 # Whitespace is not required; strings should also work.
137 self.assertEqual(gn_helpers.FromGNArgs('foo="bar baz"'),
140 # Comments should work (and be ignored).
142 '# Top-level comment.',
144 'bar = 1 # In-line comment followed by whitespace.',
148 self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)), {
155 self.assertEqual(gn_helpers.FromGNArgs('foo=[1, 2, 3]'),
158 # Empty strings should return an empty dict.
159 self.assertEqual(gn_helpers.FromGNArgs(''), {})
160 self.assertEqual(gn_helpers.FromGNArgs(' \n '), {})
162 # Non-identifiers should raise an exception.
163 with self.assertRaises(gn_helpers.GNError):
164 gn_helpers.FromGNArgs('123 = true')
166 # References to other variables should raise an exception.
167 with self.assertRaises(gn_helpers.GNError):
168 gn_helpers.FromGNArgs('foo = bar')
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")')
174 # Underscores in identifiers should work.
175 self.assertEqual(gn_helpers.FromGNArgs('_foo = true'),
177 self.assertEqual(gn_helpers.FromGNArgs('foo_bar = true'),
179 self.assertEqual(gn_helpers.FromGNArgs('foo_=true'),
182 def test_ReplaceImports(self):
183 # Should be a no-op on args inputs without any imports.
184 parser = gn_helpers.GNValueParser(
189 parser.ReplaceImports()
197 # A single "import(...)" line should be replaced with the contents of the
198 # file being imported.
199 parser = gn_helpers.GNValueParser(
202 import("//some/args/file.gni")
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()
214 some_imported_arg = "imported_val"
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()
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()
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()
237 if __name__ == '__main__':