Newer
Older
from mako.template import Template
from util import flatten_result, result_lines
<%def name="mycomp()">
eq_(
template.render(variable='hi').strip(),
"""hello mycomp hi"""
)
eq_(
template.render(variable='hi').strip(),
"hello mycomp hi"
)
hello mycomp ${variable}, ${a}, ${b}
eq_(
template.render(variable='hi', a=5, b=6).strip(),
"""hello mycomp hi, 5, 6"""
)
def test_inter_def(self):
"""test defs calling each other"""
<%def name="a()">\
<%def name="b()">
<%def name="c()">
# check that "a" is declared in "b", but not in "c"
assert "a" not in template.module.render_c.func_code.co_varnames
assert "a" in template.module.render_b.func_code.co_varnames
eq_(
flatten_result(template.render()),
"im b and heres a: im a"
)
def test_toplevel(self):
"""test calling a def from the top level"""
template = Template("""
this is the body
<%def name="a()">
this is a
</%def>
<%def name="b(x, y)">
this is b, ${x} ${y}
</%def>
self._do_test(template.get_def("a"),
"this is a",
filters=flatten_result)
self._do_test(template.get_def("b"),
"this is b, 10 15",
template_args={'x': 10, 'y': 15},
filters=flatten_result)
self._do_test(template.get_def("body"),
"this is the body",
filters=flatten_result)
# test that args outside of the dict can be used
self._do_test(template.get_def("a"), "this is a",
filters=flatten_result,
template_args={'q': 5, 'zq': 'test'})
"""test scoping rules. The key is, enclosing
scope always takes precedence over contextual scope."""
<%def name="a()">
${a()}
<%
y = 7
%>
${a()}
""",
"this is a, and y is None this is a, and y is 7",
filters=flatten_result,
y is ${y}
<%
y = 7
%>
y is ${y}
try:
t.render(y=None)
assert False
except UnboundLocalError:
assert True
"""test that variables are pulled
from 'enclosing' scope before context."""
t = Template("""
<%
x = 5
%>
<%def name="a()">
<%def name="b()">
<%
x = 9
%>
this is b. x is ${x}.
calling a. ${a()}
eq_(
flatten_result(t.render()),
"this is b. x is 9. calling a. this is a. x is 5."
)
"""test that variables are pulled from
'enclosing' scope before context."""
# same as test four, but adds a scope around it.
t = Template("""
<%def name="enclosing()">
<%def name="a()">
<%def name="b()">
<%
x = 9
%>
this is b. x is ${x}.
calling a. ${a()}
eq_(
flatten_result(t.render()),
"this is b. x is 9. calling a. this is a. x is 5."
)
"""test that the initial context counts
as 'enclosing' scope, for plain defs"""
<%def name="a()">
<%def name="b()">
<%
x = 10
%>
b. x is ${x}. ${a()}
eq_(
flatten_result(t.render(x=5)),
"b. x is 10. a: x is 5"
)
def test_scope_seven(self):
"""test that the initial context counts
as 'enclosing' scope, for nested defs"""
<%def name="enclosing()">
<%def name="a()">
<%def name="b()">
<%
x = 10
%>
b. x is ${x}. ${a()}
eq_(
flatten_result(t.render(x=5)),
"b. x is 10. a: x is 5"
)
def test_scope_eight(self):
"""test that the initial context counts
as 'enclosing' scope, for nested defs"""
<%def name="enclosing()">
<%def name="a()">
<%def name="b()">
eq_(
flatten_result(t.render(x=5)),
"b. x is 10. a: x is 5"
)
"""test that 'enclosing scope' doesnt
get exported to other templates"""
l = lookup.TemplateLookup()
l.put_string('main', """
<%
x = 5
%>
this is main. <%include file="secondary"/>
""")
l.put_string('secondary', """
""")
eq_(
flatten_result(l.get_template('main').render(x=2)),
"this is main. this is secondary. x is 2"
)
def test_scope_ten(self):
t = Template("""
<%def name="a()">
<%def name="b()">
<%
y = 19
%>
b/c: ${c()}
b/y: ${y}
<%def name="c()">
c/y: ${y}
<%
# we assign to "y". but the 'enclosing
# scope' of "b" and "c" is from
# the "y" on the outside
y = 10
%>
a/y: ${y}
a/b: ${b()}
<%
y = 7
%>
main/a: ${a()}
main/y: ${y}
""")
eq_(
flatten_result(t.render()),
"main/a: a/y: 10 a/b: b/c: c/y: 10 b/y: 19 main/y: 7"
)
def test_scope_eleven(self):
t = Template("""
x is ${x}
<%def name="a(x)">
this is a, ${b()}
<%def name="b()">
this is b, x is ${x}
</%def>
</%def>
def test_unbound_scope(self):
t = Template("""
<%
y = 10
%>
<%def name="a()">
y is: ${y}
<%
# should raise error ?
y = 15
%>
y is ${y}
${a()}
""")
assert_raises(
UnboundLocalError,
t.render
)
def test_unbound_scope_two(self):
t = Template("""
<%def name="enclosing()">
<%
y = 10
%>
<%def name="a()">
y is: ${y}
<%
# should raise error ?
y = 15
%>
y is ${y}
${a()}
${enclosing()}
""")
try:
print t.render()
assert False
except UnboundLocalError:
assert True
def test_canget_kwargs(self):
"""test that arguments passed to the body()
function are accessible by top-level defs"""
l = lookup.TemplateLookup()
l.put_string("base", """
${next.body(x=12)}
l.put_string("main", """
<%inherit file="base"/>
this is main. x is ${x}
<%def name="a(**args)">
this is a, x is ${x}
</%def>
""")
# test via inheritance
eq_(
result_lines(l.get_template("main").render()),
[
"this is main. x is 12",
"this is a, x is 12"
l.put_string("another", """
<%namespace name="ns" file="main"/>
${ns.body(x=15)}
""")
# test via namespace
eq_(
result_lines(l.get_template("another").render()),
[
"this is main. x is 15",
"this is a, x is 15"
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
def test_inline_expression_from_arg_one(self):
"""test that cache_key=${foo} gets its value from
the 'foo' argument in the <%def> tag,
and strict_undefined doesn't complain.
this is #191.
"""
t = Template("""
<%def name="layout(foo)" cached="True" cache_key="${foo}">
foo: ${foo}
</%def>
${layout(3)}
""", strict_undefined=True,
cache_impl="plain")
eq_(
result_lines(t.render()),
["foo: 3"]
)
def test_interpret_expression_from_arg_two(self):
"""test that cache_key=${foo} gets its value from
the 'foo' argument regardless of it being passed
from the context.
This is here testing that there's no change
to existing behavior before and after #191.
"""
t = Template("""
<%def name="layout(foo)" cached="True" cache_key="${foo}">
foo: ${value}
</%def>
${layout(3)}
""", cache_impl="plain")
eq_(
result_lines(t.render(foo='foo', value=1)),
["foo: 1"]
)
eq_(
result_lines(t.render(foo='bar', value=2)),
["foo: 1"]
)
<%def name="hi()">
hey, im hi.
and heres ${foo()}, ${bar()}
<%def name="foo()">
<%def name="bar()">
eq_(
flatten_result(t.render()),
"hey, im hi. and heres this is foo , this is bar"
)
def test_nested_2(self):
t = Template("""
x is ${x}
<%def name="a()">
this is a, x is ${x}
${b()}
<%def name="b()">
this is b: ${x}
</%def>
</%def>
${a()}
""")
eq_(
flatten_result(t.render(x=10)),
"x is 10 this is a, x is 10 this is b: 10"
)
<%def name="a()">
eq_(
flatten_result(t.render()),
"a b x is 5 y is 2"
)
template = Template("""
${a()}
<%def name="a()">
<%def name="b()">
<%def name="c()">
comp c
${c()}
${b()}
""")
eq_(
flatten_result(template.render()),
"comp c"
)
<%def name="a()">
<%def name="b1()">
a_b1
<%def name="b2()">
<%def name="c1()">
<%def name="b3()">
<%def name="c1()">
a_b3_c1 heres x: ${x}
<%
y = 7
%>
y is ${y}
<%def name="c2()">
a_b3_c2
y is ${y}
c1 is ${c1()}
eq_(
flatten_result(t.render(x=5, y=None)),
"a a_b1 a_b2 a_b2_c1 a_b3 a_b3_c1 "
"heres x: 5 y is 7 a_b3_c2 y is "
"None c1 is a_b3_c1 heres x: 5 y is 7"
)
<%def name="a()">
this is a ${b()}
<%def name="b()">
this is b
${c()}
<%def name="c()">
this is c
${a()}
""")
eq_(
flatten_result(t.render()),
"this is a this is b this is c"
)
def test_outer_scope(self):
t = Template("""
<%def name="a()">
<%def name="b()">
<%def name="c()">
<%
x = 10
%>
c. x is ${x}. ${a()}
eq_(
flatten_result(t.render(x=5)),
"b. c. x is 10. a: x is 5 x is 5"
)
def test_raise(self):
template = Template("""
<%
raise Exception("this is a test")
%>
""", format_exceptions=False)
assert_raises(
Exception,
template.render
)
def test_handler(self):
def handle(context, error):
context.write("error message is " + str(error))
return True
template = Template("""
<%
raise Exception("this is a test")
%>
""", error_handler=handle)
eq_(
template.render().strip(),
"error message is this is a test"
)