def test_visit_if(self): if_stmt = ast.If( condition="username", consequence=ast.Block([ ast.Text("Hello, "), ast.Lookup("username", transforms=[]), ast.Text("!"), ]), alternative=ast.Block([ast.Text("Hello, Guest!")]), ) renderer = self.render(if_stmt, {"username": "******"}) self.assertEqual(renderer.result, "Hello, rsiemens!") renderer = self.render(if_stmt, {"username": None}) self.assertEqual(renderer.result, "Hello, Guest!")
def if_stmt(self) -> ast.If: """ @if thing@ {thing} @else@ Nothing @endif@ """ self.match("@if ") word = self.word() self.match("@", after_whitespace=True) self.maybe_eat_newline() consequence = self.block() alternative = ast.Block([]) if self.peek_match("@else@"): self.match("@else@") self.maybe_eat_newline() alternative = self.block() self.match("@endif@") self.maybe_eat_newline() return ast.If(word, consequence, alternative)
def test_visit_call_macro(self): call = ast.Call(name="foo", arguments={}) renderer = Renderer(context={}, transforms={}) renderer.macros["foo"] = ([], ast.Text("foo text")) call.accept(renderer) self.assertEqual(renderer.result, "foo text") body = ast.Block([ ast.Text('<input type="'), ast.Lookup("type", transforms=[]), ast.Text('" value="'), ast.Lookup("value", transforms=[]), ast.Text('">'), ]) call = ast.Call( name="input", arguments={ "type": "text", "value": ast.Lookup("val", transforms=[]) }, ) renderer = Renderer(context={"val": "hi"}, transforms={}) renderer.macros["input"] = (["type", "value"], body) call.accept(renderer) self.assertEqual(renderer.result, '<input type="text" value="hi">')
def test_visit_macro(self): body = ast.Block([ ast.Text('<input type="'), ast.Lookup("type", transforms=[]), ast.Text('" value="'), ast.Lookup("value", transforms=[]), ast.Text('">'), ]) macro = ast.Macro(name="input", parameters=["type", "value"], body=body) renderer = self.render(macro, {}) self.assertEqual(renderer.result, "") self.assertEqual(renderer.macros, {"input": (["type", "value"], body)})
def test_visit_for(self): for_loop = ast.For( name="item", iterator="list", body=ast.Block([ ast.Text("item="), ast.Lookup("item", transforms=[]), ast.Text("\n") ]), ) renderer = self.render( for_loop, {"list": ["Bulbasaur", "Charmander", "Squirtle"]}) self.assertEqual(renderer.result, "item=Bulbasaur\nitem=Charmander\nitem=Squirtle\n") renderer = self.render(for_loop, {"list": []}) self.assertEqual(renderer.result, "")
def block(self) -> ast.Block: nodes: List[ast.AST] = [] while self.current: if self.peek_match("@if "): nodes.append(self.if_stmt()) elif self.peek_match("@for "): nodes.append(self.for_loop()) elif self.peek_match("@include "): nodes.append(self.include()) elif self.peek_match("@macro "): nodes.append(self.macro()) elif self.current == "{": nodes.append(self.lookup()) elif self.current != "@": nodes.append(self.text()) else: break return ast.Block(nodes)