Added tests for the test functions (the jinja ones ^^)
[jinja2.git] / jinja2 / testsuite / filters.py
1 # -*- coding: utf-8 -*-
2 """
3     jinja2.testsuite.filters
4     ~~~~~~~~~~~~~~~~~~~~~~~~
5
6     Tests for the jinja filters.
7
8     :copyright: (c) 2010 by the Jinja Team.
9     :license: BSD, see LICENSE for more details.
10 """
11 import unittest
12 from jinja2.testsuite import JinjaTestCase
13
14 from jinja2 import Markup, Environment
15
16 env = Environment()
17
18
19 class FilterTestCase(JinjaTestCase):
20
21     def test_capitalize(self):
22         tmpl = env.from_string('{{ "foo bar"|capitalize }}')
23         assert tmpl.render() == 'Foo bar'
24
25     def test_center(self):
26         tmpl = env.from_string('{{ "foo"|center(9) }}')
27         assert tmpl.render() == '   foo   '
28
29     def test_default(self):
30         tmpl = env.from_string(
31             "{{ missing|default('no') }}|{{ false|default('no') }}|"
32             "{{ false|default('no', true) }}|{{ given|default('no') }}"
33         )
34         assert tmpl.render(given='yes') == 'no|False|no|yes'
35
36     def test_dictsort(self):
37         tmpl = env.from_string(
38             '{{ foo|dictsort }}|'
39             '{{ foo|dictsort(true) }}|'
40             '{{ foo|dictsort(false, "value") }}'
41         )
42         out = tmpl.render(foo={"aa": 0, "b": 1, "c": 2, "AB": 3})
43         assert out == ("[('aa', 0), ('AB', 3), ('b', 1), ('c', 2)]|"
44                        "[('AB', 3), ('aa', 0), ('b', 1), ('c', 2)]|"
45                        "[('aa', 0), ('b', 1), ('c', 2), ('AB', 3)]")
46
47     def test_batch(self):
48         tmpl = env.from_string("{{ foo|batch(3)|list }}|"
49                                "{{ foo|batch(3, 'X')|list }}")
50         out = tmpl.render(foo=range(10))
51         assert out == ("[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]|"
52                        "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 'X', 'X']]")
53
54     def test_slice(self):
55         tmpl = env.from_string('{{ foo|slice(3)|list }}|'
56                                '{{ foo|slice(3, "X")|list }}')
57         out = tmpl.render(foo=range(10))
58         assert out == ("[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
59                        "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]")
60
61     def test_escape(self):
62         tmpl = env.from_string('''{{ '<">&'|escape }}''')
63         out = tmpl.render()
64         assert out == '&lt;&#34;&gt;&amp;'
65
66     def test_striptags(self):
67         tmpl = env.from_string('''{{ foo|striptags }}''')
68         out = tmpl.render(foo='  <p>just a small   \n <a href="#">'
69                           'example</a> link</p>\n<p>to a webpage</p> '
70                           '<!-- <p>and some commented stuff</p> -->')
71         assert out == 'just a small example link to a webpage'
72
73     def test_filesizeformat(self):
74         tmpl = env.from_string(
75             '{{ 100|filesizeformat }}|'
76             '{{ 1000|filesizeformat }}|'
77             '{{ 1000000|filesizeformat }}|'
78             '{{ 1000000000|filesizeformat }}|'
79             '{{ 1000000000000|filesizeformat }}|'
80             '{{ 100|filesizeformat(true) }}|'
81             '{{ 1000|filesizeformat(true) }}|'
82             '{{ 1000000|filesizeformat(true) }}|'
83             '{{ 1000000000|filesizeformat(true) }}|'
84             '{{ 1000000000000|filesizeformat(true) }}'
85         )
86         out = tmpl.render()
87         assert out == (
88             '100 Bytes|1.0 KB|1.0 MB|1.0 GB|1000.0 GB|'
89             '100 Bytes|1000 Bytes|976.6 KiB|953.7 MiB|931.3 GiB'
90         )
91
92     def test_first(self):
93         tmpl = env.from_string('{{ foo|first }}')
94         out = tmpl.render(foo=range(10))
95         assert out == '0'
96
97     def test_float(self):
98         tmpl = env.from_string('{{ "42"|float }}|'
99                                '{{ "ajsghasjgd"|float }}|'
100                                '{{ "32.32"|float }}')
101         out = tmpl.render()
102         assert out == '42.0|0.0|32.32'
103
104     def test_format(self):
105         tmpl = env.from_string('''{{ "%s|%s"|format("a", "b") }}''')
106         out = tmpl.render()
107         assert out == 'a|b'
108
109     def test_indent(self):
110         tmpl = env.from_string('{{ foo|indent(2) }}|{{ foo|indent(2, true) }}')
111         text = '\n'.join([' '.join(['foo', 'bar'] * 2)] * 2)
112         out = tmpl.render(foo=text)
113         assert out == ('foo bar foo bar\n  foo bar foo bar|  '
114                        'foo bar foo bar\n  foo bar foo bar')
115
116     def test_int(self):
117         tmpl = env.from_string('{{ "42"|int }}|{{ "ajsghasjgd"|int }}|'
118                                '{{ "32.32"|int }}')
119         out = tmpl.render()
120         assert out == '42|0|32'
121
122     def test_join(self):
123         tmpl = env.from_string('{{ [1, 2, 3]|join("|") }}')
124         out = tmpl.render()
125         assert out == '1|2|3'
126
127         env2 = Environment(autoescape=True)
128         tmpl = env2.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}')
129         assert tmpl.render() == '&lt;foo&gt;<span>foo</span>'
130
131     def test_last(self):
132         tmpl = env.from_string('''{{ foo|last }}''')
133         out = tmpl.render(foo=range(10))
134         assert out == '9'
135
136     def test_length(self):
137         tmpl = env.from_string('''{{ "hello world"|length }}''')
138         out = tmpl.render()
139         assert out == '11'
140
141     def test_lower(self):
142         tmpl = env.from_string('''{{ "FOO"|lower }}''')
143         out = tmpl.render()
144         assert out == 'foo'
145
146     def test_pprint(self):
147         from pprint import pformat
148         tmpl = env.from_string('''{{ data|pprint }}''')
149         data = range(1000)
150         assert tmpl.render(data=data) == pformat(data)
151
152     def test_random(self):
153         tmpl = env.from_string('''{{ seq|random }}''')
154         seq = range(100)
155         for _ in range(10):
156             assert int(tmpl.render(seq=seq)) in seq
157
158     def test_reverse(self):
159         tmpl = env.from_string('{{ "foobar"|reverse|join }}|'
160                                '{{ [1, 2, 3]|reverse|list }}')
161         assert tmpl.render() == 'raboof|[3, 2, 1]'
162
163     def test_string(self):
164         tmpl = env.from_string('''{{ range(10)|string }}''')
165         assert tmpl.render(foo=range(10)) == unicode(xrange(10))
166
167     def test_title(self):
168         tmpl = env.from_string('''{{ "foo bar"|title }}''')
169         assert tmpl.render() == "Foo Bar"
170
171     def test_truncate(self):
172         tmpl = env.from_string(
173             '{{ data|truncate(15, true, ">>>") }}|'
174             '{{ data|truncate(15, false, ">>>") }}|'
175             '{{ smalldata|truncate(15) }}'
176         )
177         out = tmpl.render(data='foobar baz bar' * 1000,
178                           smalldata='foobar baz bar')
179         assert out == 'foobar baz barf>>>|foobar baz >>>|foobar baz bar'
180
181     def test_upper(self):
182         tmpl = env.from_string('{{ "foo"|upper }}')
183         assert tmpl.render() == 'FOO'
184
185     def test_urlize(self):
186         tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
187         assert tmpl.render() == 'foo <a href="http://www.example.com/">'\
188                                 'http://www.example.com/</a> bar'
189
190     def test_wordcount(self):
191         tmpl = env.from_string('{{ "foo bar baz"|wordcount }}')
192         assert tmpl.render() == '3'
193
194     def test_block(self):
195         tmpl = env.from_string('{% filter lower|escape %}<HEHE>{% endfilter %}')
196         assert tmpl.render() == '&lt;hehe&gt;'
197
198     def test_chaining(self):
199         tmpl = env.from_string('''{{ ['<foo>', '<bar>']|first|upper|escape }}''')
200         assert tmpl.render() == '&lt;FOO&gt;'
201
202     def test_sum(self):
203         tmpl = env.from_string('''{{ [1, 2, 3, 4, 5, 6]|sum }}''')
204         assert tmpl.render() == '21'
205
206     def test_abs(self):
207         tmpl = env.from_string('''{{ -1|abs }}|{{ 1|abs }}''')
208         return tmpl.render() == '1|1'
209
210     def test_round(self):
211         tmpl = env.from_string('{{ 2.7|round }}|{{ 2.1|round }}|'
212                                "{{ 2.1234|round(2, 'floor') }}|"
213                                "{{ 2.1|round(0, 'ceil') }}")
214         return tmpl.render() == '3.0|2.0|2.1|3.0'
215
216     def test_xmlattr(self):
217         tmpl = env.from_string("{{ {'foo': 42, 'bar': 23, 'fish': none, "
218                                "'spam': missing, 'blub:blub': '<?>'}|xmlattr }}")
219         out = tmpl.render().split()
220         assert len(out) == 3
221         assert 'foo="42"' in out
222         assert 'bar="23"' in out
223         assert 'blub:blub="&lt;?&gt;"' in out
224
225     def test_sort1(self):
226         tmpl = env.from_string('{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}')
227         assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]'
228
229     def test_groupby(self):
230         tmpl = env.from_string('''
231         {%- for grouper, list in [{'foo': 1, 'bar': 2},
232                                   {'foo': 2, 'bar': 3},
233                                   {'foo': 1, 'bar': 1},
234                                   {'foo': 3, 'bar': 4}]|groupby('foo') -%}
235             {{ grouper }}{% for x in list %}: {{ x.foo }}, {{ x.bar }}{% endfor %}|
236         {%- endfor %}''')
237         assert tmpl.render().split('|') == [
238             "1: 1, 2: 1, 1",
239             "2: 2, 3",
240             "3: 3, 4",
241             ""
242         ]
243
244     def test_filtertag(self):
245         tmpl = env.from_string("{% filter upper|replace('FOO', 'foo') %}"
246                                "foobar{% endfilter %}")
247         assert tmpl.render() == 'fooBAR'
248
249     def test_replace(self):
250         env = Environment()
251         tmpl = env.from_string('{{ string|replace("o", 42) }}')
252         assert tmpl.render(string='<foo>') == '<f4242>'
253         env = Environment(autoescape=True)
254         tmpl = env.from_string('{{ string|replace("o", 42) }}')
255         assert tmpl.render(string='<foo>') == '&lt;f4242&gt;'
256         tmpl = env.from_string('{{ string|replace("<", 42) }}')
257         assert tmpl.render(string='<foo>') == '42foo&gt;'
258         tmpl = env.from_string('{{ string|replace("o", ">x<") }}')
259         assert tmpl.render(string=Markup('foo')) == 'f&gt;x&lt;&gt;x&lt;'
260
261     def test_forceescape(self):
262         tmpl = env.from_string('{{ x|forceescape }}')
263         assert tmpl.render(x=Markup('<div />')) == u'&lt;div /&gt;'
264
265     def test_safe(self):
266         env = Environment(autoescape=True)
267         tmpl = env.from_string('{{ "<div>foo</div>"|safe }}')
268         assert tmpl.render() == '<div>foo</div>'
269         tmpl = env.from_string('{{ "<div>foo</div>" }}')
270         assert tmpl.render() == '&lt;div&gt;foo&lt;/div&gt;'
271
272     def test_sort2(self):
273         tmpl = env.from_string('''{{ ['foo', 'Bar', 'blah']|sort }}''')
274         assert tmpl.render() == "['Bar', 'blah', 'foo']"
275
276
277 def suite():
278     suite = unittest.TestSuite()
279     suite.addTest(unittest.makeSuite(FilterTestCase))
280     return suite