# -*- coding: utf-8 -*- """ jinja2.testsuite.filters ~~~~~~~~~~~~~~~~~~~~~~~~ Tests for the jinja filters. :copyright: (c) 2010 by the Jinja Team. :license: BSD, see LICENSE for more details. """ import unittest from jinja2.testsuite import JinjaTestCase from jinja2 import Markup, Environment env = Environment() class FilterTestCase(JinjaTestCase): def test_capitalize(self): tmpl = env.from_string('{{ "foo bar"|capitalize }}') assert tmpl.render() == 'Foo bar' def test_center(self): tmpl = env.from_string('{{ "foo"|center(9) }}') assert tmpl.render() == ' foo ' def test_default(self): tmpl = env.from_string( "{{ missing|default('no') }}|{{ false|default('no') }}|" "{{ false|default('no', true) }}|{{ given|default('no') }}" ) assert tmpl.render(given='yes') == 'no|False|no|yes' def test_dictsort(self): tmpl = env.from_string( '{{ foo|dictsort }}|' '{{ foo|dictsort(true) }}|' '{{ foo|dictsort(false, "value") }}' ) out = tmpl.render(foo={"aa": 0, "b": 1, "c": 2, "AB": 3}) assert out == ("[('aa', 0), ('AB', 3), ('b', 1), ('c', 2)]|" "[('AB', 3), ('aa', 0), ('b', 1), ('c', 2)]|" "[('aa', 0), ('b', 1), ('c', 2), ('AB', 3)]") def test_batch(self): tmpl = env.from_string("{{ foo|batch(3)|list }}|" "{{ foo|batch(3, 'X')|list }}") out = tmpl.render(foo=range(10)) assert out == ("[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]|" "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 'X', 'X']]") def test_slice(self): tmpl = env.from_string('{{ foo|slice(3)|list }}|' '{{ foo|slice(3, "X")|list }}') out = tmpl.render(foo=range(10)) assert out == ("[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|" "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]") def test_escape(self): tmpl = env.from_string('''{{ '<">&'|escape }}''') out = tmpl.render() assert out == '<">&' def test_striptags(self): tmpl = env.from_string('''{{ foo|striptags }}''') out = tmpl.render(foo='

just a small \n ' 'example link

\n

to a webpage

' '') assert out == 'just a small example link to a webpage' def test_filesizeformat(self): tmpl = env.from_string( '{{ 100|filesizeformat }}|' '{{ 1000|filesizeformat }}|' '{{ 1000000|filesizeformat }}|' '{{ 1000000000|filesizeformat }}|' '{{ 1000000000000|filesizeformat }}|' '{{ 100|filesizeformat(true) }}|' '{{ 1000|filesizeformat(true) }}|' '{{ 1000000|filesizeformat(true) }}|' '{{ 1000000000|filesizeformat(true) }}|' '{{ 1000000000000|filesizeformat(true) }}' ) out = tmpl.render() assert out == ( '100 Bytes|0.0 kB|0.0 MB|0.0 GB|0.0 TB|100 Bytes|' '1000 Bytes|1.0 KiB|0.9 MiB|0.9 GiB' ) def test_first(self): tmpl = env.from_string('{{ foo|first }}') out = tmpl.render(foo=range(10)) assert out == '0' def test_float(self): tmpl = env.from_string('{{ "42"|float }}|' '{{ "ajsghasjgd"|float }}|' '{{ "32.32"|float }}') out = tmpl.render() assert out == '42.0|0.0|32.32' def test_format(self): tmpl = env.from_string('''{{ "%s|%s"|format("a", "b") }}''') out = tmpl.render() assert out == 'a|b' def test_indent(self): tmpl = env.from_string('{{ foo|indent(2) }}|{{ foo|indent(2, true) }}') text = '\n'.join([' '.join(['foo', 'bar'] * 2)] * 2) out = tmpl.render(foo=text) assert out == ('foo bar foo bar\n foo bar foo bar| ' 'foo bar foo bar\n foo bar foo bar') def test_int(self): tmpl = env.from_string('{{ "42"|int }}|{{ "ajsghasjgd"|int }}|' '{{ "32.32"|int }}') out = tmpl.render() assert out == '42|0|32' def test_join(self): tmpl = env.from_string('{{ [1, 2, 3]|join("|") }}') out = tmpl.render() assert out == '1|2|3' env2 = Environment(autoescape=True) tmpl = env2.from_string('{{ ["", "foo"|safe]|join }}') assert tmpl.render() == '<foo>foo' def test_join_attribute(self): class User(object): def __init__(self, username): self.username = username tmpl = env.from_string('''{{ users|join(', ', 'username') }}''') assert tmpl.render(users=map(User, ['foo', 'bar'])) == 'foo, bar' def test_last(self): tmpl = env.from_string('''{{ foo|last }}''') out = tmpl.render(foo=range(10)) assert out == '9' def test_length(self): tmpl = env.from_string('''{{ "hello world"|length }}''') out = tmpl.render() assert out == '11' def test_lower(self): tmpl = env.from_string('''{{ "FOO"|lower }}''') out = tmpl.render() assert out == 'foo' def test_pprint(self): from pprint import pformat tmpl = env.from_string('''{{ data|pprint }}''') data = range(1000) assert tmpl.render(data=data) == pformat(data) def test_random(self): tmpl = env.from_string('''{{ seq|random }}''') seq = range(100) for _ in range(10): assert int(tmpl.render(seq=seq)) in seq def test_reverse(self): tmpl = env.from_string('{{ "foobar"|reverse|join }}|' '{{ [1, 2, 3]|reverse|list }}') assert tmpl.render() == 'raboof|[3, 2, 1]' def test_string(self): x = [1, 2, 3, 4, 5] tmpl = env.from_string('''{{ obj|string }}''') assert tmpl.render(obj=x) == unicode(x) def test_title(self): tmpl = env.from_string('''{{ "foo bar"|title }}''') assert tmpl.render() == "Foo Bar" def test_truncate(self): tmpl = env.from_string( '{{ data|truncate(15, true, ">>>") }}|' '{{ data|truncate(15, false, ">>>") }}|' '{{ smalldata|truncate(15) }}' ) out = tmpl.render(data='foobar baz bar' * 1000, smalldata='foobar baz bar') assert out == 'foobar baz barf>>>|foobar baz >>>|foobar baz bar' def test_upper(self): tmpl = env.from_string('{{ "foo"|upper }}') assert tmpl.render() == 'FOO' def test_urlize(self): tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}') assert tmpl.render() == 'foo '\ 'http://www.example.com/ bar' def test_wordcount(self): tmpl = env.from_string('{{ "foo bar baz"|wordcount }}') assert tmpl.render() == '3' def test_block(self): tmpl = env.from_string('{% filter lower|escape %}{% endfilter %}') assert tmpl.render() == '<hehe>' def test_chaining(self): tmpl = env.from_string('''{{ ['', '']|first|upper|escape }}''') assert tmpl.render() == '<FOO>' def test_sum(self): tmpl = env.from_string('''{{ [1, 2, 3, 4, 5, 6]|sum }}''') assert tmpl.render() == '21' def test_sum_attributes(self): tmpl = env.from_string('''{{ values|sum('value') }}''') assert tmpl.render(values=[ {'value': 23}, {'value': 1}, {'value': 18}, ]) == '42' def test_sum_attributes_nested(self): tmpl = env.from_string('''{{ values|sum('real.value') }}''') assert tmpl.render(values=[ {'real': {'value': 23}}, {'real': {'value': 1}}, {'real': {'value': 18}}, ]) == '42' def test_abs(self): tmpl = env.from_string('''{{ -1|abs }}|{{ 1|abs }}''') assert tmpl.render() == '1|1', tmpl.render() def test_round_positive(self): tmpl = env.from_string('{{ 2.7|round }}|{{ 2.1|round }}|' "{{ 2.1234|round(3, 'floor') }}|" "{{ 2.1|round(0, 'ceil') }}") assert tmpl.render() == '3.0|2.0|2.123|3.0', tmpl.render() def test_round_negative(self): tmpl = env.from_string('{{ 21.3|round(-1)}}|' "{{ 21.3|round(-1, 'ceil')}}|" "{{ 21.3|round(-1, 'floor')}}") assert tmpl.render() == '20.0|30.0|20.0',tmpl.render() def test_xmlattr(self): tmpl = env.from_string("{{ {'foo': 42, 'bar': 23, 'fish': none, " "'spam': missing, 'blub:blub': ''}|xmlattr }}") out = tmpl.render().split() assert len(out) == 3 assert 'foo="42"' in out assert 'bar="23"' in out assert 'blub:blub="<?>"' in out def test_sort1(self): tmpl = env.from_string('{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}') assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]' def test_sort2(self): tmpl = env.from_string('{{ "".join(["c", "A", "b", "D"]|sort) }}') assert tmpl.render() == 'AbcD' def test_sort3(self): tmpl = env.from_string('''{{ ['foo', 'Bar', 'blah']|sort }}''') assert tmpl.render() == "['Bar', 'blah', 'foo']" def test_sort4(self): class Magic(object): def __init__(self, value): self.value = value def __unicode__(self): return unicode(self.value) tmpl = env.from_string('''{{ items|sort(attribute='value')|join }}''') assert tmpl.render(items=map(Magic, [3, 2, 4, 1])) == '1234' def test_groupby(self): tmpl = env.from_string(''' {%- for grouper, list in [{'foo': 1, 'bar': 2}, {'foo': 2, 'bar': 3}, {'foo': 1, 'bar': 1}, {'foo': 3, 'bar': 4}]|groupby('foo') -%} {{ grouper }}{% for x in list %}: {{ x.foo }}, {{ x.bar }}{% endfor %}| {%- endfor %}''') assert tmpl.render().split('|') == [ "1: 1, 2: 1, 1", "2: 2, 3", "3: 3, 4", "" ] def test_groupby_tuple_index(self): tmpl = env.from_string(''' {%- for grouper, list in [('a', 1), ('a', 2), ('b', 1)]|groupby(0) -%} {{ grouper }}{% for x in list %}:{{ x.1 }}{% endfor %}| {%- endfor %}''') assert tmpl.render() == 'a:1:2|b:1|' def test_groupby_multidot(self): class Date(object): def __init__(self, day, month, year): self.day = day self.month = month self.year = year class Article(object): def __init__(self, title, *date): self.date = Date(*date) self.title = title articles = [ Article('aha', 1, 1, 1970), Article('interesting', 2, 1, 1970), Article('really?', 3, 1, 1970), Article('totally not', 1, 1, 1971) ] tmpl = env.from_string(''' {%- for year, list in articles|groupby('date.year') -%} {{ year }}{% for x in list %}[{{ x.title }}]{% endfor %}| {%- endfor %}''') assert tmpl.render(articles=articles).split('|') == [ '1970[aha][interesting][really?]', '1971[totally not]', '' ] def test_filtertag(self): tmpl = env.from_string("{% filter upper|replace('FOO', 'foo') %}" "foobar{% endfilter %}") assert tmpl.render() == 'fooBAR' def test_replace(self): env = Environment() tmpl = env.from_string('{{ string|replace("o", 42) }}') assert tmpl.render(string='') == '' env = Environment(autoescape=True) tmpl = env.from_string('{{ string|replace("o", 42) }}') assert tmpl.render(string='') == '<f4242>' tmpl = env.from_string('{{ string|replace("<", 42) }}') assert tmpl.render(string='') == '42foo>' tmpl = env.from_string('{{ string|replace("o", ">x<") }}') assert tmpl.render(string=Markup('foo')) == 'f>x<>x<' def test_forceescape(self): tmpl = env.from_string('{{ x|forceescape }}') assert tmpl.render(x=Markup('
')) == u'<div />' def test_safe(self): env = Environment(autoescape=True) tmpl = env.from_string('{{ "
foo
"|safe }}') assert tmpl.render() == '
foo
' tmpl = env.from_string('{{ "
foo
" }}') assert tmpl.render() == '<div>foo</div>' def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(FilterTestCase)) return suite