xref: /aosp_15_r20/external/cronet/build/gn_helpers_unittest.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6777b538SAndroid Build Coastguard Worker# Copyright 2016 The Chromium Authors
3*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file.
5*6777b538SAndroid Build Coastguard Worker
6*6777b538SAndroid Build Coastguard Workerimport os
7*6777b538SAndroid Build Coastguard Workerimport pathlib
8*6777b538SAndroid Build Coastguard Workerimport shutil
9*6777b538SAndroid Build Coastguard Workerimport sys
10*6777b538SAndroid Build Coastguard Workerimport tempfile
11*6777b538SAndroid Build Coastguard Workerimport textwrap
12*6777b538SAndroid Build Coastguard Workerimport unittest
13*6777b538SAndroid Build Coastguard Workerfrom unittest import mock
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Workerimport gn_helpers
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Workerclass UnitTest(unittest.TestCase):
19*6777b538SAndroid Build Coastguard Worker  def test_ToGNString(self):
20*6777b538SAndroid Build Coastguard Worker    test_cases = [
21*6777b538SAndroid Build Coastguard Worker        (42, '42', '42'), ('foo', '"foo"', '"foo"'), (True, 'true', 'true'),
22*6777b538SAndroid Build Coastguard Worker        (False, 'false', 'false'), ('', '""', '""'),
23*6777b538SAndroid Build Coastguard Worker        ('\\$"$\\', '"\\\\\\$\\"\\$\\\\"', '"\\\\\\$\\"\\$\\\\"'),
24*6777b538SAndroid Build Coastguard Worker        (' \t\r\n', '" $0x09$0x0D$0x0A"', '" $0x09$0x0D$0x0A"'),
25*6777b538SAndroid Build Coastguard Worker        (u'\u2713', '"$0xE2$0x9C$0x93"', '"$0xE2$0x9C$0x93"'),
26*6777b538SAndroid Build Coastguard Worker        ([], '[  ]', '[]'), ([1], '[ 1 ]', '[\n  1\n]\n'),
27*6777b538SAndroid Build Coastguard Worker        ([3, 1, 4, 1], '[ 3, 1, 4, 1 ]', '[\n  3,\n  1,\n  4,\n  1\n]\n'),
28*6777b538SAndroid Build Coastguard Worker        (['a', True, 2], '[ "a", true, 2 ]', '[\n  "a",\n  true,\n  2\n]\n'),
29*6777b538SAndroid Build Coastguard Worker        ({
30*6777b538SAndroid Build Coastguard Worker            'single': 'item'
31*6777b538SAndroid Build Coastguard Worker        }, 'single = "item"\n', 'single = "item"\n'),
32*6777b538SAndroid Build Coastguard Worker        ({
33*6777b538SAndroid Build Coastguard Worker            'kEy': 137,
34*6777b538SAndroid Build Coastguard Worker            '_42A_Zaz_': [False, True]
35*6777b538SAndroid Build Coastguard Worker        }, '_42A_Zaz_ = [ false, true ]\nkEy = 137\n',
36*6777b538SAndroid Build Coastguard Worker         '_42A_Zaz_ = [\n  false,\n  true\n]\nkEy = 137\n'),
37*6777b538SAndroid Build Coastguard Worker        ([1, 'two',
38*6777b538SAndroid Build Coastguard Worker          ['"thr,.$\\', True, False, [],
39*6777b538SAndroid Build Coastguard Worker           u'(\u2713)']], '[ 1, "two", [ "\\"thr,.\\$\\\\", true, false, ' +
40*6777b538SAndroid Build Coastguard Worker         '[  ], "($0xE2$0x9C$0x93)" ] ]', '''[
41*6777b538SAndroid Build Coastguard Worker  1,
42*6777b538SAndroid Build Coastguard Worker  "two",
43*6777b538SAndroid Build Coastguard Worker  [
44*6777b538SAndroid Build Coastguard Worker    "\\"thr,.\\$\\\\",
45*6777b538SAndroid Build Coastguard Worker    true,
46*6777b538SAndroid Build Coastguard Worker    false,
47*6777b538SAndroid Build Coastguard Worker    [],
48*6777b538SAndroid Build Coastguard Worker    "($0xE2$0x9C$0x93)"
49*6777b538SAndroid Build Coastguard Worker  ]
50*6777b538SAndroid Build Coastguard Worker]
51*6777b538SAndroid Build Coastguard Worker'''),
52*6777b538SAndroid Build Coastguard Worker        ({
53*6777b538SAndroid Build Coastguard Worker            's': 'foo',
54*6777b538SAndroid Build Coastguard Worker            'n': 42,
55*6777b538SAndroid Build Coastguard Worker            'b': True,
56*6777b538SAndroid Build Coastguard Worker            'a': [3, 'x']
57*6777b538SAndroid Build Coastguard Worker        }, 'a = [ 3, "x" ]\nb = true\nn = 42\ns = "foo"\n',
58*6777b538SAndroid Build Coastguard Worker         'a = [\n  3,\n  "x"\n]\nb = true\nn = 42\ns = "foo"\n'),
59*6777b538SAndroid Build Coastguard Worker        (
60*6777b538SAndroid Build Coastguard Worker            [[[], [[]]], []],
61*6777b538SAndroid Build Coastguard Worker            '[ [ [  ], [ [  ] ] ], [  ] ]',
62*6777b538SAndroid Build Coastguard Worker            '[\n  [\n    [],\n    [\n      []\n    ]\n  ],\n  []\n]\n',
63*6777b538SAndroid Build Coastguard Worker        ),
64*6777b538SAndroid Build Coastguard Worker        (
65*6777b538SAndroid Build Coastguard Worker            [{
66*6777b538SAndroid Build Coastguard Worker                'a': 1,
67*6777b538SAndroid Build Coastguard Worker                'c': {
68*6777b538SAndroid Build Coastguard Worker                    'z': 8
69*6777b538SAndroid Build Coastguard Worker                },
70*6777b538SAndroid Build Coastguard Worker                'b': []
71*6777b538SAndroid Build Coastguard Worker            }],
72*6777b538SAndroid Build Coastguard Worker            '[ { a = 1\nb = [  ]\nc = { z = 8 } } ]\n',
73*6777b538SAndroid Build Coastguard Worker            '[\n  {\n    a = 1\n    b = []\n    c = {\n' +
74*6777b538SAndroid Build Coastguard Worker            '      z = 8\n    }\n  }\n]\n',
75*6777b538SAndroid Build Coastguard Worker        )
76*6777b538SAndroid Build Coastguard Worker    ]
77*6777b538SAndroid Build Coastguard Worker    for obj, exp_ugly, exp_pretty in test_cases:
78*6777b538SAndroid Build Coastguard Worker      out_ugly = gn_helpers.ToGNString(obj)
79*6777b538SAndroid Build Coastguard Worker      self.assertEqual(exp_ugly, out_ugly)
80*6777b538SAndroid Build Coastguard Worker      out_pretty = gn_helpers.ToGNString(obj, pretty=True)
81*6777b538SAndroid Build Coastguard Worker      self.assertEqual(exp_pretty, out_pretty)
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker  def test_UnescapeGNString(self):
84*6777b538SAndroid Build Coastguard Worker    # Backslash followed by a \, $, or " means the folling character without
85*6777b538SAndroid Build Coastguard Worker    # the special meaning. Backslash followed by everything else is a literal.
86*6777b538SAndroid Build Coastguard Worker    self.assertEqual(
87*6777b538SAndroid Build Coastguard Worker        gn_helpers.UnescapeGNString('\\as\\$\\\\asd\\"'),
88*6777b538SAndroid Build Coastguard Worker        '\\as$\\asd"')
89*6777b538SAndroid Build Coastguard Worker
90*6777b538SAndroid Build Coastguard Worker  def test_FromGNString(self):
91*6777b538SAndroid Build Coastguard Worker    self.assertEqual(
92*6777b538SAndroid Build Coastguard Worker        gn_helpers.FromGNString('[1, -20, true, false,["as\\"", []]]'),
93*6777b538SAndroid Build Coastguard Worker        [ 1, -20, True, False, [ 'as"', [] ] ])
94*6777b538SAndroid Build Coastguard Worker
95*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
96*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('123 456')
97*6777b538SAndroid Build Coastguard Worker      parser.Parse()
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker  def test_ParseBool(self):
100*6777b538SAndroid Build Coastguard Worker    parser = gn_helpers.GNValueParser('true')
101*6777b538SAndroid Build Coastguard Worker    self.assertEqual(parser.Parse(), True)
102*6777b538SAndroid Build Coastguard Worker
103*6777b538SAndroid Build Coastguard Worker    parser = gn_helpers.GNValueParser('false')
104*6777b538SAndroid Build Coastguard Worker    self.assertEqual(parser.Parse(), False)
105*6777b538SAndroid Build Coastguard Worker
106*6777b538SAndroid Build Coastguard Worker  def test_ParseNumber(self):
107*6777b538SAndroid Build Coastguard Worker    parser = gn_helpers.GNValueParser('123')
108*6777b538SAndroid Build Coastguard Worker    self.assertEqual(parser.ParseNumber(), 123)
109*6777b538SAndroid Build Coastguard Worker
110*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
111*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('')
112*6777b538SAndroid Build Coastguard Worker      parser.ParseNumber()
113*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
114*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('a123')
115*6777b538SAndroid Build Coastguard Worker      parser.ParseNumber()
116*6777b538SAndroid Build Coastguard Worker
117*6777b538SAndroid Build Coastguard Worker  def test_ParseString(self):
118*6777b538SAndroid Build Coastguard Worker    parser = gn_helpers.GNValueParser('"asdf"')
119*6777b538SAndroid Build Coastguard Worker    self.assertEqual(parser.ParseString(), 'asdf')
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
122*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('')  # Empty.
123*6777b538SAndroid Build Coastguard Worker      parser.ParseString()
124*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
125*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('asdf')  # Unquoted.
126*6777b538SAndroid Build Coastguard Worker      parser.ParseString()
127*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
128*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('"trailing')  # Unterminated.
129*6777b538SAndroid Build Coastguard Worker      parser.ParseString()
130*6777b538SAndroid Build Coastguard Worker
131*6777b538SAndroid Build Coastguard Worker  def test_ParseList(self):
132*6777b538SAndroid Build Coastguard Worker    parser = gn_helpers.GNValueParser('[1,]')  # Optional end comma OK.
133*6777b538SAndroid Build Coastguard Worker    self.assertEqual(parser.ParseList(), [ 1 ])
134*6777b538SAndroid Build Coastguard Worker
135*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
136*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('')  # Empty.
137*6777b538SAndroid Build Coastguard Worker      parser.ParseList()
138*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
139*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('asdf')  # No [].
140*6777b538SAndroid Build Coastguard Worker      parser.ParseList()
141*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
142*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('[1, 2')  # Unterminated
143*6777b538SAndroid Build Coastguard Worker      parser.ParseList()
144*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
145*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('[1 2]')  # No separating comma.
146*6777b538SAndroid Build Coastguard Worker      parser.ParseList()
147*6777b538SAndroid Build Coastguard Worker
148*6777b538SAndroid Build Coastguard Worker  def test_ParseScope(self):
149*6777b538SAndroid Build Coastguard Worker    parser = gn_helpers.GNValueParser('{a = 1}')
150*6777b538SAndroid Build Coastguard Worker    self.assertEqual(parser.ParseScope(), {'a': 1})
151*6777b538SAndroid Build Coastguard Worker
152*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
153*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('')  # Empty.
154*6777b538SAndroid Build Coastguard Worker      parser.ParseScope()
155*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
156*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('asdf')  # No {}.
157*6777b538SAndroid Build Coastguard Worker      parser.ParseScope()
158*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
159*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('{a = 1')  # Unterminated.
160*6777b538SAndroid Build Coastguard Worker      parser.ParseScope()
161*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
162*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('{"a" = 1}')  # Not identifier.
163*6777b538SAndroid Build Coastguard Worker      parser.ParseScope()
164*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
165*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser('{a = }')  # No value.
166*6777b538SAndroid Build Coastguard Worker      parser.ParseScope()
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker  def test_FromGNArgs(self):
169*6777b538SAndroid Build Coastguard Worker    # Booleans and numbers should work; whitespace is allowed works.
170*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('foo = true\nbar = 1\n'),
171*6777b538SAndroid Build Coastguard Worker                     {'foo': True, 'bar': 1})
172*6777b538SAndroid Build Coastguard Worker
173*6777b538SAndroid Build Coastguard Worker    # Whitespace is not required; strings should also work.
174*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('foo="bar baz"'),
175*6777b538SAndroid Build Coastguard Worker                     {'foo': 'bar baz'})
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker    # Comments should work (and be ignored).
178*6777b538SAndroid Build Coastguard Worker    gn_args_lines = [
179*6777b538SAndroid Build Coastguard Worker        '# Top-level comment.',
180*6777b538SAndroid Build Coastguard Worker        'foo = true',
181*6777b538SAndroid Build Coastguard Worker        'bar = 1  # In-line comment followed by whitespace.',
182*6777b538SAndroid Build Coastguard Worker        ' ',
183*6777b538SAndroid Build Coastguard Worker        'baz = false',
184*6777b538SAndroid Build Coastguard Worker    ]
185*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)), {
186*6777b538SAndroid Build Coastguard Worker        'foo': True,
187*6777b538SAndroid Build Coastguard Worker        'bar': 1,
188*6777b538SAndroid Build Coastguard Worker        'baz': False
189*6777b538SAndroid Build Coastguard Worker    })
190*6777b538SAndroid Build Coastguard Worker
191*6777b538SAndroid Build Coastguard Worker    # Lists should work.
192*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('foo=[1, 2, 3]'),
193*6777b538SAndroid Build Coastguard Worker                     {'foo': [1, 2, 3]})
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker    # Empty strings should return an empty dict.
196*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs(''), {})
197*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs(' \n '), {})
198*6777b538SAndroid Build Coastguard Worker
199*6777b538SAndroid Build Coastguard Worker    # Comments should work everywhere (and be ignored).
200*6777b538SAndroid Build Coastguard Worker    gn_args_lines = [
201*6777b538SAndroid Build Coastguard Worker        '# Top-level comment.',
202*6777b538SAndroid Build Coastguard Worker        '',
203*6777b538SAndroid Build Coastguard Worker        '# Variable comment.',
204*6777b538SAndroid Build Coastguard Worker        'foo = true',
205*6777b538SAndroid Build Coastguard Worker        'bar = [',
206*6777b538SAndroid Build Coastguard Worker        '    # Value comment in list.',
207*6777b538SAndroid Build Coastguard Worker        '    1,',
208*6777b538SAndroid Build Coastguard Worker        '    2,',
209*6777b538SAndroid Build Coastguard Worker        ']',
210*6777b538SAndroid Build Coastguard Worker        '',
211*6777b538SAndroid Build Coastguard Worker        'baz # Comment anywhere, really',
212*6777b538SAndroid Build Coastguard Worker        '  = # also here',
213*6777b538SAndroid Build Coastguard Worker        '    4',
214*6777b538SAndroid Build Coastguard Worker    ]
215*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)), {
216*6777b538SAndroid Build Coastguard Worker        'foo': True,
217*6777b538SAndroid Build Coastguard Worker        'bar': [1, 2],
218*6777b538SAndroid Build Coastguard Worker        'baz': 4
219*6777b538SAndroid Build Coastguard Worker    })
220*6777b538SAndroid Build Coastguard Worker
221*6777b538SAndroid Build Coastguard Worker    # Scope should be parsed, even empty ones.
222*6777b538SAndroid Build Coastguard Worker    gn_args_lines = [
223*6777b538SAndroid Build Coastguard Worker        'foo = {',
224*6777b538SAndroid Build Coastguard Worker        '  a = 1',
225*6777b538SAndroid Build Coastguard Worker        '  b = [',
226*6777b538SAndroid Build Coastguard Worker        '    { },',
227*6777b538SAndroid Build Coastguard Worker        '    {',
228*6777b538SAndroid Build Coastguard Worker        '      c = 1',
229*6777b538SAndroid Build Coastguard Worker        '    },',
230*6777b538SAndroid Build Coastguard Worker        '  ]',
231*6777b538SAndroid Build Coastguard Worker        '}',
232*6777b538SAndroid Build Coastguard Worker    ]
233*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('\n'.join(gn_args_lines)),
234*6777b538SAndroid Build Coastguard Worker                     {'foo': {
235*6777b538SAndroid Build Coastguard Worker                         'a': 1,
236*6777b538SAndroid Build Coastguard Worker                         'b': [
237*6777b538SAndroid Build Coastguard Worker                             {},
238*6777b538SAndroid Build Coastguard Worker                             {
239*6777b538SAndroid Build Coastguard Worker                                 'c': 1,
240*6777b538SAndroid Build Coastguard Worker                             },
241*6777b538SAndroid Build Coastguard Worker                         ]
242*6777b538SAndroid Build Coastguard Worker                     }})
243*6777b538SAndroid Build Coastguard Worker
244*6777b538SAndroid Build Coastguard Worker    # Non-identifiers should raise an exception.
245*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
246*6777b538SAndroid Build Coastguard Worker      gn_helpers.FromGNArgs('123 = true')
247*6777b538SAndroid Build Coastguard Worker
248*6777b538SAndroid Build Coastguard Worker    # References to other variables should raise an exception.
249*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
250*6777b538SAndroid Build Coastguard Worker      gn_helpers.FromGNArgs('foo = bar')
251*6777b538SAndroid Build Coastguard Worker
252*6777b538SAndroid Build Coastguard Worker    # References to functions should raise an exception.
253*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
254*6777b538SAndroid Build Coastguard Worker      gn_helpers.FromGNArgs('foo = exec_script("//build/baz.py")')
255*6777b538SAndroid Build Coastguard Worker
256*6777b538SAndroid Build Coastguard Worker    # Underscores in identifiers should work.
257*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('_foo = true'),
258*6777b538SAndroid Build Coastguard Worker                     {'_foo': True})
259*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('foo_bar = true'),
260*6777b538SAndroid Build Coastguard Worker                     {'foo_bar': True})
261*6777b538SAndroid Build Coastguard Worker    self.assertEqual(gn_helpers.FromGNArgs('foo_=true'),
262*6777b538SAndroid Build Coastguard Worker                     {'foo_': True})
263*6777b538SAndroid Build Coastguard Worker
264*6777b538SAndroid Build Coastguard Worker  def test_ReplaceImports(self):
265*6777b538SAndroid Build Coastguard Worker    # Should be a no-op on args inputs without any imports.
266*6777b538SAndroid Build Coastguard Worker    parser = gn_helpers.GNValueParser(
267*6777b538SAndroid Build Coastguard Worker        textwrap.dedent("""
268*6777b538SAndroid Build Coastguard Worker        some_arg1 = "val1"
269*6777b538SAndroid Build Coastguard Worker        some_arg2 = "val2"
270*6777b538SAndroid Build Coastguard Worker    """))
271*6777b538SAndroid Build Coastguard Worker    parser.ReplaceImports()
272*6777b538SAndroid Build Coastguard Worker    self.assertEqual(
273*6777b538SAndroid Build Coastguard Worker        parser.input,
274*6777b538SAndroid Build Coastguard Worker        textwrap.dedent("""
275*6777b538SAndroid Build Coastguard Worker        some_arg1 = "val1"
276*6777b538SAndroid Build Coastguard Worker        some_arg2 = "val2"
277*6777b538SAndroid Build Coastguard Worker    """))
278*6777b538SAndroid Build Coastguard Worker
279*6777b538SAndroid Build Coastguard Worker    # A single "import(...)" line should be replaced with the contents of the
280*6777b538SAndroid Build Coastguard Worker    # file being imported.
281*6777b538SAndroid Build Coastguard Worker    parser = gn_helpers.GNValueParser(
282*6777b538SAndroid Build Coastguard Worker        textwrap.dedent("""
283*6777b538SAndroid Build Coastguard Worker        some_arg1 = "val1"
284*6777b538SAndroid Build Coastguard Worker        import("//some/args/file.gni")
285*6777b538SAndroid Build Coastguard Worker        some_arg2 = "val2"
286*6777b538SAndroid Build Coastguard Worker    """))
287*6777b538SAndroid Build Coastguard Worker    fake_import = 'some_imported_arg = "imported_val"'
288*6777b538SAndroid Build Coastguard Worker    builtin_var = '__builtin__' if sys.version_info.major < 3 else 'builtins'
289*6777b538SAndroid Build Coastguard Worker    open_fun = '{}.open'.format(builtin_var)
290*6777b538SAndroid Build Coastguard Worker    with mock.patch(open_fun, mock.mock_open(read_data=fake_import)):
291*6777b538SAndroid Build Coastguard Worker      parser.ReplaceImports()
292*6777b538SAndroid Build Coastguard Worker    self.assertEqual(
293*6777b538SAndroid Build Coastguard Worker        parser.input,
294*6777b538SAndroid Build Coastguard Worker        textwrap.dedent("""
295*6777b538SAndroid Build Coastguard Worker        some_arg1 = "val1"
296*6777b538SAndroid Build Coastguard Worker        some_imported_arg = "imported_val"
297*6777b538SAndroid Build Coastguard Worker        some_arg2 = "val2"
298*6777b538SAndroid Build Coastguard Worker    """))
299*6777b538SAndroid Build Coastguard Worker
300*6777b538SAndroid Build Coastguard Worker    # No trailing parenthesis should raise an exception.
301*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
302*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser(
303*6777b538SAndroid Build Coastguard Worker          textwrap.dedent('import("//some/args/file.gni"'))
304*6777b538SAndroid Build Coastguard Worker      parser.ReplaceImports()
305*6777b538SAndroid Build Coastguard Worker
306*6777b538SAndroid Build Coastguard Worker    # No double quotes should raise an exception.
307*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
308*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser(
309*6777b538SAndroid Build Coastguard Worker          textwrap.dedent('import(//some/args/file.gni)'))
310*6777b538SAndroid Build Coastguard Worker      parser.ReplaceImports()
311*6777b538SAndroid Build Coastguard Worker
312*6777b538SAndroid Build Coastguard Worker    # A path that's not source absolute should raise an exception.
313*6777b538SAndroid Build Coastguard Worker    with self.assertRaises(gn_helpers.GNError):
314*6777b538SAndroid Build Coastguard Worker      parser = gn_helpers.GNValueParser(
315*6777b538SAndroid Build Coastguard Worker          textwrap.dedent('import("some/relative/args/file.gni")'))
316*6777b538SAndroid Build Coastguard Worker      parser.ReplaceImports()
317*6777b538SAndroid Build Coastguard Worker
318*6777b538SAndroid Build Coastguard Worker  def test_CreateBuildCommand(self):
319*6777b538SAndroid Build Coastguard Worker    with tempfile.TemporaryDirectory() as temp_dir:
320*6777b538SAndroid Build Coastguard Worker      suffix = '.bat' if sys.platform.startswith('win32') else ''
321*6777b538SAndroid Build Coastguard Worker      self.assertEqual(f'autoninja{suffix}',
322*6777b538SAndroid Build Coastguard Worker                       gn_helpers.CreateBuildCommand(temp_dir)[0])
323*6777b538SAndroid Build Coastguard Worker
324*6777b538SAndroid Build Coastguard Worker      siso_deps = pathlib.Path(temp_dir) / '.siso_deps'
325*6777b538SAndroid Build Coastguard Worker      siso_deps.touch()
326*6777b538SAndroid Build Coastguard Worker      self.assertEqual(f'autoninja{suffix}',
327*6777b538SAndroid Build Coastguard Worker                       gn_helpers.CreateBuildCommand(temp_dir)[0])
328*6777b538SAndroid Build Coastguard Worker
329*6777b538SAndroid Build Coastguard Worker      with mock.patch('shutil.which', lambda x: None):
330*6777b538SAndroid Build Coastguard Worker        cmd = gn_helpers.CreateBuildCommand(temp_dir)
331*6777b538SAndroid Build Coastguard Worker        self.assertIn('third_party', cmd[0])
332*6777b538SAndroid Build Coastguard Worker        self.assertIn(f'{os.sep}siso', cmd[0])
333*6777b538SAndroid Build Coastguard Worker        self.assertEqual(['ninja', '-C', temp_dir], cmd[1:])
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Worker      ninja_deps = pathlib.Path(temp_dir) / '.ninja_deps'
336*6777b538SAndroid Build Coastguard Worker      ninja_deps.touch()
337*6777b538SAndroid Build Coastguard Worker
338*6777b538SAndroid Build Coastguard Worker      with self.assertRaisesRegex(Exception, 'Found both'):
339*6777b538SAndroid Build Coastguard Worker        gn_helpers.CreateBuildCommand(temp_dir)
340*6777b538SAndroid Build Coastguard Worker
341*6777b538SAndroid Build Coastguard Worker      siso_deps.unlink()
342*6777b538SAndroid Build Coastguard Worker      self.assertEqual(f'autoninja{suffix}',
343*6777b538SAndroid Build Coastguard Worker                       gn_helpers.CreateBuildCommand(temp_dir)[0])
344*6777b538SAndroid Build Coastguard Worker
345*6777b538SAndroid Build Coastguard Worker      with mock.patch('shutil.which', lambda x: None):
346*6777b538SAndroid Build Coastguard Worker        cmd = gn_helpers.CreateBuildCommand(temp_dir)
347*6777b538SAndroid Build Coastguard Worker        self.assertIn('third_party', cmd[0])
348*6777b538SAndroid Build Coastguard Worker        self.assertIn(f'{os.sep}ninja', cmd[0])
349*6777b538SAndroid Build Coastguard Worker        self.assertEqual(['-C', temp_dir], cmd[1:])
350*6777b538SAndroid Build Coastguard Worker
351*6777b538SAndroid Build Coastguard Worker
352*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__':
353*6777b538SAndroid Build Coastguard Worker  unittest.main()
354