def test_statement(self): # Missing '%end' with self.parse(''' %define x(a) y = a '''): self.assertError('Input ended unexpectedly') # Success with self.parse(''' %define f1() %end %define f2(foo) x = foo %end %define f3(foo, bar) x = foo y = bar %end ''') as p: self.assertIsInstance(p, ast.Module) self.assertEqual(3, len(p.statements)) p = p.statements self.assertIsInstance(p[0], ast.StatementMacroStmt) self.assertLocation(p[0], 2, 26) self.assertEqual('f1', p[0].name) self.assertEqual((), p[0].parameters) self.assertEqual((), p[0].statements) self.assertIsInstance(p[1], ast.StatementMacroStmt) self.assertLocation(p[1], 5, 26) self.assertEqual('f2', p[1].name) self.assertEqual(('foo',), p[1].parameters) self.assertEqual((ast.AssignmentStmt(varname = 'x', value = self.foo),), p[1].statements) self.assertIsInstance(p[2], ast.StatementMacroStmt) self.assertLocation(p[2], 9, 26) self.assertEqual('f3', p[2].name) self.assertEqual(('foo', 'bar'), p[2].parameters) self.assertEqual((ast.AssignmentStmt(varname = 'x', value = self.foo), ast.AssignmentStmt(varname = 'y', value = self.bar)), p[2].statements)
def test_module(self): def test_mod(src, *statements): with self.parse(src) as p: self.assertIsInstance(p, ast.Module) self.assertLocation(p, 0, 0) self.assertIsInstance(p.filename, type('')) self.assertEqual('', p.filename) self.assertIsInstance(p.statements, tuple) self.assertEqual(statements, p.statements) # Empty test_mod('') test_mod('// This module is empty\n \n') # Single statement test_mod(''' var foo = bar ''', ast.VarStmt(name='foo', value=self.bar), ) # Multiple statements test_mod(''' // This is a nice module var foo = bar x = 2 // One more statement foo bar () ''', ast.VarStmt(name='foo', value=self.bar), ast.AssignmentStmt(varname='x', value=self.two), ast.DeclarationStmt(type = 'foo', tag = 'bar', params = (), children = ()), ) # Missing newline between statements with self.parse(''' x = 1 y = 2 '''): self.assertError('Missing newline at end of statement', token='y')
def test_basic(self): basedir = os.path.join(self.tmpdir, 'base') os.mkdir(basedir) blah_src = '''\ foo = 1 blah () ''' blah_path = self.write_file('base/blah.mwel', blah_src) something_src = '''\ baz { foo = 3 } ''' something_path = self.write_file('something.mwel', something_src) syntax_error_src = '''\ bar = = 1 ''' syntax_error_path = self.write_file('syntax_error.foo', syntax_error_src) with self.parse( '''\ var foo = bar %%include blah bar = 2 %%include "../something.mwel" foo bar () {} %%include not_an_include bar = foo %%include '%s/syntax_error.foo' bar = 1 %%include 'blah.mwel' // Repeated include is OK ''' % self.tmpdir, basedir) as p: self.assertIsInstance(p, ast.Module) self.assertEqual(10, len(p.statements)) self.assertEqual( ast.DeclarationStmt(type='var', tag='foo', value=self.bar), p.statements[0]) blah = p.statements[1] self.assertIsInstance(blah, ast.Module) self.assertLocation(blah, 2, 2) self.assertEqual(blah_path, blah.filename) self.assertEqual(2, len(blah.statements)) self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.one), blah.statements[0]) self.assertEqual(ast.DeclarationStmt(type='blah'), blah.statements[1]) self.assertEqual(ast.AssignmentStmt(varname='bar', value=self.two), p.statements[2]) something = p.statements[3] self.assertIsInstance(something, ast.Module) self.assertLocation(something, 4, 2) self.assertEqual(something_path, something.filename) self.assertEqual(1, len(something.statements)) self.assertEqual( ast.DeclarationStmt(type='baz', children=(ast.AssignmentStmt( varname='foo', value=self.three), )), something.statements[0]) self.assertEqual(ast.DeclarationStmt(type='foo', tag='bar'), p.statements[4]) self.assertError(("Failed to open file '%s': " "No such file or directory" % os.path.join(basedir, 'not_an_include.mwel')), lineno=6, colno=2) not_an_include = p.statements[5] self.assertIsInstance(not_an_include, ast.Module) self.assertLocation(not_an_include, 6, 2) self.assertEqual(os.path.join(basedir, 'not_an_include.mwel'), not_an_include.filename) self.assertEqual(0, len(not_an_include.statements)) self.assertEqual(ast.AssignmentStmt(varname='bar', value=self.foo), p.statements[6]) self.assertError(token='=', lineno=1, colno=7, filename=os.path.join(self.tmpdir, 'syntax_error.foo')) syntax_error = p.statements[7] self.assertIsInstance(syntax_error, ast.Module) self.assertLocation(syntax_error, 8, 2) self.assertEqual(syntax_error_path, syntax_error.filename) self.assertEqual(0, len(syntax_error.statements)) self.assertEqual(ast.AssignmentStmt(varname='bar', value=self.one), p.statements[8]) blah_2 = p.statements[9] self.assertIsInstance(blah_2, ast.Module) self.assertLocation(blah_2, 10, 2) self.assertEqual(blah_path, blah_2.filename) self.assertEqual(0, len(blah_2.statements)) self.assertIsInstance(self.parser.included_files, dict) self.assertEqual(3, len(self.parser.included_files)) included_files = list(self.parser.included_files.items()) self.assertEqual(blah_path, included_files[0][0]) self.assertEqual(blah_src, included_files[0][1]) self.assertEqual(something_path, included_files[1][0]) self.assertEqual(something_src, included_files[1][1]) self.assertEqual(syntax_error_path, included_files[2][0]) self.assertEqual(syntax_error_src, included_files[2][1])
def test_declaration_stmt(self): def test_decl(src, typename, tagname=None, value=None, params=(), children=()): with self.parse(src) as p: self.assertIsInstance(p, ast.Module) self.assertEqual(1, len(p.statements)) p = p.statements[0] self.assertIsInstance(p, ast.DeclarationStmt) self.assertLocation(p, 1, 1) self.assertEqual(typename, p.type) self.assertEqual(tagname, p.tag) self.assertEqual(value, p.value) self.assertIsInstance(p.params, (tuple, dict)) self.assertEqual(params, p.params) self.assertIsInstance(p.children, tuple) self.assertEqual(children, p.children) # # Basics # test_decl('foo ()', 'foo') test_decl('foo ( \n \n\n \n )', 'foo') test_decl('foo/bar blah ()', 'foo/bar', 'blah') test_decl('foo (bar)', 'foo', params=(self.bar, )) test_decl( 'foo ( \n \n 1 \n + \n \n foo \n )', 'foo', params=(self.one_plus_foo, ), ) test_decl('foo/bar (p1 = 1)', 'foo/bar', params={'p1': self.one}) test_decl( 'foo/bar (p1 = 1; p2 = 2; p3 = 3)', 'foo/bar', params={ 'p1': self.one, 'p2': self.two, 'p3': self.three }, ) test_decl('''foo 'blah blah blah' ( p1 = 1 p2 = 2 ) ''', 'foo', 'blah blah blah', params={ 'p1': self.one, 'p2': self.two }) # # Expression lists # foo_bar = ast.ExprList(items=(self.foo, self.bar)) one_two_three = ast.ExprList(items=(self.one, self.two, self.three)) foo_to_bar = ast.RangeExpr(start=self.foo, stop=self.bar) test_decl('foo "bar" (foo, bar)', 'foo', 'bar', params=(foo_bar, )) test_decl('''foo/bar ( abc = 1,2,3 xyz = foo:bar ) ''', 'foo/bar', params={ 'abc': one_two_three, 'xyz': foo_to_bar }) # # Children # # Empty child list test_decl('foo () {}', 'foo') test_decl('foo {}', 'foo') # One child test_decl( '''foo/bar (p1 = 1) { x = 2 } ''', 'foo/bar', params={'p1': self.one}, children=(ast.AssignmentStmt(varname='x', value=self.two), ), ) # Multiple children test_decl( '''foo bar (p1 = 1; p2 = 2) { var foo = bar x = 2 foo bar () {} } ''', 'foo', 'bar', params={ 'p1': self.one, 'p2': self.two }, children=( ast.DeclarationStmt(type='var', tag='foo', value=self.bar), ast.AssignmentStmt(varname='x', value=self.two), ast.DeclarationStmt(type='foo', tag='bar'), ), ) # # Value # # No params or children test_decl('foo bar = 1', 'foo', 'bar', value=self.one) # Params test_decl('foo bar = 1 (p1 = 1)', 'foo', 'bar', value=self.one, params={'p1': self.one}) # Children test_decl( '''foo/bar blah = 2 { x = 2 } ''', 'foo/bar', 'blah', value=self.two, children=(ast.AssignmentStmt(varname='x', value=self.two), ), ) # Params and children test_decl( '''foo/bar blah = 2 (p1 = 1) { x = 2 } ''', 'foo/bar', 'blah', value=self.two, params={'p1': self.one}, children=(ast.AssignmentStmt(varname='x', value=self.two), ), ) # # Errors # # Bad sub-type with self.parse('foo/1 ()'): self.assertExpected('identifier', got='1') # Extra / with self.parse(''' foo/bar/blah () '''): self.assertExpected("'(' or '{'", got='/', colno=32) # No parentheses with self.parse(''' foo blah bar abc () '''): self.assertExpected("'(' or '{'", lineno=2, colno=33) # Missing right paren with self.parse(''' foo blah ( bar abc () '''): self.assertExpected(')', got='abc') # Bad param name with self.parse(''' foo ( a = 1 'b' = 2 ) '''): self.assertExpected('identifier', got="'b'") # Missing = with self.parse('foo (a 1)'): self.assertExpected(')', got='1') # Missing value with self.parse(''' foo ( a = b = 2 ) '''): self.assertError('Line ended unexpectedly', token='\n', lineno=3) # Missing newline or semicolon with self.parse('foo (a = 1 b = 2)'): self.assertExpected("line ending or ';'", got='b') # Extra semicolon with self.parse('foo (a = 1; b = 2;)'): self.assertExpected('identifier', got=')') # Missing right brace with self.parse(''' foo () { x = 1 y = 2 bar () '''): self.assertError('Input ended unexpectedly') # Value without tag with self.parse('foo = 1 (b = 2)'): self.assertError('Missing newline at end of statement', token='(')
def test_nested(self): os.makedirs(os.path.join(self.tmpdir, 'dir1/dir2')) os.makedirs(os.path.join(self.tmpdir, 'dir3/dir4')) include1_src = '''\ foo = 2 %include 'dir2/include2' foo = 2 ''' include1_path = self.write_file('dir1/include1.mwel', include1_src) include2_src = '''\ foo = 3 %include '../../dir3/dir4/include3' foo = 3 ''' include2_path = self.write_file('dir1/dir2/include2.mwel', include2_src) include3_src = '''\ bar = 1 %include include3 // Recursive include is OK ''' include3_path = self.write_file('dir3/dir4/include3.mwel', include3_src) with self.parse('''\ foo = 1 %include 'dir1/include1' foo = 1 ''', self.tmpdir) as p: self.assertIsInstance(p, ast.Module) self.assertEqual(3, len(p.statements)) self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.one), p.statements[0]) self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.one), p.statements[2]) p = p.statements[1] self.assertIsInstance(p, ast.Module) self.assertEqual(3, len(p.statements)) self.assertLocation(p, 2, 2) self.assertEqual(include1_path, p.filename) self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.two), p.statements[0]) self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.two), p.statements[2]) p = p.statements[1] self.assertIsInstance(p, ast.Module) self.assertEqual(3, len(p.statements)) self.assertLocation(p, 2, 2) self.assertEqual(include2_path, p.filename) self.assertEqual( ast.AssignmentStmt(varname='foo', value=self.three), p.statements[0]) self.assertEqual( ast.AssignmentStmt(varname='foo', value=self.three), p.statements[2]) p = p.statements[1] self.assertIsInstance(p, ast.Module) self.assertEqual(2, len(p.statements)) self.assertLocation(p, 2, 2) self.assertEqual(include3_path, p.filename) self.assertEqual(ast.AssignmentStmt(varname='bar', value=self.one), p.statements[0]) p = p.statements[1] self.assertIsInstance(p, ast.Module) self.assertEqual(0, len(p.statements)) self.assertLocation(p, 2, 2) self.assertEqual(include3_path, p.filename) self.assertIsInstance(self.parser.included_files, dict) self.assertEqual(3, len(self.parser.included_files)) included_files = list(self.parser.included_files.items()) self.assertEqual(include1_path, included_files[0][0]) self.assertEqual(include1_src, included_files[0][1]) self.assertEqual(include2_path, included_files[1][0]) self.assertEqual(include2_src, included_files[1][1]) self.assertEqual(include3_path, included_files[2][0]) self.assertEqual(include3_src, included_files[2][1])