blob: 9356f6aeaf940cd0ae7096288202df022992ced7 [file] [log] [blame]
brettw9dffb542016-01-22 18:40:031# 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
Ben Pastene00156a22020-03-23 18:13:105import mock
6import textwrap
brettw9dffb542016-01-22 18:40:037import unittest
8
Ben Pastene00156a22020-03-23 18:13:109import gn_helpers
10
11
brettw9dffb542016-01-22 18:40:0312class UnitTest(unittest.TestCase):
13 def test_ToGNString(self):
14 self.assertEqual(
15 gn_helpers.ToGNString([1, 'two', [ '"thr$\\', True, False, [] ]]),
16 '[ 1, "two", [ "\\"thr\\$\\\\", true, false, [ ] ] ]')
17
18 def test_UnescapeGNString(self):
19 # Backslash followed by a \, $, or " means the folling character without
20 # the special meaning. Backslash followed by everything else is a literal.
21 self.assertEqual(
22 gn_helpers.UnescapeGNString('\\as\\$\\\\asd\\"'),
23 '\\as$\\asd"')
24
25 def test_FromGNString(self):
26 self.assertEqual(
27 gn_helpers.FromGNString('[1, -20, true, false,["as\\"", []]]'),
28 [ 1, -20, True, False, [ 'as"', [] ] ])
29
Samuel Huang1ea5180e2020-05-25 16:29:4030 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0331 parser = gn_helpers.GNValueParser('123 456')
32 parser.Parse()
33
dprankee031ec22016-04-02 00:17:3434 def test_ParseBool(self):
35 parser = gn_helpers.GNValueParser('true')
36 self.assertEqual(parser.Parse(), True)
37
38 parser = gn_helpers.GNValueParser('false')
39 self.assertEqual(parser.Parse(), False)
40
brettw9dffb542016-01-22 18:40:0341 def test_ParseNumber(self):
42 parser = gn_helpers.GNValueParser('123')
43 self.assertEqual(parser.ParseNumber(), 123)
44
Samuel Huang1ea5180e2020-05-25 16:29:4045 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0346 parser = gn_helpers.GNValueParser('')
47 parser.ParseNumber()
Samuel Huang1ea5180e2020-05-25 16:29:4048 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0349 parser = gn_helpers.GNValueParser('a123')
50 parser.ParseNumber()
51
52 def test_ParseString(self):
53 parser = gn_helpers.GNValueParser('"asdf"')
54 self.assertEqual(parser.ParseString(), 'asdf')
55
Samuel Huang1ea5180e2020-05-25 16:29:4056 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0357 parser = gn_helpers.GNValueParser('') # Empty.
58 parser.ParseString()
Samuel Huang1ea5180e2020-05-25 16:29:4059 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0360 parser = gn_helpers.GNValueParser('asdf') # Unquoted.
61 parser.ParseString()
Samuel Huang1ea5180e2020-05-25 16:29:4062 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0363 parser = gn_helpers.GNValueParser('"trailing') # Unterminated.
64 parser.ParseString()
65
66 def test_ParseList(self):
67 parser = gn_helpers.GNValueParser('[1,]') # Optional end comma OK.
68 self.assertEqual(parser.ParseList(), [ 1 ])
69
Samuel Huang1ea5180e2020-05-25 16:29:4070 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0371 parser = gn_helpers.GNValueParser('') # Empty.
72 parser.ParseList()
Samuel Huang1ea5180e2020-05-25 16:29:4073 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0374 parser = gn_helpers.GNValueParser('asdf') # No [].
75 parser.ParseList()
Samuel Huang1ea5180e2020-05-25 16:29:4076 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0377 parser = gn_helpers.GNValueParser('[1, 2') # Unterminated
78 parser.ParseList()
Samuel Huang1ea5180e2020-05-25 16:29:4079 with self.assertRaises(gn_helpers.GNError):
brettw9dffb542016-01-22 18:40:0380 parser = gn_helpers.GNValueParser('[1 2]') # No separating comma.
81 parser.ParseList()
82
dpranke65d84dc02016-04-06 00:07:1883 def test_FromGNArgs(self):
84 # Booleans and numbers should work; whitespace is allowed works.
85 self.assertEqual(gn_helpers.FromGNArgs('foo = true\nbar = 1\n'),
86 {'foo': True, 'bar': 1})
87
88 # Whitespace is not required; strings should also work.
89 self.assertEqual(gn_helpers.FromGNArgs('foo="bar baz"'),
90 {'foo': 'bar baz'})
91
Ben Pastene9b24d852018-11-06 00:42:0992 # Comments should work (and be ignored).
93 gn_args_lines = [
94 '# Top-level comment.',
95 'foo = true',
Ben Pasteneb75f8ec2020-06-04 22:09:2896 'bar = 1 # In-line comment followed by whitespace.',
97 ' ',
98 'baz = false',
Ben Pastene9b24d852018-11-06 00:42:0999 ]
Ben Pasteneb75f8ec2020-06-04 22:09:28100 self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)), {
101 'foo': True,
102 'bar': 1,
103 'baz': False
104 })
Ben Pastene9b24d852018-11-06 00:42:09105
dpranke65d84dc02016-04-06 00:07:18106 # Lists should work.
107 self.assertEqual(gn_helpers.FromGNArgs('foo=[1, 2, 3]'),
108 {'foo': [1, 2, 3]})
109
110 # Empty strings should return an empty dict.
111 self.assertEqual(gn_helpers.FromGNArgs(''), {})
112 self.assertEqual(gn_helpers.FromGNArgs(' \n '), {})
113
114 # Non-identifiers should raise an exception.
Samuel Huang1ea5180e2020-05-25 16:29:40115 with self.assertRaises(gn_helpers.GNError):
dpranke65d84dc02016-04-06 00:07:18116 gn_helpers.FromGNArgs('123 = true')
117
118 # References to other variables should raise an exception.
Samuel Huang1ea5180e2020-05-25 16:29:40119 with self.assertRaises(gn_helpers.GNError):
dpranke65d84dc02016-04-06 00:07:18120 gn_helpers.FromGNArgs('foo = bar')
121
122 # References to functions should raise an exception.
Samuel Huang1ea5180e2020-05-25 16:29:40123 with self.assertRaises(gn_helpers.GNError):
dpranke65d84dc02016-04-06 00:07:18124 gn_helpers.FromGNArgs('foo = exec_script("//build/baz.py")')
125
126 # Underscores in identifiers should work.
127 self.assertEqual(gn_helpers.FromGNArgs('_foo = true'),
128 {'_foo': True})
129 self.assertEqual(gn_helpers.FromGNArgs('foo_bar = true'),
130 {'foo_bar': True})
131 self.assertEqual(gn_helpers.FromGNArgs('foo_=true'),
132 {'foo_': True})
133
Ben Pastene00156a22020-03-23 18:13:10134 def test_ReplaceImports(self):
135 # Should be a no-op on args inputs without any imports.
136 parser = gn_helpers.GNValueParser(
137 textwrap.dedent("""
138 some_arg1 = "val1"
139 some_arg2 = "val2"
140 """))
141 parser.ReplaceImports()
142 self.assertEquals(
143 parser.input,
144 textwrap.dedent("""
145 some_arg1 = "val1"
146 some_arg2 = "val2"
147 """))
148
149 # A single "import(...)" line should be replaced with the contents of the
150 # file being imported.
151 parser = gn_helpers.GNValueParser(
152 textwrap.dedent("""
153 some_arg1 = "val1"
154 import("//some/args/file.gni")
155 some_arg2 = "val2"
156 """))
157 fake_import = 'some_imported_arg = "imported_val"'
158 with mock.patch('__builtin__.open', mock.mock_open(read_data=fake_import)):
159 parser.ReplaceImports()
160 self.assertEquals(
161 parser.input,
162 textwrap.dedent("""
163 some_arg1 = "val1"
164 some_imported_arg = "imported_val"
165 some_arg2 = "val2"
166 """))
167
168 # No trailing parenthesis should raise an exception.
Samuel Huang1ea5180e2020-05-25 16:29:40169 with self.assertRaises(gn_helpers.GNError):
Ben Pastene00156a22020-03-23 18:13:10170 parser = gn_helpers.GNValueParser(
171 textwrap.dedent('import("//some/args/file.gni"'))
172 parser.ReplaceImports()
173
174 # No double quotes should raise an exception.
Samuel Huang1ea5180e2020-05-25 16:29:40175 with self.assertRaises(gn_helpers.GNError):
Ben Pastene00156a22020-03-23 18:13:10176 parser = gn_helpers.GNValueParser(
177 textwrap.dedent('import(//some/args/file.gni)'))
178 parser.ReplaceImports()
179
180 # A path that's not source absolute should raise an exception.
Samuel Huang1ea5180e2020-05-25 16:29:40181 with self.assertRaises(gn_helpers.GNError):
Ben Pastene00156a22020-03-23 18:13:10182 parser = gn_helpers.GNValueParser(
183 textwrap.dedent('import("some/relative/args/file.gni")'))
184 parser.ReplaceImports()
185
186
brettw9dffb542016-01-22 18:40:03187if __name__ == '__main__':
188 unittest.main()