def test_string_dbl_square(self): tree = ast.parse(r"b = [[hello]]") exp = Chunk( Block([ Assign( targets=[Name("b")], values=[String("hello", StringDelimiter.DOUBLE_SQUARE)], ) ])) self.assertEqual(exp, tree) tree = ast.parse( textwrap.dedent(r""" b = [[Multiple lines of text can be enclosed in double square brackets.]] """)) exp = Chunk( Block([ Assign( targets=[Name("b")], values=[ String( "Multiple lines of text\ncan be enclosed in double square\nbrackets.", StringDelimiter.DOUBLE_SQUARE, ) ], ) ])) self.assertEqual(exp, tree)
def test_string_dbl_square(self): tree = ast.parse(r'b = [[hello]]') exp = Chunk( Block([ Assign(targets=[Name('b')], values=[String('hello', StringDelimiter.DOUBLE_SQUARE)]) ])) self.assertEqual(exp, tree) tree = ast.parse( textwrap.dedent(r''' b = [[Multiple lines of text can be enclosed in double square brackets.]] ''')) exp = Chunk( Block([ Assign( targets=[Name('b')], values=[ String( 'Multiple lines of text\ncan be enclosed in double square\nbrackets.', StringDelimiter.DOUBLE_SQUARE) ]) ])) self.assertEqual(exp, tree)
def test_cont_int_3(self): tree = ast.parse(textwrap.dedent(r'x[a]')) exp = Chunk(Block([Index(idx=Name('a'), value=Name('x'))])) self.assertEqual(exp, tree) tree = ast.parse(textwrap.dedent(r'''x['a']''')) exp = Chunk(Block([Index(idx=String('a'), value=Name('x'))])) self.assertEqual(exp, tree) tree = ast.parse(textwrap.dedent(r'x.a')) exp = Chunk(Block([Index(idx=String('a'), value=Name('x'))])) self.assertEqual(exp, tree)
def test_string_dbl_square_equal(self): tree = ast.parse(r'b = [=[one [[two]] one]=]') exp = Chunk( Block([ Assign(targets=[Name('b')], values=[String('one [[two]] one')]) ])) self.assertEqual(exp, tree)
def test_function_def_anonymous(self): tree = ast.parse(r'f = function() local a end') exp = Chunk( Block([ Assign(targets=[Name('f')], values=[ AnonymousFunction(args=[], body=Block([ LocalAssign( targets=[Name('a')], values=[]) ])) ]) ])) self.assertEqual(exp, tree) # test tokens nodes = list(ast.walk(tree)) self.assertIsInstance(nodes[3], AnonymousFunction) self.assertEqual(nodes[3].tokens[0].value.text, ' ') self.assertEqual(nodes[3].tokens[1].value.text, 'function') self.assertEqual(nodes[3].tokens[2].value.text, '(') self.assertEqual(nodes[3].tokens[3].value.text, ')') self.assertEqual(nodes[3].tokens[4].value.text, ' ') self.assertEqual(nodes[3].tokens[5].value.text, 'local') self.assertEqual(nodes[3].tokens[6].value.text, ' ') self.assertEqual(nodes[3].tokens[7].value.text, 'a') self.assertEqual(nodes[3].tokens[8].value.text, ' ') self.assertEqual(nodes[3].tokens[9].value.text, 'end')
def test_empty_block(self): tree, builder = ast.parse(";;;;") exp = Chunk(Block([SemiColon(), SemiColon(), SemiColon(), SemiColon()])) self.assertEqual(exp, tree)
def test_function_def_local(self): tree = ast.parse(r'local function _process() end') exp = Chunk( Block([ LocalFunction(name=Name('_process'), args=[], body=Block([])) ])) self.assertEqual(exp, tree)
def test_array(self): tree = ast.parse( textwrap.dedent(r''' foo = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 } ''')) exp = Chunk( Block([ Assign(targets=[Name('foo')], values=[ Table([ Field(Number(1), Number(1)), Field(Number(2), Number(2)), Field(Number(3), Number(4)), Field(Number(4), Number(8)), Field(Number(5), Number(16)), Field(Number(6), Number(32)), Field(Number(7), Number(64)), Field(Number(8), Number(128)), Field(Number(9), Number(256)), Field(Number(10), Number(512)), Field(Number(11), Number(1024)), Field(Number(12), Number(2048)) ]) ]) ])) self.assertEqual(exp, tree)
def test_comment_in_table(self): tree = ast.parse(textwrap.dedent(""" --- @table a table of constants local limits = { -- pre field 1 HIGH = 127, -- max rate limit -- pre field 2 LOW = 42, -- min rate limit [true] = false, -- test "foo" -- just a value -- last ,toto -- toto value , Model = true -- model } """)) print(ast.toPrettyStr(tree)) exp = Chunk(Block([ LocalAssign( [Name('limits')], [Table([ Field(Name('HIGH'), Number(127), [Comment('-- pre field 1'), Comment('-- max rate limit')]), Field(Name('LOW'), Number(42), [Comment('-- pre field 2'), Comment('-- min rate limit')]), Field(TrueExpr(), FalseExpr(), [Comment('-- test')]), Field(Number(1), String('foo'), [Comment('-- just a value')]), Field(Number(2), Name('toto'), [Comment('-- last'), Comment('-- toto value')]), Field(Name('Model'), TrueExpr(), [Comment('-- model')]) ])], [Comment('--- @table a table of constants')] ) ])) #print(ast.toPrettyStr(exp)) self.assertEqual(exp, tree)
def test_comment_in_table_2(self): tree = ast.parse( textwrap.dedent(""" --- @module utils return { --- @export BAR = 4, --- test FOO = 5 } """)) exp = Chunk( Block([ Return(values=[ Table([ Field( Name("BAR"), Number(4), comments=[Comment("--- @export")], ), Field( Name("FOO"), Number(5), comments=[Comment("--- test")], ), ]) ]) ]), comments=[Comment("--- @module utils")], ) self.assertEqual(exp, tree)
def test_index_function_call(self): tree = ast.parse(r'foo.print {}') exp = Chunk( Block([ Call(func=Index(Name('print'), Name('foo')), args=[Table([])]) ])) self.assertEqual(exp, tree)
def test_table(self): source = textwrap.dedent('''\ local table = { ['ok'] = true, foo = bar, }''') self.assertEqual(source, ast.to_lua_source(ast.parse(source)))
def test_func(self): source = textwrap.dedent('''\ function nop(arg, ...) break return 1, 2, 3 end''') self.assertEqual(source, ast.to_lua_source(ast.parse(source)))
def test_while(self): source = textwrap.dedent('''\ while a[i] do print(a[i]) i = i + 1 end''') self.assertEqual(source, ast.to_lua_source(ast.parse(source)))
def test_nested_dict(self): tree = ast.parse( textwrap.dedent(r""" foo = { car = { name = 'bmw' }, options = { radio = true } };;; """)) exp = Chunk( Block([ Assign( targets=[Name("foo")], values=[ Table([ Field( Name("car"), Table([Field(Name("name"), String("bmw"))]), ), Field( Name("options"), Table([Field(Name("radio"), TrueExpr())]), ), ]) ], ), SemiColon(), SemiColon(), SemiColon(), ])) self.assertEqual(exp, tree)
def test_cont_int_1(self): tree, builder = ast.parse(textwrap.dedent(r''' describe("", function() it(function() do function foo() end end end) do function bar() end end end) ''')) exp = Chunk(Block([ Call(Name('describe'), [ String('\"\"'), AnonymousFunction([], Block([ Call(Name('it'), [ AnonymousFunction([], Block([ Do(Block([ Function(Name('foo'), [], Block([])) ])) ])) ]), Do(Block([ Function(Name('bar'), [], Block([])) ])) ])) ]) ])) self.assertEqual(exp, tree)
def test_addition(self): tree = ast.parse(r'a = 1 + 0.2') exp = Chunk( Block([ Assign(targets=[Name('a')], values=[AddOp(left=Number(1), right=Number(0.2))]) ])) self.assertEqual(exp, tree) # test tokens nodes = list(ast.walk(tree)) self.assertIsInstance(nodes[0], Chunk) self.assertEqual(nodes[0].tokens[0].value.text, 'a') self.assertEqual(nodes[0].tokens[1].value.text, ' ') self.assertEqual(nodes[0].tokens[2].value.text, '=') self.assertEqual(nodes[0].tokens[3].value.text, ' ') self.assertEqual(nodes[0].tokens[4].value.text, '1') self.assertEqual(nodes[0].tokens[5].value.text, ' ') self.assertEqual(nodes[0].tokens[6].value.text, '+') self.assertEqual(nodes[0].tokens[7].value.text, ' ') self.assertEqual(nodes[0].tokens[8].value.text, '0.2') self.assertIsInstance(nodes[1], Block) self.assertEqual(nodes[1].tokens[0].value.text, 'a') self.assertEqual(nodes[1].tokens[1].value.text, ' ') self.assertEqual(nodes[1].tokens[2].value.text, '=') self.assertEqual(nodes[1].tokens[3].value.text, ' ') self.assertEqual(nodes[1].tokens[4].value.text, '1') self.assertEqual(nodes[1].tokens[5].value.text, ' ') self.assertEqual(nodes[1].tokens[6].value.text, '+') self.assertEqual(nodes[1].tokens[7].value.text, ' ') self.assertEqual(nodes[1].tokens[8].value.text, '0.2') self.assertIsInstance(nodes[2], Assign) self.assertEqual(nodes[2].tokens[0].value.text, 'a') self.assertEqual(nodes[2].tokens[1].value.text, ' ') self.assertEqual(nodes[2].tokens[2].value.text, '=') self.assertEqual(nodes[2].tokens[3].value.text, ' ') self.assertEqual(nodes[2].tokens[4].value.text, '1') self.assertEqual(nodes[2].tokens[5].value.text, ' ') self.assertEqual(nodes[2].tokens[6].value.text, '+') self.assertEqual(nodes[2].tokens[7].value.text, ' ') self.assertEqual(nodes[2].tokens[8].value.text, '0.2') self.assertIsInstance(nodes[3], AddOp) self.assertEqual(nodes[3].tokens[0].value.text, ' ') self.assertEqual(nodes[3].tokens[1].value.text, '1') self.assertEqual(nodes[3].tokens[2].value.text, ' ') self.assertEqual(nodes[3].tokens[3].value.text, '+') self.assertEqual(nodes[3].tokens[4].value.text, ' ') self.assertEqual(nodes[3].tokens[5].value.text, '0.2') self.assertIsInstance(nodes[4], Number) self.assertEqual(nodes[4].tokens[0].value.text, ' ') self.assertEqual(nodes[4].tokens[1].value.text, '0.2') self.assertIsInstance(nodes[5], Number) self.assertEqual(nodes[5].tokens[0].value.text, ' ') self.assertEqual(nodes[5].tokens[1].value.text, '1')
def test_dict(self): tree = ast.parse(r'a = {foo = "bar", bar = "foo"}') exp = Chunk( Block([ Assign(targets=[Name('a')], values=[ Table(keys=[Name('foo'), Name('bar')], values=[String('bar'), String('foo')]) ]) ])) self.assertEqual(exp, tree) # test tokens nodes = list(ast.walk(tree)) self.assertIsInstance(nodes[3], Table) self.assertEqual(nodes[3].tokens[0].value.text, ' ') self.assertEqual(nodes[3].tokens[1].value.text, '{') self.assertEqual(nodes[3].tokens[2].value.text, 'foo') self.assertEqual(nodes[3].tokens[3].value.text, ' ') self.assertEqual(nodes[3].tokens[4].value.text, '=') self.assertEqual(nodes[3].tokens[5].value.text, ' ') self.assertEqual(nodes[3].tokens[6].value.text, '"bar"') self.assertEqual(nodes[3].tokens[7].value.text, ',') self.assertEqual(nodes[3].tokens[8].value.text, ' ') self.assertEqual(nodes[3].tokens[9].value.text, 'bar') self.assertEqual(nodes[3].tokens[10].value.text, ' ') self.assertEqual(nodes[3].tokens[11].value.text, '=') self.assertEqual(nodes[3].tokens[12].value.text, ' ') self.assertEqual(nodes[3].tokens[13].value.text, '"foo"') self.assertEqual(nodes[3].tokens[14].value.text, '}')
def test_nested_dict(self): tree = ast.parse( textwrap.dedent(r''' foo = { car = { name = 'bmw' }, options = { radio = true } };;; ''')) exp = Chunk( Block([ Assign(targets=[Name('foo')], values=[ Table([ Field( Name('car'), Table([Field(Name('name'), String('bmw'))])), Field(Name('options'), Table([Field(Name('radio'), TrueExpr())])) ]) ]), SemiColon(), SemiColon(), SemiColon() ])) self.assertEqual(exp, tree)
def test_mix_dict_array(self): tree = ast.parse( textwrap.dedent(r''' foo = { options = { radio = true }, "enabled", 157 }; ''')) exp = Chunk( Block([ Assign(targets=[Name('foo')], values=[ Table(keys=[Name('options'), Number(1), Number(2)], values=[ Table(keys=[Name('radio')], values=[TrueExpr()]), String('enabled'), Number(157) ]) ]) ])) self.assertEqual(exp, tree)
def test_mix_dict_array(self): tree = ast.parse( textwrap.dedent(r''' foo = { options = { radio = true }, "enabled", 157, [true] = false, ['true'] = true, }; ''')) exp = Chunk( Block([ Assign(targets=[Name('foo')], values=[ Table([ Field(Name('options'), Table([Field(Name('radio'), TrueExpr())])), Field(Number(1), String('enabled')), Field(Number(2), Number(157)), Field(TrueExpr(), FalseExpr(), between_brackets=True), Field(String('true'), TrueExpr(), between_brackets=True), ]) ]), SemiColon() ])) self.assertEqual(exp, tree)
def test_function_nested_invoke(self): tree = ast.parse(r'foo:bar():print("hello")') exp = Chunk( Block([ Invoke(source=Invoke(source=Name('foo'), func=Name('bar'), args=[]), func=Name('print'), args=[String('hello')]) ])) self.assertEqual(exp, tree) # test tokens nodes = list(ast.walk(tree)) self.assertIsInstance(nodes[2], Invoke) self.assertEqual(nodes[2].tokens[0].value.text, 'foo') self.assertEqual(nodes[2].tokens[1].value.text, ':') self.assertEqual(nodes[2].tokens[2].value.text, 'bar') self.assertEqual(nodes[2].tokens[3].value.text, '(') self.assertEqual(nodes[2].tokens[4].value.text, ')') self.assertEqual(nodes[2].tokens[5].value.text, ':') self.assertEqual(nodes[2].tokens[6].value.text, 'print') self.assertEqual(nodes[2].tokens[7].value.text, '(') self.assertEqual(nodes[2].tokens[8].value.text, '"hello"') self.assertEqual(nodes[2].tokens[9].value.text, ')') self.assertIsInstance(nodes[5], Invoke) self.assertEqual(nodes[5].tokens[0].value.text, 'foo') self.assertEqual(nodes[5].tokens[1].value.text, ':') self.assertEqual(nodes[5].tokens[2].value.text, 'bar') self.assertEqual(nodes[5].tokens[3].value.text, '(') self.assertEqual(nodes[5].tokens[4].value.text, ')')
def test_cont_int_6(self): tree = ast.parse( textwrap.dedent(""" foo = { mykey = "myvalue", -- this comment is ignored if previous line ends with a comma } """)) exp = Chunk( Block([ Assign( [Name("foo")], [ Table([ Field( Name("mykey"), String( "myvalue", delimiter=StringDelimiter.DOUBLE_QUOTE, ), comments=[ Comment( "-- this comment is ignored if previous line ends with a comma" ) ], ), ]) ], ) ])) self.assertEqual(exp, tree)
def test_string_quote(self): tree = ast.parse(r"b = 'another line'") exp = Chunk( Block( [Assign(targets=[Name('b')], values=[String('another line')])])) self.assertEqual(exp, tree)
def walk_functions(code): tree = ast.parse(code) try: yield from walk_functions_block(tree.body.body, ()) except Exception as e: print(e) print(code)
def test_label(self): tree, builder = ast.parse( textwrap.dedent(""" ::foo:: """)) exp = Chunk(Block([Label(Name('foo'))])) self.assertEqual(exp, tree)
def test_break(self): tree, builder = ast.parse( textwrap.dedent(""" break """)) exp = Chunk(Block([Break()])) self.assertEqual(exp, tree)
def test_set_table_index(self): tree, builder = ast.parse('_ENV.x = val') exp = Chunk( Block([ Assign(targets=[Index(idx=String('x'), value=Name('_ENV'))], values=[Name('val')]) ])) self.assertEqual(exp, tree)
def test_set_array_index(self): tree, builder = ast.parse('a[i] = 42') exp = Chunk( Block([ Assign(targets=[Index(idx=Name('i'), value=Name('a'))], values=[Number(42)]) ])) self.assertEqual(exp, tree)
def test_repeat_until(self): tree, builder = ast.parse( textwrap.dedent(""" repeat until true """)) exp = Chunk(Block([Repeat(body=Block([]), test=TrueExpr())])) self.assertEqual(exp, tree)