Home | History | Annotate | Download | only in tests
      1 #!/usr/bin/env python3
      2 
      3 from sourcedr import ninja
      4 
      5 import os
      6 import unittest
      7 
      8 
      9 TEST_DIR = os.path.abspath(os.path.dirname(__file__))
     10 TEST_DATA_DIR = os.path.join(TEST_DIR, 'testdata', 'ninja')
     11 
     12 ENCODING = 'utf-8'
     13 
     14 
     15 class MockedParser(ninja.Parser):
     16     def __init__(self, *args, **kwargs):
     17         super(MockedParser, self).__init__(*args, **kwargs)
     18         self.mocked_env = []
     19 
     20     def _push_context(self, lexer, env):
     21         super(MockedParser, self)._push_context(lexer, env)
     22         self.mocked_env.append(env)
     23 
     24 
     25 class EvalStringTest(unittest.TestCase):
     26     def test_empty(self):
     27         s = ninja.EvalStringBuilder().getvalue()
     28         self.assertFalse(s)
     29         self.assertEqual('', ninja.eval_string(s, ninja.EvalEnv()))
     30 
     31     def test_append_raw(self):
     32         s = ninja.EvalStringBuilder().append_raw('a').getvalue()
     33         self.assertTrue(s)
     34         self.assertEqual('a', ninja.eval_string(s, ninja.EvalEnv()))
     35 
     36     def test_append_raw_concat(self):
     37         sb = ninja.EvalStringBuilder()
     38         sb.append_raw('a')
     39         sb.append_raw('b')
     40         s = sb.getvalue()
     41 
     42         self.assertTrue(s)
     43         self.assertEqual('ab', ninja.eval_string(s, ninja.EvalEnv()))
     44 
     45     def test_append_var(self):
     46         s = ninja.EvalStringBuilder().append_var('key').getvalue()
     47         self.assertTrue(s)
     48 
     49     def test_var_eval(self):
     50         env = ninja.EvalEnv()
     51         env['key'] = ninja.EvalStringBuilder().append_raw('value').getvalue()
     52 
     53         s = ninja.EvalStringBuilder().append_var('key').getvalue()
     54         self.assertEqual('value', ninja.eval_string(s, env))
     55 
     56     def test_var_concat_eval(self):
     57         env = ninja.EvalEnv()
     58         env['key1'] = ninja.EvalStringBuilder().append_raw('a').getvalue()
     59         env['key2'] = ninja.EvalStringBuilder().append_raw('b').getvalue()
     60 
     61         sb = ninja.EvalStringBuilder()
     62         sb.append_var('key1')
     63         sb.append_var('key2')
     64         s = sb.getvalue()
     65 
     66         self.assertEqual('ab', ninja.eval_string(s, env))
     67 
     68     def test_var_repeat_eval(self):
     69         env = ninja.EvalEnv()
     70         env['key1'] = ninja.EvalStringBuilder().append_raw('a').getvalue()
     71         env['key2'] = ninja.EvalStringBuilder().append_raw('b').getvalue()
     72 
     73         sb = ninja.EvalStringBuilder()
     74         sb.append_var('key1')
     75         sb.append_var('key1')
     76         sb.append_var('key2')
     77         sb.append_var('key1')
     78         sb.append_var('key2')
     79         s = sb.getvalue()
     80 
     81         self.assertEqual('aabab', ninja.eval_string(s, env))
     82 
     83     def test_var_recursive_eval(self):
     84         env = ninja.EvalEnv()
     85         env['a'] = ninja.EvalStringBuilder().append_var('b').getvalue()
     86         env['c'] = ninja.EvalStringBuilder().append_raw('d').getvalue()
     87 
     88         sb = ninja.EvalStringBuilder()
     89         sb.append_var('c')
     90         sb.append_var('c')
     91         env['b'] = sb.getvalue()
     92 
     93         sb = ninja.EvalStringBuilder()
     94         sb.append_var('a')
     95         sb.append_var('a')
     96         s = sb.getvalue()
     97 
     98         self.assertEqual('dddd', ninja.eval_string(s, env))
     99 
    100     def test_unknown_variable_eval_error(self):
    101         s = ninja.EvalStringBuilder().append_var('a').getvalue()
    102         self.assertEqual('', ninja.eval_string(s, ninja.EvalEnv()))
    103 
    104     def test_circular_eval_eval_error(self):
    105         env = ninja.EvalEnv()
    106         env['a'] = ninja.EvalStringBuilder().append_var('b').getvalue()
    107         env['b'] = ninja.EvalStringBuilder().append_var('b').getvalue()
    108 
    109         s = ninja.EvalStringBuilder().append_var('a').getvalue()
    110         with self.assertRaises(ninja.EvalCircularError):
    111             ninja.eval_string(s, env)
    112 
    113     def test_raw_and_var_eval(self):
    114         env = ninja.EvalEnv()
    115         env['b'] = ninja.EvalStringBuilder().append_raw('d').getvalue()
    116 
    117         sb = ninja.EvalStringBuilder()
    118         sb.append_raw('a')
    119         sb.append_var('b')
    120         sb.append_raw('c')
    121         s = sb.getvalue()
    122 
    123         self.assertEqual('adc', ninja.eval_string(s, env))
    124 
    125 
    126 class ParseErrorTest(unittest.TestCase):
    127     def test_repr(self):
    128         ex = ninja.ParseError('build.ninja', 5, 1)
    129         self.assertEqual('ParseError: build.ninja:5:1', repr(ex))
    130 
    131         ex = ninja.ParseError('build.ninja', 5, 1, 'invalid char')
    132         self.assertEqual('ParseError: build.ninja:5:1: invalid char', repr(ex))
    133 
    134 
    135 class LexerTest(unittest.TestCase):
    136     def test_peek_skip_comment(self):
    137         lexer = ninja.Lexer(['#comment'])
    138         tok = lexer.peek()
    139         self.assertEqual(ninja.TK.EOF, tok.kind)
    140 
    141     def test_peek_skip_comment_line(self):
    142         lexer = ninja.Lexer(['#comment\n'])
    143         tok = lexer.peek()
    144         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    145 
    146         lexer = ninja.Lexer([' #comment\n'])
    147         tok = lexer.peek()
    148         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    149 
    150         lexer = ninja.Lexer(['\t#comment\n'])
    151         tok = lexer.peek()
    152         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    153 
    154         lexer = ninja.Lexer([' \t#comment\n'])
    155         tok = lexer.peek()
    156         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    157 
    158     def test_peek_skip_empty_line(self):
    159         lexer = ninja.Lexer([' \n'])
    160         tok = lexer.peek()
    161         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    162 
    163         lexer = ninja.Lexer(['\t\n'])
    164         tok = lexer.peek()
    165         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    166 
    167         lexer = ninja.Lexer([' \t\n'])
    168         tok = lexer.peek()
    169         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    170 
    171     def test_peek_newline(self):
    172         lexer = ninja.Lexer(['\n'])
    173         tok = lexer.peek()
    174         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    175 
    176     def test_peek_space(self):
    177         lexer = ninja.Lexer([' a'])
    178 
    179         tok = lexer.peek()
    180         self.assertEqual(ninja.TK.SPACE, tok.kind)
    181         tok = lexer.peek()  # Again
    182         self.assertEqual(ninja.TK.SPACE, tok.kind)  # Not changed
    183 
    184         tok = lexer.lex()  # Consume
    185         self.assertEqual(ninja.TK.SPACE, tok.kind)  # Not changed
    186         tok = lexer.lex()
    187         self.assertEqual(ninja.TK.IDENT, tok.kind)
    188 
    189     def test_lex_space(self):
    190         lexer = ninja.Lexer([' '])
    191         tok = lexer.lex()
    192         self.assertEqual(ninja.TK.SPACE, tok.kind)
    193 
    194         lexer = ninja.Lexer(['\t'])
    195         tok = lexer.lex()
    196         self.assertEqual(ninja.TK.SPACE, tok.kind)
    197 
    198         lexer = ninja.Lexer(['\t '])
    199         tok = lexer.lex()
    200         self.assertEqual(ninja.TK.SPACE, tok.kind)
    201 
    202         lexer = ninja.Lexer([' \t'])
    203         tok = lexer.lex()
    204         self.assertEqual(ninja.TK.SPACE, tok.kind)
    205 
    206         lexer = ninja.Lexer([' a'])
    207         tok = lexer.lex()
    208         self.assertEqual(ninja.TK.SPACE, tok.kind)
    209         tok = lexer.lex()
    210         self.assertEqual(ninja.TK.IDENT, tok.kind)
    211 
    212     def test_lex_skip_space(self):
    213         lexer = ninja.Lexer(['a b'])
    214 
    215         tok = lexer.lex()
    216         self.assertEqual(ninja.TK.IDENT, tok.kind)
    217         self.assertEqual(1, tok.line)
    218         self.assertEqual(1, tok.column)
    219 
    220         tok = lexer.lex()
    221         self.assertEqual(ninja.TK.IDENT, tok.kind)
    222         self.assertEqual(1, tok.line)
    223         self.assertEqual(3, tok.column)
    224 
    225     def test_lex_skip_space_newline_escape(self):
    226         lexer = ninja.Lexer(['build $\n', ' \texample'])
    227         tok = lexer.lex()
    228         self.assertEqual(ninja.TK.IDENT, tok.kind)
    229         self.assertEqual(1, tok.line)
    230         self.assertEqual(1, tok.column)
    231         tok = lexer.lex()
    232         self.assertEqual(ninja.TK.IDENT, tok.kind)
    233         self.assertEqual(2, tok.line)
    234         self.assertEqual(3, tok.column)
    235 
    236         lexer = ninja.Lexer(['build $\n', 'example'])
    237         tok = lexer.lex()
    238         self.assertEqual(ninja.TK.IDENT, tok.kind)
    239         self.assertEqual(1, tok.line)
    240         self.assertEqual(1, tok.column)
    241         tok = lexer.lex()
    242         self.assertEqual(ninja.TK.IDENT, tok.kind)
    243         self.assertEqual(2, tok.line)
    244         self.assertEqual(1, tok.column)
    245 
    246         lexer = ninja.Lexer(['build a:$\n', 'example'])
    247         tok = lexer.lex()
    248         self.assertEqual(ninja.TK.IDENT, tok.kind)
    249         self.assertEqual(1, tok.line)
    250         self.assertEqual(1, tok.column)
    251         tok = lexer.lex()
    252         self.assertEqual(ninja.TK.IDENT, tok.kind)
    253         self.assertEqual(1, tok.line)
    254         self.assertEqual(7, tok.column)
    255         tok = lexer.lex()
    256         self.assertEqual(ninja.TK.COLON, tok.kind)
    257         self.assertEqual(1, tok.line)
    258         self.assertEqual(8, tok.column)
    259         tok = lexer.lex()
    260         self.assertEqual(ninja.TK.IDENT, tok.kind)
    261         self.assertEqual(2, tok.line)
    262         self.assertEqual(1, tok.column)
    263 
    264         # Multiple newline escapes.
    265         lexer = ninja.Lexer(['build $\n', '$\n', '$\n', 'example'])
    266         tok = lexer.lex()
    267         self.assertEqual(ninja.TK.IDENT, tok.kind)
    268         self.assertEqual(1, tok.line)
    269         self.assertEqual(1, tok.column)
    270         tok = lexer.lex()
    271         self.assertEqual(ninja.TK.IDENT, tok.kind)
    272         self.assertEqual(4, tok.line)
    273         self.assertEqual(1, tok.column)
    274 
    275     def test_peek_space_after_newline(self):
    276         lexer = ninja.Lexer(['a b\n', ' c'])
    277 
    278         tok = lexer.lex()
    279         self.assertEqual(ninja.TK.IDENT, tok.kind)
    280         self.assertEqual(1, tok.line)
    281         self.assertEqual(1, tok.column)
    282 
    283         tok = lexer.lex()
    284         self.assertEqual(ninja.TK.IDENT, tok.kind)
    285         self.assertEqual(1, tok.line)
    286         self.assertEqual(3, tok.column)
    287 
    288         tok = lexer.lex()
    289         self.assertEqual(ninja.TK.NEWLINE, tok.kind)
    290         self.assertEqual(1, tok.line)
    291         self.assertEqual(4, tok.column)
    292 
    293         # A space token must be emitted.
    294         tok = lexer.lex()
    295         self.assertEqual(ninja.TK.SPACE, tok.kind)
    296         self.assertEqual(2, tok.line)
    297         self.assertEqual(1, tok.column)
    298 
    299         tok = lexer.lex()
    300         self.assertEqual(ninja.TK.IDENT, tok.kind)
    301         self.assertEqual(2, tok.line)
    302         self.assertEqual(2, tok.column)
    303 
    304     def test_lex_ident(self):
    305         lexer = ninja.Lexer(['abcdefghijklmnopqrstuvwxyz'])
    306         tok = lexer.lex()
    307         self.assertEqual(ninja.TK.IDENT, tok.kind)
    308 
    309         lexer = ninja.Lexer(['ABCDEFGHIJKLMNOPQRSTUVWXYZ'])
    310         tok = lexer.lex()
    311         self.assertEqual(ninja.TK.IDENT, tok.kind)
    312 
    313         lexer = ninja.Lexer(['0123456789'])
    314         tok = lexer.lex()
    315         self.assertEqual(ninja.TK.IDENT, tok.kind)
    316 
    317         lexer = ninja.Lexer(['.'])
    318         tok = lexer.lex()
    319         self.assertEqual(ninja.TK.IDENT, tok.kind)
    320 
    321         lexer = ninja.Lexer(['-'])
    322         tok = lexer.lex()
    323         self.assertEqual(ninja.TK.IDENT, tok.kind)
    324 
    325         lexer = ninja.Lexer(['_'])
    326         tok = lexer.lex()
    327         self.assertEqual(ninja.TK.IDENT, tok.kind)
    328 
    329     def test_lex_assign(self):
    330         lexer = ninja.Lexer(['='])
    331         tok = lexer.lex()
    332         self.assertEqual(ninja.TK.ASSIGN, tok.kind)
    333 
    334     def test_lex_colon(self):
    335         lexer = ninja.Lexer([':'])
    336         tok = lexer.lex()
    337         self.assertEqual(ninja.TK.COLON, tok.kind)
    338 
    339     def test_lex_pipe(self):
    340         lexer = ninja.Lexer(['|'])
    341         tok = lexer.lex()
    342         self.assertEqual(ninja.TK.PIPE, tok.kind)
    343 
    344     def test_lex_pipe2(self):
    345         lexer = ninja.Lexer(['||'])
    346         tok = lexer.lex()
    347         self.assertEqual(ninja.TK.PIPE2, tok.kind)
    348 
    349     def test_lex_non_trivial(self):
    350         lexer = ninja.Lexer(['$name'])
    351         with self.assertRaises(ninja.ParseError):
    352             lexer.lex()
    353         lexer = ninja.Lexer(['${name}'])
    354         with self.assertRaises(ninja.ParseError):
    355             lexer.lex()
    356 
    357     def test_lex_match(self):
    358         lexer = ninja.Lexer(['ident'])
    359         with self.assertRaises(ninja.ParseError):
    360             lexer.lex_match({ninja.TK.PIPE})
    361 
    362     def test_lex_path_char(self):
    363         lexer = ninja.Lexer(['path1 path2'])
    364 
    365         tok = lexer.lex_path()
    366         self.assertEqual(ninja.TK.PATH, tok.kind)
    367         self.assertEqual(1, tok.line)
    368         self.assertEqual(1, tok.column)
    369         self.assertEqual(('t', 'path1'), tok.value)
    370 
    371         tok = lexer.lex_path()
    372         self.assertEqual(ninja.TK.PATH, tok.kind)
    373         self.assertEqual(1, tok.line)
    374         self.assertEqual(7, tok.column)
    375         self.assertEqual(('t', 'path2'), tok.value)
    376 
    377     def test_lex_str_char(self):
    378         lexer = ninja.Lexer(['string with spaces'])
    379         tok = lexer.lex_string()
    380         self.assertEqual(ninja.TK.STRING, tok.kind)
    381         self.assertEqual(1, tok.line)
    382         self.assertEqual(1, tok.column)
    383         self.assertEqual(('t', 'string with spaces'), tok.value)
    384 
    385     def test_lex_path_escape_char(self):
    386         for char in ' \t$:':
    387             lexer = ninja.Lexer(['$' + char])
    388             tok = lexer.lex_path()
    389             self.assertEqual(ninja.TK.PATH, tok.kind)
    390             self.assertEqual(1, tok.line)
    391             self.assertEqual(1, tok.column)
    392             self.assertEqual(('t', char), tok.value)
    393 
    394     def test_lex_str_escape_char(self):
    395         for char in ' \t$:':
    396             lexer = ninja.Lexer(['$' + char])
    397             tok = lexer.lex_string()
    398             self.assertEqual(ninja.TK.STRING, tok.kind)
    399             self.assertEqual(1, tok.line)
    400             self.assertEqual(1, tok.column)
    401             self.assertEqual(('t', char), tok.value)
    402 
    403     def test_lex_path_escape_char_bad(self):
    404         lexer = ninja.Lexer(['$'])
    405         with self.assertRaises(ninja.ParseError):
    406             lexer.lex_path()
    407 
    408         lexer = ninja.Lexer(['$%'])
    409         with self.assertRaises(ninja.ParseError):
    410             lexer.lex_path()
    411 
    412     def test_lex_str_escape_char_bad(self):
    413         lexer = ninja.Lexer(['$'])
    414         with self.assertRaises(ninja.ParseError):
    415             lexer.lex_string()
    416 
    417         lexer = ninja.Lexer(['$%'])
    418         with self.assertRaises(ninja.ParseError):
    419             lexer.lex_string()
    420 
    421     def test_lex_path_end_char(self):
    422         for char in ' \t\n:|':
    423             lexer = ninja.Lexer(['path' + char])
    424             tok = lexer.lex_path()
    425             self.assertEqual(ninja.TK.PATH, tok.kind)
    426             self.assertEqual(1, tok.line)
    427             self.assertEqual(1, tok.column)
    428             self.assertEqual(('t', 'path'), tok.value)
    429 
    430     def test_lex_path_var(self):
    431         lexer = ninja.Lexer(['$a'])
    432         tok = lexer.lex_path()
    433         self.assertIs(type(tok.value), ninja.EvalString)
    434         self.assertEqual(('v', 'a',), tok.value)
    435 
    436         lexer = ninja.Lexer(['${a}'])
    437         tok = lexer.lex_path()
    438         self.assertIs(type(tok.value), ninja.EvalString)
    439         self.assertEqual(('v', 'a',), tok.value)
    440 
    441         lexer = ninja.Lexer(['path/${a}'])
    442         tok = lexer.lex_path()
    443         self.assertIs(type(tok.value), ninja.EvalString)
    444         self.assertEqual(('tv' ,'path/', 'a'), tok.value)
    445 
    446     def test_lex_str_var(self):
    447         lexer = ninja.Lexer(['$a'])
    448         tok = lexer.lex_string()
    449         self.assertIs(type(tok.value), ninja.EvalString)
    450         self.assertEqual(('v', 'a'), tok.value)
    451 
    452         lexer = ninja.Lexer(['${a}'])
    453         tok = lexer.lex_string()
    454         self.assertIs(type(tok.value), ninja.EvalString)
    455         self.assertEqual(('v', 'a'), tok.value)
    456 
    457         lexer = ninja.Lexer(['path/${a}'])
    458         tok = lexer.lex_string()
    459         self.assertIs(type(tok.value), ninja.EvalString)
    460         self.assertEqual(('tv', 'path/', 'a'), tok.value)
    461 
    462         lexer = ninja.Lexer(['path/${a} with space'])
    463         tok = lexer.lex_string()
    464         self.assertIs(type(tok.value), ninja.EvalString)
    465         self.assertEqual(('tvt', 'path/', 'a', ' with space'), tok.value)
    466 
    467 
    468 class ParserTest(unittest.TestCase):
    469     def test_init_base_dir(self):
    470         parser = ninja.Parser()
    471         self.assertEqual(os.getcwd(), parser._base_dir)
    472         parser = ninja.Parser('/path/to/a/dir')
    473         self.assertEqual('/path/to/a/dir', parser._base_dir)
    474 
    475     def test_global_binding_stmt(self):
    476         input_path = os.path.join(TEST_DATA_DIR, 'global_binding.ninja')
    477 
    478         parser = MockedParser()
    479         parser.parse(input_path, ENCODING)
    480 
    481         env = parser.mocked_env[0]
    482         self.assertEqual('1', env['a'])
    483         self.assertEqual('2', env['b'])
    484         self.assertEqual('3', env['c'])
    485         self.assertEqual('1 2 3', env['d'])
    486         self.assertEqual('mixed 1 and 2', env['e'])
    487 
    488     def test_rule_stmt(self):
    489         input_path = os.path.join(TEST_DATA_DIR, 'rule.ninja')
    490 
    491         parser = ninja.Parser()
    492         manifest = parser.parse(input_path, ENCODING)
    493 
    494         self.assertEqual(2, len(manifest.rules))
    495 
    496         rule_cc = manifest.rules[0]
    497         self.assertEqual('cc', rule_cc.name)
    498         self.assertEqual(1, len(rule_cc.bindings))
    499 
    500         sb = ninja.EvalStringBuilder()
    501         sb.append_raw('gcc -c -o ')
    502         sb.append_var('outs')
    503         sb.append_raw(' ')
    504         sb.append_var('ins')
    505 
    506         self.assertEqual(sb.getvalue(), rule_cc.bindings['command'])
    507 
    508         rule_ld = manifest.rules[1]
    509         self.assertEqual('ld', rule_ld.name)
    510         self.assertEqual(1, len(rule_ld.bindings))
    511 
    512         sb = ninja.EvalStringBuilder()
    513         sb.append_raw('gcc -o ')
    514         sb.append_var('outs')
    515         sb.append_raw(' ')
    516         sb.append_var('ins')
    517 
    518         self.assertEqual(sb.getvalue(), rule_ld.bindings['command'])
    519 
    520     def test_build_stmt(self):
    521         input_path = os.path.join(TEST_DATA_DIR, 'build.ninja')
    522 
    523         parser = ninja.Parser()
    524         manifest = parser.parse(input_path, ENCODING)
    525 
    526         self.assertEqual(1, len(manifest.builds))
    527 
    528         build = manifest.builds[0]
    529         self.assertEqual('explicit_out1', build.explicit_outs[0])
    530         self.assertEqual('explicit_out2', build.explicit_outs[1])
    531         self.assertEqual('implicit_out1', build.implicit_outs[0])
    532         self.assertEqual('implicit_out2', build.implicit_outs[1])
    533         self.assertEqual('phony', build.rule)
    534         self.assertEqual('explicit_in1', build.explicit_ins[0])
    535         self.assertEqual('explicit_in2', build.explicit_ins[1])
    536         self.assertEqual('implicit_in1', build.implicit_ins[0])
    537         self.assertEqual('implicit_in2', build.implicit_ins[1])
    538         self.assertEqual('order_only1', build.prerequisites[0])
    539         self.assertEqual('order_only2', build.prerequisites[1])
    540 
    541         self.assertEqual(('t', '1',), build.bindings['a'])
    542         self.assertEqual(('t', '2',), build.bindings['b'])
    543 
    544     def test_default_stmt(self):
    545         input_path = os.path.join(TEST_DATA_DIR, 'default.ninja')
    546 
    547         parser = ninja.Parser()
    548         manifest = parser.parse(input_path, ENCODING)
    549 
    550         self.assertEqual(1, len(manifest.defaults))
    551 
    552         default = manifest.defaults[0]
    553         self.assertEqual('foo.o', default.outs[0])
    554         self.assertEqual('bar.o', default.outs[1])
    555 
    556     def test_pool_stmt(self):
    557         input_path = os.path.join(TEST_DATA_DIR, 'pool.ninja')
    558 
    559         parser = ninja.Parser()
    560         manifest = parser.parse(input_path, ENCODING)
    561 
    562         self.assertEqual(1, len(manifest.pools))
    563 
    564         pool = manifest.pools[0]
    565         self.assertEqual('example', pool.name)
    566         self.assertEqual(('t', '5',), pool.bindings['depth'])
    567 
    568     def test_subninja_stmt(self):
    569         input_path = os.path.join(TEST_DATA_DIR, 'subninja.ninja')
    570 
    571         parser = MockedParser(TEST_DATA_DIR)
    572         manifest = parser.parse(input_path, ENCODING)
    573 
    574         env = parser.mocked_env[0]
    575         self.assertEqual('original', env['a'])
    576         self.assertEqual(2, len(manifest.builds))
    577 
    578         env = parser.mocked_env[1]
    579         self.assertEqual('changed', env['a'])
    580 
    581     def test_include_stmt(self):
    582         input_path = os.path.join(TEST_DATA_DIR, 'include.ninja')
    583 
    584         parser = MockedParser(TEST_DATA_DIR)
    585         manifest = parser.parse(input_path, ENCODING)
    586 
    587         env = parser.mocked_env[0]
    588         self.assertEqual('changed', env['a'])
    589         self.assertEqual(2, len(manifest.builds))
    590 
    591 
    592 class ParserTestWithBadInput(unittest.TestCase):
    593     def test_unexpected_trivial_token(self):
    594         input_path = os.path.join(TEST_DATA_DIR, 'bad_trivial.ninja')
    595         with self.assertRaises(ninja.ParseError) as ctx:
    596             MockedParser().parse(input_path, ENCODING)
    597 
    598         self.assertEqual(input_path, ctx.exception.path)
    599         self.assertEqual(1, ctx.exception.line)
    600         self.assertEqual(1, ctx.exception.column)
    601 
    602     def test_unexpected_non_trivial_token(self):
    603         input_path = os.path.join(TEST_DATA_DIR, 'bad_non_trivial.ninja')
    604         with self.assertRaises(ninja.ParseError) as ctx:
    605             MockedParser().parse(input_path, ENCODING)
    606 
    607         self.assertEqual(input_path, ctx.exception.path)
    608         self.assertEqual(1, ctx.exception.line)
    609         self.assertEqual(1, ctx.exception.column)
    610 
    611     def test_bad_after_good(self):
    612         input_path = os.path.join(TEST_DATA_DIR, 'bad_after_good.ninja')
    613         with self.assertRaises(ninja.ParseError) as ctx:
    614             MockedParser().parse(input_path, ENCODING)
    615 
    616         self.assertEqual(input_path, ctx.exception.path)
    617         self.assertEqual(4, ctx.exception.line)
    618         self.assertEqual(1, ctx.exception.column)
    619 
    620     def test_bad_path(self):
    621         input_path = os.path.join(TEST_DATA_DIR, 'bad_path.ninja')
    622         with self.assertRaises(ninja.ParseError) as ctx:
    623             MockedParser().parse(input_path, ENCODING)
    624 
    625         self.assertEqual(input_path, ctx.exception.path)
    626         self.assertEqual(1, ctx.exception.line)
    627         self.assertEqual(9, ctx.exception.column)
    628 
    629 
    630 if __name__ == '__main__':
    631     unittest.main()
    632