blob: 99d720b907bca6e869354053c0598063cd3e90d1 [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
30 with self.assertRaises(gn_helpers.GNException):
31 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
45 with self.assertRaises(gn_helpers.GNException):
46 parser = gn_helpers.GNValueParser('')
47 parser.ParseNumber()
48 with self.assertRaises(gn_helpers.GNException):
49 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
56 with self.assertRaises(gn_helpers.GNException):
57 parser = gn_helpers.GNValueParser('') # Empty.
58 parser.ParseString()
59 with self.assertRaises(gn_helpers.GNException):
60 parser = gn_helpers.GNValueParser('asdf') # Unquoted.
61 parser.ParseString()
62 with self.assertRaises(gn_helpers.GNException):
63 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
70 with self.assertRaises(gn_helpers.GNException):
71 parser = gn_helpers.GNValueParser('') # Empty.
72 parser.ParseList()
73 with self.assertRaises(gn_helpers.GNException):
74 parser = gn_helpers.GNValueParser('asdf') # No [].
75 parser.ParseList()
76 with self.assertRaises(gn_helpers.GNException):
77 parser = gn_helpers.GNValueParser('[1, 2') # Unterminated
78 parser.ParseList()
79 with self.assertRaises(gn_helpers.GNException):
80 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',
96 'bar = 1 # In-line comment.',
97 ]
98 self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)),
99 {'foo': True, 'bar': 1})
100
dpranke65d84dc02016-04-06 00:07:18101 # Lists should work.
102 self.assertEqual(gn_helpers.FromGNArgs('foo=[1, 2, 3]'),
103 {'foo': [1, 2, 3]})
104
105 # Empty strings should return an empty dict.
106 self.assertEqual(gn_helpers.FromGNArgs(''), {})
107 self.assertEqual(gn_helpers.FromGNArgs(' \n '), {})
108
109 # Non-identifiers should raise an exception.
110 with self.assertRaises(gn_helpers.GNException):
111 gn_helpers.FromGNArgs('123 = true')
112
113 # References to other variables should raise an exception.
114 with self.assertRaises(gn_helpers.GNException):
115 gn_helpers.FromGNArgs('foo = bar')
116
117 # References to functions should raise an exception.
118 with self.assertRaises(gn_helpers.GNException):
119 gn_helpers.FromGNArgs('foo = exec_script("//build/baz.py")')
120
121 # Underscores in identifiers should work.
122 self.assertEqual(gn_helpers.FromGNArgs('_foo = true'),
123 {'_foo': True})
124 self.assertEqual(gn_helpers.FromGNArgs('foo_bar = true'),
125 {'foo_bar': True})
126 self.assertEqual(gn_helpers.FromGNArgs('foo_=true'),
127 {'foo_': True})
128
Ben Pastene00156a22020-03-23 18:13:10129 def test_ReplaceImports(self):
130 # Should be a no-op on args inputs without any imports.
131 parser = gn_helpers.GNValueParser(
132 textwrap.dedent("""
133 some_arg1 = "val1"
134 some_arg2 = "val2"
135 """))
136 parser.ReplaceImports()
137 self.assertEquals(
138 parser.input,
139 textwrap.dedent("""
140 some_arg1 = "val1"
141 some_arg2 = "val2"
142 """))
143
144 # A single "import(...)" line should be replaced with the contents of the
145 # file being imported.
146 parser = gn_helpers.GNValueParser(
147 textwrap.dedent("""
148 some_arg1 = "val1"
149 import("//some/args/file.gni")
150 some_arg2 = "val2"
151 """))
152 fake_import = 'some_imported_arg = "imported_val"'
153 with mock.patch('__builtin__.open', mock.mock_open(read_data=fake_import)):
154 parser.ReplaceImports()
155 self.assertEquals(
156 parser.input,
157 textwrap.dedent("""
158 some_arg1 = "val1"
159 some_imported_arg = "imported_val"
160 some_arg2 = "val2"
161 """))
162
163 # No trailing parenthesis should raise an exception.
164 with self.assertRaises(gn_helpers.GNException):
165 parser = gn_helpers.GNValueParser(
166 textwrap.dedent('import("//some/args/file.gni"'))
167 parser.ReplaceImports()
168
169 # No double quotes should raise an exception.
170 with self.assertRaises(gn_helpers.GNException):
171 parser = gn_helpers.GNValueParser(
172 textwrap.dedent('import(//some/args/file.gni)'))
173 parser.ReplaceImports()
174
175 # A path that's not source absolute should raise an exception.
176 with self.assertRaises(gn_helpers.GNException):
177 parser = gn_helpers.GNValueParser(
178 textwrap.dedent('import("some/relative/args/file.gni")'))
179 parser.ReplaceImports()
180
181
brettw9dffb542016-01-22 18:40:03182if __name__ == '__main__':
183 unittest.main()