Skip to content
Snippets Groups Projects
component.py 8.43 KiB
Newer Older
from mako.template import Template
import unittest
Mike Bayer's avatar
Mike Bayer committed
from util import flatten_result

class ComponentTest(unittest.TestCase):
    def test_component_noargs(self):
        template = Template("""
        
        ${mycomp()}
        
        <%component name="mycomp">
            hello mycomp ${variable}
        </%component>
        
        """)
        print template.code
        assert template.render(variable='hi').strip() == """hello mycomp hi"""

    def test_component_blankargs(self):
        template = Template("""
        <%component name="mycomp()">
            hello mycomp ${variable}
        </%component>

        ${mycomp()}""")
        assert template.render(variable='hi').strip() == """hello mycomp hi"""

    def test_component_args(self):
        template = Template("""
        <%component name="mycomp(a, b)">
            hello mycomp ${variable}, ${a}, ${b}
        </%component>

        ${mycomp(5, 6)}""")
        assert template.render(variable='hi', a=5, b=6).strip() == """hello mycomp hi, 5, 6"""

    def test_outer_scope(self):
        t = Template("""

        <%component name="a">
            a: x is ${x}
        </%component>

        <%component name="b">
            <%
                x = 10
            %>
            b. x is ${x}.  ${a()}
        </%component>

        ${b()}
""")
Mike Bayer's avatar
Mike Bayer committed
        assert flatten_result(t.render(x=5)) == "b. x is 10. a: x is 10"
        
    def test_inter_component(self):
        """test components calling each other"""
        template = Template("""
Mike Bayer's avatar
Mike Bayer committed
        ${b()}
Mike Bayer's avatar
Mike Bayer committed
        <%component name="a">\
        im a
        </%component>
Mike Bayer's avatar
Mike Bayer committed
        <%component name="b">
        im b
        and heres a:  ${a()}
        </%component>
Mike Bayer's avatar
Mike Bayer committed
        <%component name="c">
        im c
        </%component>
""")
        # 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
        
        # then test output
Mike Bayer's avatar
Mike Bayer committed
        assert flatten_result(template.render()) == "im b and heres a: im a"
    def test_local_names(self):
Mike Bayer's avatar
Mike Bayer committed
        t = Template("""
        <%component name="a">
            this is a, and y is ${y}
        </%component>

        ${a()}

        <%
            y = 7
        %>

        ${a()}

Mike Bayer's avatar
Mike Bayer committed
""")
        assert flatten_result(t.render()) == "this is a, and y is None this is a, and y is 7"

    def test_local_names_2(self):
Mike Bayer's avatar
Mike Bayer committed
        t = Template("""
Mike Bayer's avatar
Mike Bayer committed
""")
        assert flatten_result(t.render()) == "y is None y is 7"
    def test_local_names_3(self):
        """test in place assignment/undeclared variable combinations
        
        i.e. things like 'x=x+1', x is declared and undeclared at the same time"""
        template = Template("""
        hi
    	<%component name="a">
    	    y is ${y}

            <%
                x = x + y
                a = 3
            %>
            
            x is ${x}
    	</%component>

    	${a()}
    """)
Mike Bayer's avatar
Mike Bayer committed
        assert flatten_result(template.render(x=5, y=10)) == "hi y is 10 x is 15"
class NestedComponentTest(unittest.TestCase):
    def test_nested_component(self):
Mike Bayer's avatar
Mike Bayer committed
        t = Template("""

        ${hi()}
        
        <%component name="hi">
            hey, im hi.
            and heres ${foo()}, ${bar()}
            
            <%component name="foo">
                this is foo
            </%component>
            
            <%component name="bar">
                this is bar
            </%component>
        </%component>
Mike Bayer's avatar
Mike Bayer committed
""")
        assert flatten_result(t.render()) == "hey, im hi. and heres this is foo , this is bar"
Mike Bayer's avatar
Mike Bayer committed
    def test_nested_with_args(self):
Mike Bayer's avatar
Mike Bayer committed
        t = Template("""
Mike Bayer's avatar
Mike Bayer committed
        ${a()}
        <%component name="a">
            <%component name="b(x, y=2)">
                b x is ${x} y is ${y}
            </%component>
            a ${b(5)}
        </%component>
""")
Mike Bayer's avatar
Mike Bayer committed
        assert flatten_result(t.render()) == "a b x is 5 y is 2"
Mike Bayer's avatar
Mike Bayer committed
        
    def test_nested_component_2(self):
        template = Template("""
        ${a()}
        <%component name="a">
            <%component name="b">
                <%component name="c">
                    comp c
                </%component>
                ${c()}
            </%component>
            ${b()}
        </%component>
""")
Mike Bayer's avatar
Mike Bayer committed
        assert flatten_result(template.render()) == "comp c"

    def test_nested_nested_component(self):
Mike Bayer's avatar
Mike Bayer committed
        t = Template("""
        
        ${a()}
        <%component name="a">
            <%component name="b1">
            </%component>
            <%component name="b2">
                a_b2 ${c1()}
                <%component name="c1">
                    a_b2_c1
                </%component>
            </%component>
            <%component name="b3">
                a_b3 ${c1()}
                <%component name="c1">
                    a_b3_c1 heres x: ${x}
                    <%
                        y = 7
                    %>
                    y is ${y}
                </%component>
                <%component name="c2">
                    a_b3_c2
                    y is ${y}
                    c1 is ${c1()}
                </%component>
                ${c2()}
            </%component>
            
            ${b1()} ${b2()}  ${b3()}
        </%component>
Mike Bayer's avatar
Mike Bayer committed
""")

        assert flatten_result(t.render(x=5)) == "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 test_nested_nested_component_2(self):
Mike Bayer's avatar
Mike Bayer committed
        t = Template("""
        <%component name="a">
            this is a ${b()}
            <%component name="b">
                this is b
                ${c()}
            </%component>
            
            <%component name="c">
                this is c
            </%component>
        </%component>
        ${a()}
Mike Bayer's avatar
Mike Bayer committed
""" )
        assert flatten_result(t.render()) == "this is a this is b this is c"
        
    def test_local_local_names(self):
        """test assignment of variables inside nested components, which requires extra scoping logic"""
Mike Bayer's avatar
Mike Bayer committed
        t = Template("""
            heres y: ${y}
            
            <%component name="a">
                <%component name="b">
                    b, heres y: ${y}
                    
                    <%
                        y = 19
                    %>
                    
                    b, heres c: ${c()}
                    
                    b, heres y again: ${y}
                </%component>
                
                a, heres y: ${y}
                <% 
                    y = 10
                    x = 12
                %>
                
                a, now heres y: ${y}
                a, heres b: ${b()}
                
                <%component name="c">
                    this is c
                </%component>
            </%component>
            
        <%
            y = 7
        %>
Mike Bayer's avatar
Mike Bayer committed
""")
        assert flatten_result(t.render(y=5)) == "heres y: 5 now heres y 7 a, heres y: 7 a, now heres y: 10 a, heres b: b, heres y: 10 b, heres c: this is c b, heres y again: 19 heres y again: 7"

    def test_outer_scope(self):
        t = Template("""
        <%component name="a">
            a: x is ${x}
        </%component>

        <%component name="b">
            <%component name="c">
            <%
                x = 10
            %>
            c. x is ${x}.  ${a()}
            
            b. ${c()}
        </%component>

        ${b()}
Mike Bayer's avatar
Mike Bayer committed
        
        x is ${x}
Mike Bayer's avatar
Mike Bayer committed
        assert flatten_result(t.render(x=5)) == "b. c. x is 10. a: x is 10 x is 5"
class ExceptionTest(unittest.TestCase):
    def test_raise(self):
        template = Template("""
            <%
                raise Exception("this is a test")
            %>
    """, format_exceptions=False)
        try:
            template.render()
            assert False
        except Exception, e:
            assert str(e) == "this is a test"
    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)
        assert template.render().strip() == """error message is this is a test"""
        

if __name__ == '__main__':
    unittest.main()