diff options
Diffstat (limited to 'test/test_namespace.py')
-rw-r--r-- | test/test_namespace.py | 1031 |
1 files changed, 1031 insertions, 0 deletions
diff --git a/test/test_namespace.py b/test/test_namespace.py new file mode 100644 index 0000000..b6b0544 --- /dev/null +++ b/test/test_namespace.py @@ -0,0 +1,1031 @@ +from mako import exceptions +from mako import lookup +from mako.template import Template +from mako.testing.assertions import assert_raises +from mako.testing.assertions import assert_raises_message_with_given_cause +from mako.testing.assertions import eq_ +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import flatten_result +from mako.testing.helpers import result_lines + + +class NamespaceTest(TemplateTest): + def test_inline_crossreference(self): + self._do_memory_test( + """ + <%namespace name="x"> + <%def name="a()"> + this is x a + </%def> + <%def name="b()"> + this is x b, and heres ${a()} + </%def> + </%namespace> + + ${x.a()} + + ${x.b()} + """, + "this is x a this is x b, and heres this is x a", + filters=flatten_result, + ) + + def test_inline_assignment(self): + self._do_memory_test( + """ + <%namespace name="x"> + <%def name="a()"> + <% + x = 5 + %> + this is x: ${x} + </%def> + </%namespace> + + ${x.a()} + + """, + "this is x: 5", + filters=flatten_result, + ) + + def test_inline_arguments(self): + self._do_memory_test( + """ + <%namespace name="x"> + <%def name="a(x, y)"> + <% + result = x * y + %> + result: ${result} + </%def> + </%namespace> + + ${x.a(5, 10)} + + """, + "result: 50", + filters=flatten_result, + ) + + def test_inline_not_duped(self): + self._do_memory_test( + """ + <%namespace name="x"> + <%def name="a()"> + foo + </%def> + </%namespace> + + <% + assert x.a is not UNDEFINED, "namespace x.a wasn't defined" + assert a is UNDEFINED, "name 'a' is in the body locals" + %> + + """, + "", + filters=flatten_result, + ) + + def test_dynamic(self): + collection = lookup.TemplateLookup() + + collection.put_string( + "a", + """ + <%namespace name="b" file="${context['b_def']}"/> + + a. b: ${b.body()} +""", + ) + + collection.put_string( + "b", + """ + b. +""", + ) + + eq_( + flatten_result(collection.get_template("a").render(b_def="b")), + "a. b: b.", + ) + + def test_template(self): + collection = lookup.TemplateLookup() + + collection.put_string( + "main.html", + """ + <%namespace name="comp" file="defs.html"/> + + this is main. ${comp.def1("hi")} + ${comp.def2("there")} +""", + ) + + collection.put_string( + "defs.html", + """ + <%def name="def1(s)"> + def1: ${s} + </%def> + + <%def name="def2(x)"> + def2: ${x} + </%def> +""", + ) + + assert ( + flatten_result(collection.get_template("main.html").render()) + == "this is main. def1: hi def2: there" + ) + + def test_module(self): + collection = lookup.TemplateLookup() + + collection.put_string( + "main.html", + """ + <%namespace name="comp" module="test.sample_module_namespace"/> + + this is main. ${comp.foo1()} + ${comp.foo2("hi")} +""", + ) + + assert ( + flatten_result(collection.get_template("main.html").render()) + == "this is main. this is foo1. this is foo2, x is hi" + ) + + def test_module_2(self): + collection = lookup.TemplateLookup() + + collection.put_string( + "main.html", + """ + <%namespace name="comp" module="test.foo.test_ns"/> + + this is main. ${comp.foo1()} + ${comp.foo2("hi")} +""", + ) + + assert ( + flatten_result(collection.get_template("main.html").render()) + == "this is main. this is foo1. this is foo2, x is hi" + ) + + def test_module_imports(self): + collection = lookup.TemplateLookup() + + collection.put_string( + "main.html", + """ + <%namespace import="*" module="test.foo.test_ns"/> + + this is main. ${foo1()} + ${foo2("hi")} +""", + ) + + assert ( + flatten_result(collection.get_template("main.html").render()) + == "this is main. this is foo1. this is foo2, x is hi" + ) + + def test_module_imports_2(self): + collection = lookup.TemplateLookup() + + collection.put_string( + "main.html", + """ + <%namespace import="foo1, foo2" module="test.foo.test_ns"/> + + this is main. ${foo1()} + ${foo2("hi")} +""", + ) + + assert ( + flatten_result(collection.get_template("main.html").render()) + == "this is main. this is foo1. this is foo2, x is hi" + ) + + def test_context(self): + """test that namespace callables get access to the current context""" + collection = lookup.TemplateLookup() + + collection.put_string( + "main.html", + """ + <%namespace name="comp" file="defs.html"/> + + this is main. ${comp.def1()} + ${comp.def2("there")} +""", + ) + + collection.put_string( + "defs.html", + """ + <%def name="def1()"> + def1: x is ${x} + </%def> + + <%def name="def2(x)"> + def2: x is ${x} + </%def> +""", + ) + + assert ( + flatten_result( + collection.get_template("main.html").render(x="context x") + ) + == "this is main. def1: x is context x def2: x is there" + ) + + def test_overload(self): + collection = lookup.TemplateLookup() + + collection.put_string( + "main.html", + """ + <%namespace name="comp" file="defs.html"> + <%def name="def1(x, y)"> + overridden def1 ${x}, ${y} + </%def> + </%namespace> + + this is main. ${comp.def1("hi", "there")} + ${comp.def2("there")} + """, + ) + + collection.put_string( + "defs.html", + """ + <%def name="def1(s)"> + def1: ${s} + </%def> + + <%def name="def2(x)"> + def2: ${x} + </%def> + """, + ) + + assert ( + flatten_result(collection.get_template("main.html").render()) + == "this is main. overridden def1 hi, there def2: there" + ) + + def test_getattr(self): + collection = lookup.TemplateLookup() + collection.put_string( + "main.html", + """ + <%namespace name="foo" file="ns.html"/> + <% + if hasattr(foo, 'lala'): + foo.lala() + if not hasattr(foo, 'hoho'): + context.write('foo has no hoho.') + %> + """, + ) + collection.put_string( + "ns.html", + """ + <%def name="lala()">this is lala.</%def> + """, + ) + assert ( + flatten_result(collection.get_template("main.html").render()) + == "this is lala.foo has no hoho." + ) + + def test_in_def(self): + collection = lookup.TemplateLookup() + collection.put_string( + "main.html", + """ + <%namespace name="foo" file="ns.html"/> + + this is main. ${bar()} + <%def name="bar()"> + this is bar, foo is ${foo.bar()} + </%def> + """, + ) + + collection.put_string( + "ns.html", + """ + <%def name="bar()"> + this is ns.html->bar + </%def> + """, + ) + + assert result_lines(collection.get_template("main.html").render()) == [ + "this is main.", + "this is bar, foo is", + "this is ns.html->bar", + ] + + def test_in_remote_def(self): + collection = lookup.TemplateLookup() + collection.put_string( + "main.html", + """ + <%namespace name="foo" file="ns.html"/> + + this is main. ${bar()} + <%def name="bar()"> + this is bar, foo is ${foo.bar()} + </%def> + """, + ) + + collection.put_string( + "ns.html", + """ + <%def name="bar()"> + this is ns.html->bar + </%def> + """, + ) + + collection.put_string( + "index.html", + """ + <%namespace name="main" file="main.html"/> + + this is index + ${main.bar()} + """, + ) + + assert result_lines( + collection.get_template("index.html").render() + ) == ["this is index", "this is bar, foo is", "this is ns.html->bar"] + + def test_dont_pollute_self(self): + # test that get_namespace() doesn't modify the original context + # incompatibly + + collection = lookup.TemplateLookup() + collection.put_string( + "base.html", + """ + + <%def name="foo()"> + <% + foo = local.get_namespace("foo.html") + %> + </%def> + + name: ${self.name} + name via bar: ${bar()} + + ${next.body()} + + name: ${self.name} + name via bar: ${bar()} + <%def name="bar()"> + ${self.name} + </%def> + + + """, + ) + + collection.put_string( + "page.html", + """ + <%inherit file="base.html"/> + + ${self.foo()} + + hello world + + """, + ) + + collection.put_string("foo.html", """<%inherit file="base.html"/>""") + assert result_lines(collection.get_template("page.html").render()) == [ + "name: self:page.html", + "name via bar:", + "self:page.html", + "hello world", + "name: self:page.html", + "name via bar:", + "self:page.html", + ] + + def test_inheritance(self): + """test namespace initialization in a base inherited template that + doesnt otherwise access the namespace""" + collection = lookup.TemplateLookup() + collection.put_string( + "base.html", + """ + <%namespace name="foo" file="ns.html" inheritable="True"/> + + ${next.body()} +""", + ) + collection.put_string( + "ns.html", + """ + <%def name="bar()"> + this is ns.html->bar + </%def> + """, + ) + + collection.put_string( + "index.html", + """ + <%inherit file="base.html"/> + + this is index + ${self.foo.bar()} + """, + ) + + assert result_lines( + collection.get_template("index.html").render() + ) == ["this is index", "this is ns.html->bar"] + + def test_inheritance_two(self): + collection = lookup.TemplateLookup() + collection.put_string( + "base.html", + """ + <%def name="foo()"> + base.foo + </%def> + + <%def name="bat()"> + base.bat + </%def> +""", + ) + collection.put_string( + "lib.html", + """ + <%inherit file="base.html"/> + <%def name="bar()"> + lib.bar + ${parent.foo()} + ${self.foo()} + ${parent.bat()} + ${self.bat()} + </%def> + + <%def name="foo()"> + lib.foo + </%def> + + """, + ) + + collection.put_string( + "front.html", + """ + <%namespace name="lib" file="lib.html"/> + ${lib.bar()} + """, + ) + + assert result_lines( + collection.get_template("front.html").render() + ) == ["lib.bar", "base.foo", "lib.foo", "base.bat", "base.bat"] + + def test_attr(self): + l = lookup.TemplateLookup() + + l.put_string( + "foo.html", + """ + <%! + foofoo = "foo foo" + onlyfoo = "only foo" + %> + <%inherit file="base.html"/> + <%def name="setup()"> + <% + self.attr.foolala = "foo lala" + %> + </%def> + ${self.attr.basefoo} + ${self.attr.foofoo} + ${self.attr.onlyfoo} + ${self.attr.lala} + ${self.attr.foolala} + """, + ) + + l.put_string( + "base.html", + """ + <%! + basefoo = "base foo 1" + foofoo = "base foo 2" + %> + <% + self.attr.lala = "base lala" + %> + + ${self.attr.basefoo} + ${self.attr.foofoo} + ${self.attr.onlyfoo} + ${self.attr.lala} + ${self.setup()} + ${self.attr.foolala} + body + ${self.body()} + """, + ) + + assert result_lines(l.get_template("foo.html").render()) == [ + "base foo 1", + "foo foo", + "only foo", + "base lala", + "foo lala", + "body", + "base foo 1", + "foo foo", + "only foo", + "base lala", + "foo lala", + ] + + def test_attr_raise(self): + l = lookup.TemplateLookup() + + l.put_string( + "foo.html", + """ + <%def name="foo()"> + </%def> + """, + ) + + l.put_string( + "bar.html", + """ + <%namespace name="foo" file="foo.html"/> + + ${foo.notfoo()} + """, + ) + + assert_raises(AttributeError, l.get_template("bar.html").render) + + def test_custom_tag_1(self): + template = Template( + """ + + <%def name="foo(x, y)"> + foo: ${x} ${y} + </%def> + + <%self:foo x="5" y="${7+8}"/> + """ + ) + assert result_lines(template.render()) == ["foo: 5 15"] + + def test_custom_tag_2(self): + collection = lookup.TemplateLookup() + collection.put_string( + "base.html", + """ + <%def name="foo(x, y)"> + foo: ${x} ${y} + </%def> + + <%def name="bat(g)"><% + return "the bat! %s" % g + %></%def> + + <%def name="bar(x)"> + ${caller.body(z=x)} + </%def> + """, + ) + + collection.put_string( + "index.html", + """ + <%namespace name="myns" file="base.html"/> + + <%myns:foo x="${'some x'}" y="some y"/> + + <%myns:bar x="${myns.bat(10)}" args="z"> + record: ${z} + </%myns:bar> + + """, + ) + + assert result_lines( + collection.get_template("index.html").render() + ) == ["foo: some x some y", "record: the bat! 10"] + + def test_custom_tag_3(self): + collection = lookup.TemplateLookup() + collection.put_string( + "base.html", + """ + <%namespace name="foo" file="ns.html" inheritable="True"/> + + ${next.body()} + """, + ) + collection.put_string( + "ns.html", + """ + <%def name="bar()"> + this is ns.html->bar + caller body: ${caller.body()} + </%def> + """, + ) + + collection.put_string( + "index.html", + """ + <%inherit file="base.html"/> + + this is index + <%self.foo:bar> + call body + </%self.foo:bar> + """, + ) + + assert result_lines( + collection.get_template("index.html").render() + ) == [ + "this is index", + "this is ns.html->bar", + "caller body:", + "call body", + ] + + def test_custom_tag_case_sensitive(self): + t = Template( + """ + <%def name="renderPanel()"> + panel ${caller.body()} + </%def> + + <%def name="renderTablePanel()"> + <%self:renderPanel> + hi + </%self:renderPanel> + </%def> + + <%self:renderTablePanel/> + """ + ) + assert result_lines(t.render()) == ["panel", "hi"] + + def test_expr_grouping(self): + """test that parenthesis are placed around string-embedded + expressions.""" + + template = Template( + """ + <%def name="bar(x, y)"> + ${x} + ${y} + </%def> + + <%self:bar x=" ${foo} " y="x${g and '1' or '2'}y"/> + """, + input_encoding="utf-8", + ) + + # the concat has to come out as "x + (g and '1' or '2') + y" + assert result_lines(template.render(foo="this is foo", g=False)) == [ + "this is foo", + "x2y", + ] + + def test_ccall(self): + collection = lookup.TemplateLookup() + collection.put_string( + "base.html", + """ + <%namespace name="foo" file="ns.html" inheritable="True"/> + + ${next.body()} + """, + ) + collection.put_string( + "ns.html", + """ + <%def name="bar()"> + this is ns.html->bar + caller body: ${caller.body()} + </%def> + """, + ) + + collection.put_string( + "index.html", + """ + <%inherit file="base.html"/> + + this is index + <%call expr="self.foo.bar()"> + call body + </%call> + """, + ) + + assert result_lines( + collection.get_template("index.html").render() + ) == [ + "this is index", + "this is ns.html->bar", + "caller body:", + "call body", + ] + + def test_ccall_2(self): + collection = lookup.TemplateLookup() + collection.put_string( + "base.html", + """ + <%namespace name="foo" file="ns1.html" inheritable="True"/> + + ${next.body()} + """, + ) + collection.put_string( + "ns1.html", + """ + <%namespace name="foo2" file="ns2.html"/> + <%def name="bar()"> + <%call expr="foo2.ns2_bar()"> + this is ns1.html->bar + caller body: ${caller.body()} + </%call> + </%def> + """, + ) + + collection.put_string( + "ns2.html", + """ + <%def name="ns2_bar()"> + this is ns2.html->bar + caller body: ${caller.body()} + </%def> + """, + ) + + collection.put_string( + "index.html", + """ + <%inherit file="base.html"/> + + this is index + <%call expr="self.foo.bar()"> + call body + </%call> + """, + ) + + assert result_lines( + collection.get_template("index.html").render() + ) == [ + "this is index", + "this is ns2.html->bar", + "caller body:", + "this is ns1.html->bar", + "caller body:", + "call body", + ] + + def test_import(self): + collection = lookup.TemplateLookup() + collection.put_string( + "functions.html", + """ + <%def name="foo()"> + this is foo + </%def> + + <%def name="bar()"> + this is bar + </%def> + + <%def name="lala()"> + this is lala + </%def> + """, + ) + + collection.put_string( + "func2.html", + """ + <%def name="a()"> + this is a + </%def> + <%def name="b()"> + this is b + </%def> + """, + ) + collection.put_string( + "index.html", + """ + <%namespace file="functions.html" import="*"/> + <%namespace file="func2.html" import="a, b"/> + ${foo()} + ${bar()} + ${lala()} + ${a()} + ${b()} + ${x} + """, + ) + + assert result_lines( + collection.get_template("index.html").render( + bar="this is bar", x="this is x" + ) + ) == [ + "this is foo", + "this is bar", + "this is lala", + "this is a", + "this is b", + "this is x", + ] + + def test_import_calledfromdef(self): + l = lookup.TemplateLookup() + l.put_string( + "a", + """ + <%def name="table()"> + im table + </%def> + """, + ) + + l.put_string( + "b", + """ + <%namespace file="a" import="table"/> + + <% + def table2(): + table() + return "" + %> + + ${table2()} + """, + ) + + t = l.get_template("b") + assert flatten_result(t.render()) == "im table" + + def test_closure_import(self): + collection = lookup.TemplateLookup() + collection.put_string( + "functions.html", + """ + <%def name="foo()"> + this is foo + </%def> + + <%def name="bar()"> + this is bar + </%def> + """, + ) + + collection.put_string( + "index.html", + """ + <%namespace file="functions.html" import="*"/> + <%def name="cl1()"> + ${foo()} + </%def> + + <%def name="cl2()"> + ${bar()} + </%def> + + ${cl1()} + ${cl2()} + """, + ) + assert result_lines( + collection.get_template("index.html").render( + bar="this is bar", x="this is x" + ) + ) == ["this is foo", "this is bar"] + + def test_import_local(self): + t = Template( + """ + <%namespace import="*"> + <%def name="foo()"> + this is foo + </%def> + </%namespace> + + ${foo()} + + """ + ) + assert flatten_result(t.render()) == "this is foo" + + def test_ccall_import(self): + collection = lookup.TemplateLookup() + collection.put_string( + "functions.html", + """ + <%def name="foo()"> + this is foo + </%def> + + <%def name="bar()"> + this is bar. + ${caller.body()} + ${caller.lala()} + </%def> + """, + ) + + collection.put_string( + "index.html", + """ + <%namespace name="func" file="functions.html" import="*"/> + <%call expr="bar()"> + this is index embedded + foo is ${foo()} + <%def name="lala()"> + this is lala ${foo()} + </%def> + </%call> + """, + ) + # print collection.get_template("index.html").code + # print collection.get_template("functions.html").code + assert result_lines( + collection.get_template("index.html").render() + ) == [ + "this is bar.", + "this is index embedded", + "foo is", + "this is foo", + "this is lala", + "this is foo", + ] + + def test_nonexistent_namespace_uri(self): + collection = lookup.TemplateLookup() + collection.put_string( + "main.html", + """ + <%namespace name="defs" file="eefs.html"/> + + this is main. ${defs.def1("hi")} + ${defs.def2("there")} +""", + ) + + collection.put_string( + "defs.html", + """ + <%def name="def1(s)"> + def1: ${s} + </%def> + + <%def name="def2(x)"> + def2: ${x} + </%def> +""", + ) + + assert_raises_message_with_given_cause( + exceptions.TemplateLookupException, + "Can't locate template for uri 'eefs.html", + exceptions.TopLevelLookupException, + collection.get_template("main.html").render, + ) |