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