1 # -*- coding: utf-8 -*-
3 jinja2.testsuite.filters
4 ~~~~~~~~~~~~~~~~~~~~~~~~
6 Tests for the jinja filters.
8 :copyright: (c) 2010 by the Jinja Team.
9 :license: BSD, see LICENSE for more details.
12 from jinja2
.testsuite
import JinjaTestCase
14 from jinja2
import Markup
, Environment
19 class FilterTestCase(JinjaTestCase
):
21 def test_capitalize(self
):
22 tmpl
= env
.from_string('{{ "foo bar"|capitalize }}')
23 assert tmpl
.render() == 'Foo bar'
25 def test_center(self
):
26 tmpl
= env
.from_string('{{ "foo"|center(9) }}')
27 assert tmpl
.render() == ' foo '
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') }}"
34 assert tmpl
.render(given
='yes') == 'no|False|no|yes'
36 def test_dictsort(self
):
37 tmpl
= env
.from_string(
39 '{{ foo|dictsort(true) }}|'
40 '{{ foo|dictsort(false, "value") }}'
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)]")
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']]")
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']]")
61 def test_escape(self
):
62 tmpl
= env
.from_string('''{{ '<">&'|escape }}''')
64 assert out
== '<">&'
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'
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) }}'
88 '100 Bytes|0.0 kB|0.0 MB|0.0 GB|0.0 TB|100 Bytes|'
89 '1000 Bytes|1.0 KiB|0.9 MiB|0.9 GiB'
93 tmpl
= env
.from_string('{{ foo|first }}')
94 out
= tmpl
.render(foo
=range(10))
98 tmpl
= env
.from_string('{{ "42"|float }}|'
99 '{{ "ajsghasjgd"|float }}|'
100 '{{ "32.32"|float }}')
102 assert out
== '42.0|0.0|32.32'
104 def test_format(self
):
105 tmpl
= env
.from_string('''{{ "%s|%s"|format("a", "b") }}''')
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')
117 tmpl
= env
.from_string('{{ "42"|int }}|{{ "ajsghasjgd"|int }}|'
120 assert out
== '42|0|32'
123 tmpl
= env
.from_string('{{ [1, 2, 3]|join("|") }}')
125 assert out
== '1|2|3'
127 env2
= Environment(autoescape
=True)
128 tmpl
= env2
.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}')
129 assert tmpl
.render() == '<foo><span>foo</span>'
131 def test_join_attribute(self
):
133 def __init__(self
, username
):
134 self
.username
= username
135 tmpl
= env
.from_string('''{{ users|join(', ', 'username') }}''')
136 assert tmpl
.render(users
=map(User
, ['foo', 'bar'])) == 'foo, bar'
139 tmpl
= env
.from_string('''{{ foo|last }}''')
140 out
= tmpl
.render(foo
=range(10))
143 def test_length(self
):
144 tmpl
= env
.from_string('''{{ "hello world"|length }}''')
148 def test_lower(self
):
149 tmpl
= env
.from_string('''{{ "FOO"|lower }}''')
153 def test_pprint(self
):
154 from pprint
import pformat
155 tmpl
= env
.from_string('''{{ data|pprint }}''')
157 assert tmpl
.render(data
=data
) == pformat(data
)
159 def test_random(self
):
160 tmpl
= env
.from_string('''{{ seq|random }}''')
163 assert int(tmpl
.render(seq
=seq
)) in seq
165 def test_reverse(self
):
166 tmpl
= env
.from_string('{{ "foobar"|reverse|join }}|'
167 '{{ [1, 2, 3]|reverse|list }}')
168 assert tmpl
.render() == 'raboof|[3, 2, 1]'
170 def test_string(self
):
172 tmpl
= env
.from_string('''{{ obj|string }}''')
173 assert tmpl
.render(obj
=x
) == unicode(x
)
175 def test_title(self
):
176 tmpl
= env
.from_string('''{{ "foo bar"|title }}''')
177 assert tmpl
.render() == "Foo Bar"
179 def test_truncate(self
):
180 tmpl
= env
.from_string(
181 '{{ data|truncate(15, true, ">>>") }}|'
182 '{{ data|truncate(15, false, ">>>") }}|'
183 '{{ smalldata|truncate(15) }}'
185 out
= tmpl
.render(data
='foobar baz bar' * 1000,
186 smalldata
='foobar baz bar')
187 assert out
== 'foobar baz barf>>>|foobar baz >>>|foobar baz bar'
189 def test_upper(self
):
190 tmpl
= env
.from_string('{{ "foo"|upper }}')
191 assert tmpl
.render() == 'FOO'
193 def test_urlize(self
):
194 tmpl
= env
.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
195 assert tmpl
.render() == 'foo <a href="http://www.example.com/">'\
196 'http://www.example.com/</a> bar'
198 def test_wordcount(self
):
199 tmpl
= env
.from_string('{{ "foo bar baz"|wordcount }}')
200 assert tmpl
.render() == '3'
202 def test_block(self
):
203 tmpl
= env
.from_string('{% filter lower|escape %}<HEHE>{% endfilter %}')
204 assert tmpl
.render() == '<hehe>'
206 def test_chaining(self
):
207 tmpl
= env
.from_string('''{{ ['<foo>', '<bar>']|first|upper|escape }}''')
208 assert tmpl
.render() == '<FOO>'
211 tmpl
= env
.from_string('''{{ [1, 2, 3, 4, 5, 6]|sum }}''')
212 assert tmpl
.render() == '21'
214 def test_sum_attributes(self
):
215 tmpl
= env
.from_string('''{{ values|sum('value') }}''')
216 assert tmpl
.render(values
=[
222 def test_sum_attributes_nested(self
):
223 tmpl
= env
.from_string('''{{ values|sum('real.value') }}''')
224 assert tmpl
.render(values
=[
225 {'real': {'value': 23}},
226 {'real': {'value': 1}},
227 {'real': {'value': 18}},
231 tmpl
= env
.from_string('''{{ -1|abs }}|{{ 1|abs }}''')
232 assert tmpl
.render() == '1|1', tmpl
.render()
234 def test_round_positive(self
):
235 tmpl
= env
.from_string('{{ 2.7|round }}|{{ 2.1|round }}|'
236 "{{ 2.1234|round(3, 'floor') }}|"
237 "{{ 2.1|round(0, 'ceil') }}")
238 assert tmpl
.render() == '3.0|2.0|2.123|3.0', tmpl
.render()
240 def test_round_negative(self
):
241 tmpl
= env
.from_string('{{ 21.3|round(-1)}}|'
242 "{{ 21.3|round(-1, 'ceil')}}|"
243 "{{ 21.3|round(-1, 'floor')}}")
244 assert tmpl
.render() == '20.0|30.0|20.0',tmpl
.render()
246 def test_xmlattr(self
):
247 tmpl
= env
.from_string("{{ {'foo': 42, 'bar': 23, 'fish': none, "
248 "'spam': missing, 'blub:blub': '<?>'}|xmlattr }}")
249 out
= tmpl
.render().split()
251 assert 'foo="42"' in out
252 assert 'bar="23"' in out
253 assert 'blub:blub="<?>"' in out
255 def test_sort1(self
):
256 tmpl
= env
.from_string('{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}')
257 assert tmpl
.render() == '[1, 2, 3]|[3, 2, 1]'
259 def test_sort2(self
):
260 tmpl
= env
.from_string('{{ "".join(["c", "A", "b", "D"]|sort) }}')
261 assert tmpl
.render() == 'AbcD'
263 def test_sort3(self
):
264 tmpl
= env
.from_string('''{{ ['foo', 'Bar', 'blah']|sort }}''')
265 assert tmpl
.render() == "['Bar', 'blah', 'foo']"
267 def test_sort4(self
):
269 def __init__(self
, value
):
271 def __unicode__(self
):
272 return unicode(self
.value
)
273 tmpl
= env
.from_string('''{{ items|sort(attribute='value')|join }}''')
274 assert tmpl
.render(items
=map(Magic
, [3, 2, 4, 1])) == '1234'
276 def test_groupby(self
):
277 tmpl
= env
.from_string('''
278 {%- for grouper, list in [{'foo': 1, 'bar': 2},
279 {'foo': 2, 'bar': 3},
280 {'foo': 1, 'bar': 1},
281 {'foo': 3, 'bar': 4}]|groupby('foo') -%}
282 {{ grouper }}{% for x in list %}: {{ x.foo }}, {{ x.bar }}{% endfor %}|
284 assert tmpl
.render().split('|') == [
291 def test_groupby_tuple_index(self
):
292 tmpl
= env
.from_string('''
293 {%- for grouper, list in [('a', 1), ('a', 2), ('b', 1)]|groupby(0) -%}
294 {{ grouper }}{% for x in list %}:{{ x.1 }}{% endfor %}|
296 assert tmpl
.render() == 'a:1:2|b:1|'
298 def test_groupby_multidot(self
):
300 def __init__(self
, day
, month
, year
):
304 class Article(object):
305 def __init__(self
, title
, *date
):
306 self
.date
= Date(*date
)
309 Article('aha', 1, 1, 1970),
310 Article('interesting', 2, 1, 1970),
311 Article('really?', 3, 1, 1970),
312 Article('totally not', 1, 1, 1971)
314 tmpl
= env
.from_string('''
315 {%- for year, list in articles|groupby('date.year') -%}
316 {{ year }}{% for x in list %}[{{ x.title }}]{% endfor %}|
318 assert tmpl
.render(articles
=articles
).split('|') == [
319 '1970[aha][interesting][really?]',
324 def test_filtertag(self
):
325 tmpl
= env
.from_string("{% filter upper|replace('FOO', 'foo') %}"
326 "foobar{% endfilter %}")
327 assert tmpl
.render() == 'fooBAR'
329 def test_replace(self
):
331 tmpl
= env
.from_string('{{ string|replace("o", 42) }}')
332 assert tmpl
.render(string
='<foo>') == '<f4242>'
333 env
= Environment(autoescape
=True)
334 tmpl
= env
.from_string('{{ string|replace("o", 42) }}')
335 assert tmpl
.render(string
='<foo>') == '<f4242>'
336 tmpl
= env
.from_string('{{ string|replace("<", 42) }}')
337 assert tmpl
.render(string
='<foo>') == '42foo>'
338 tmpl
= env
.from_string('{{ string|replace("o", ">x<") }}')
339 assert tmpl
.render(string
=Markup('foo')) == 'f>x<>x<'
341 def test_forceescape(self
):
342 tmpl
= env
.from_string('{{ x|forceescape }}')
343 assert tmpl
.render(x
=Markup('<div />')) == u
'<div />'
346 env
= Environment(autoescape
=True)
347 tmpl
= env
.from_string('{{ "<div>foo</div>"|safe }}')
348 assert tmpl
.render() == '<div>foo</div>'
349 tmpl
= env
.from_string('{{ "<div>foo</div>" }}')
350 assert tmpl
.render() == '<div>foo</div>'
354 suite
= unittest
.TestSuite()
355 suite
.addTest(unittest
.makeSuite(FilterTestCase
))