summaryrefslogtreecommitdiff
path: root/test/test_templite.py
blob: 20f5fe7712ca324322c31a2006bec90a42897659 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"""Tests for coverage.template."""

from coverage.templite import Templite
import unittest

class AnyOldObject:
    pass

class TemplateTest(unittest.TestCase):
    
    def try_render(self, text, ctx, result):
        self.assertEqual(Templite(text).render(ctx), result)

    def test_passthrough(self):
        # Strings without variables are passed through unchanged.
        self.assertEqual(Templite("Hello").render(), "Hello")
        self.assertEqual(
            Templite("Hello, 20% fun time!").render(),
            "Hello, 20% fun time!"
            )

    def test_variables(self):
        # Variables use {{var}} syntax.
        self.assertEqual(
            Templite("Hello, {{name}}!").render({'name':'Ned'}),
            "Hello, Ned!"
            )

    def test_pipes(self):
        # Variables can be filtered with pipes.
        data = {
            'name': 'Ned',
            'upper': lambda x: x.upper(),
            'second': lambda x: x[1],
            }
        self.assertEqual(
            Templite("Hello, {{name|upper}}!").render(data),
            "Hello, NED!"
            )
        # Pipes can be concatenated.
        self.assertEqual(
            Templite("Hello, {{name|upper|second}}!").render(data),
            "Hello, E!"
            )

    def test_reusability(self):
        # A single Templite can be used more than once with different data.
        globs = {
            'upper': lambda x: x.upper(),
            'punct': '!',
            }
        
        template = Templite("This is {{name|upper}}{{punct}}", globs)
        self.assertEqual(template.render({'name':'Ned'}), "This is NED!")
        self.assertEqual(template.render({'name':'Ben'}), "This is BEN!")

    def test_attribute(self):
        # Variables' attributes can be accessed with dots.
        obj = AnyOldObject()
        obj.a = "Ay"
        self.assertEqual(
            Templite("{{obj.a}}").render(locals()), "Ay"
            )

        obj2 = AnyOldObject()
        obj2.obj = obj
        obj2.b = "Bee"
        self.assertEqual(
            Templite("{{obj2.obj.a}} {{obj2.b}}").render(locals()), "Ay Bee"
            )
        
    def test_member_function(self):
        # Variables' member functions can be used, as long as they are nullary.
        class WithMemberFns:
            def ditto(self):
                return self.txt + self.txt
        obj = WithMemberFns()
        obj.txt = "Once"
        self.assertEqual(
            Templite("{{obj.ditto}}").render(locals()), "OnceOnce"
            )

    def test_loops(self):
        # Loops work like in Django.
        nums = [1,2,3,4]
        self.assertEqual(
            Templite("Look: {% for n in nums %}{{n}}, {% endfor %}done.").
                render(locals()), "Look: 1, 2, 3, 4, done."
            )
        # Loop iterables can be filtered.
        def rev(l):
            l = l[:]
            l.reverse()
            return l
        
        self.assertEqual(
            Templite("Look: {% for n in nums|rev %}{{n}}, {% endfor %}done.").
                render(locals()), "Look: 4, 3, 2, 1, done."
            )

    def test_empty_loops(self):
        self.assertEqual(
            Templite("Empty: {% for n in nums %}{{n}}, {% endfor %}done.").
                render({'nums':[]}), "Empty: done."
            )

    def test_multiline_loops(self):
        self.assertEqual(
            Templite("Look: \n{% for n in nums %}\n{{n}}, \n{% endfor %}done.").
                render({'nums':[1,2,3]}), "Look: \n\n1, \n\n2, \n\n3, \ndone."
            )
        
    def test_multiple_loops(self):
        self.try_render(
            "{% for n in nums %}{{n}}{% endfor %} and {% for n in nums %}{{n}}{% endfor %}",
            {'nums': [1,2,3]},
            "123 and 123"
            )


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