diff options
Diffstat (limited to 'test/test_call.py')
-rw-r--r-- | test/test_call.py | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/test/test_call.py b/test/test_call.py new file mode 100644 index 0000000..164c899 --- /dev/null +++ b/test/test_call.py @@ -0,0 +1,429 @@ +from mako.template import Template +from mako import util +import unittest +from util import result_lines, flatten_result + +class CallTest(unittest.TestCase): + def test_call(self): + t = Template(""" + <%def name="foo()"> + hi im foo ${caller.body(y=5)} + </%def> + + <%call expr="foo()" args="y, **kwargs"> + this is the body, y is ${y} + </%call> +""") + assert result_lines(t.render()) == ['hi im foo', 'this is the body, y is 5'] + + + def test_compound_call(self): + t = Template(""" + + <%def name="bar()"> + this is bar + </%def> + + <%def name="comp1()"> + this comp1 should not be called + </%def> + + <%def name="foo()"> + foo calling comp1: ${caller.comp1(x=5)} + foo calling body: ${caller.body()} + </%def> + + <%call expr="foo()"> + <%def name="comp1(x)"> + this is comp1, ${x} + </%def> + this is the body, ${comp1(6)} + </%call> + ${bar()} + +""") + assert result_lines(t.render()) == ['foo calling comp1:', 'this is comp1, 5', 'foo calling body:', 'this is the body,', 'this is comp1, 6', 'this is bar'] + + def test_compound_call_revset(self): + # monkeypatch Set to return items in reverse + oldset = util.Set + class goofyset(oldset): + def __iter__(self): + x = list(oldset.__iter__(self)) + x.reverse() + return iter(x) + util.Set = goofyset + + try: + self.test_compound_call() + finally: + util.Set = oldset + + def test_ccall_caller(self): + t = Template(""" + <%def name="outer_func()"> + OUTER BEGIN + <%call expr="caller.inner_func()"> + INNER CALL + </%call> + OUTER END + </%def> + + <%call expr="outer_func()"> + <%def name="inner_func()"> + INNER BEGIN + ${caller.body()} + INNER END + </%def> + </%call> + + """) + #print t.code + assert result_lines(t.render()) == [ + "OUTER BEGIN", + "INNER BEGIN", + "INNER CALL", + "INNER END", + "OUTER END", + ] + + def test_stack_pop(self): + t = Template(""" + <%def name="links()" buffered="True"> + Some links + </%def> + + <%def name="wrapper(links)"> + <h1>${caller.body()}</h1> + ${links} + </%def> + + ## links() pushes a stack frame on. when complete, + ## 'nextcaller' must be restored + <%call expr="wrapper(links())"> + Some title + </%call> + + """) + + assert result_lines(t.render()) == [ + "<h1>", + "Some title", + "</h1>", + "Some links" + ] + + def test_conditional_call(self): + """test that 'caller' is non-None only if the immediate <%def> was called via <%call>""" + + t = Template(""" + <%def name="a()"> + % if caller: + ${ caller.body() } \\ + % endif + AAA + ${ b() } + </%def> + + <%def name="b()"> + % if caller: + ${ caller.body() } \\ + % endif + BBB + ${ c() } + </%def> + + <%def name="c()"> + % if caller: + ${ caller.body() } \\ + % endif + CCC + </%def> + + <%call expr="a()"> + CALL + </%call> + + """) + assert result_lines(t.render()) == [ + "CALL", + "AAA", + "BBB", + "CCC" + ] + + def test_chained_call(self): + """test %calls that are chained through their targets""" + t = Template(""" + <%def name="a()"> + this is a. + <%call expr="b()"> + this is a's ccall. heres my body: ${caller.body()} + </%call> + </%def> + <%def name="b()"> + this is b. heres my body: ${caller.body()} + whats in the body's caller's body ? + ${context.caller_stack[-2].body()} + </%def> + + <%call expr="a()"> + heres the main templ call + </%call> + +""") + assert result_lines(t.render()) == [ + 'this is a.', + 'this is b. heres my body:', + "this is a's ccall. heres my body:", + 'heres the main templ call', + "whats in the body's caller's body ?", + 'heres the main templ call' + ] + + def test_nested_call(self): + """test %calls that are nested inside each other""" + t = Template(""" + <%def name="foo()"> + ${caller.body(x=10)} + </%def> + + x is ${x} + <%def name="bar()"> + bar: ${caller.body()} + </%def> + + <%call expr="foo()" args="x"> + this is foo body: ${x} + + <%call expr="bar()"> + this is bar body: ${x} + </%call> + </%call> +""") + assert result_lines(t.render(x=5)) == [ + "x is 5", + "this is foo body: 10", + "bar:", + "this is bar body: 10" + ] + + def test_nested_call_2(self): + t = Template(""" + x is ${x} + <%def name="foo()"> + ${caller.foosub(x=10)} + </%def> + + <%def name="bar()"> + bar: ${caller.barsub()} + </%def> + + <%call expr="foo()"> + <%def name="foosub(x)"> + this is foo body: ${x} + + <%call expr="bar()"> + <%def name="barsub()"> + this is bar body: ${x} + </%def> + </%call> + + </%def> + + </%call> +""") + assert result_lines(t.render(x=5)) == [ + "x is 5", + "this is foo body: 10", + "bar:", + "this is bar body: 10" + ] + + def test_nested_call_3(self): + template = Template('''\ + <%def name="A()"> + ${caller.body()} + </%def> + + <%def name="B()"> + ${caller.foo()} + </%def> + + <%call expr="A()"> + <%call expr="B()"> + <%def name="foo()"> + foo + </%def> + </%call> + </%call> + + ''') + assert flatten_result(template.render()) == "foo" + + def test_chained_call_in_nested(self): + t = Template(""" + <%def name="embedded()"> + <%def name="a()"> + this is a. + <%call expr="b()"> + this is a's ccall. heres my body: ${caller.body()} + </%call> + </%def> + <%def name="b()"> + this is b. heres my body: ${caller.body()} + whats in the body's caller's body ? ${context.caller_stack[-2].body()} + </%def> + + <%call expr="a()"> + heres the main templ call + </%call> + </%def> + ${embedded()} +""") + #print t.code + #print result_lines(t.render()) + assert result_lines(t.render()) == [ + 'this is a.', + 'this is b. heres my body:', + "this is a's ccall. heres my body:", + 'heres the main templ call', + "whats in the body's caller's body ?", + 'heres the main templ call' + ] + + def test_call_in_nested(self): + t = Template(""" + <%def name="a()"> + this is a ${b()} + <%def name="b()"> + this is b + <%call expr="c()"> + this is the body in b's call + </%call> + </%def> + <%def name="c()"> + this is c: ${caller.body()} + </%def> + </%def> + ${a()} +""") + assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call"] + + def test_regular_defs(self): + t = Template(""" + <%! + @runtime.supports_caller + def a(context): + context.write("this is a") + if context['caller']: + context['caller'].body() + context.write("a is done") + return '' + %> + + <%def name="b()"> + this is b + our body: ${caller.body()} + ${a(context)} + </%def> + test 1 + <%call expr="a(context)"> + this is the body + </%call> + test 2 + <%call expr="b()"> + this is the body + </%call> + test 3 + <%call expr="b()"> + this is the body + <%call expr="b()"> + this is the nested body + </%call> + </%call> + + + """) + #print t.code + assert result_lines(t.render()) == [ + "test 1", + "this is a", + "this is the body", + "a is done", + "test 2", + "this is b", + "our body:", + "this is the body", + "this is aa is done", + "test 3", + "this is b", + "our body:", + "this is the body", + "this is b", + "our body:", + "this is the nested body", + "this is aa is done", + "this is aa is done" + ] + + def test_call_in_nested_2(self): + t = Template(""" + <%def name="a()"> + <%def name="d()"> + not this d + </%def> + this is a ${b()} + <%def name="b()"> + <%def name="d()"> + not this d either + </%def> + this is b + <%call expr="c()"> + <%def name="d()"> + this is d + </%def> + this is the body in b's call + </%call> + </%def> + <%def name="c()"> + this is c: ${caller.body()} + the embedded "d" is: ${caller.d()} + </%def> + </%def> + ${a()} +""") + assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call", 'the embedded "d" is:', 'this is d'] + +class SelfCacheTest(unittest.TestCase): + """this test uses a now non-public API.""" + + def test_basic(self): + t = Template(""" + <%! + cached = None + %> + <%def name="foo()"> + <% + global cached + if cached: + return "cached: " + cached + __M_writer = context._push_writer() + %> + this is foo + <% + buf, __M_writer = context._pop_buffer_and_writer() + cached = buf.getvalue() + return cached + %> + </%def> + + ${foo()} + ${foo()} +""") + assert result_lines(t.render()) == [ + "this is foo", + "cached:", + "this is foo" + ] + |