mirror of
https://github.com/janeczku/calibre-web
synced 2024-08-20 06:36:11 +00:00
510 lines
18 KiB
Python
510 lines
18 KiB
Python
![]() |
# -*- 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
|
||
|
from jinja2._compat import text_type, implements_to_string
|
||
|
|
||
|
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=list(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=list(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=' <p>just a small \n <a href="#">'
|
||
|
'example</a> link</p>\n<p>to a webpage</p> '
|
||
|
'<!-- <p>and some commented stuff</p> -->')
|
||
|
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()
|
||
|
self.assert_equal(out, (
|
||
|
'100 Bytes|1.0 kB|1.0 MB|1.0 GB|1.0 TB|100 Bytes|'
|
||
|
'1000 Bytes|976.6 KiB|953.7 MiB|931.3 GiB'
|
||
|
))
|
||
|
|
||
|
def test_filesizeformat_issue59(self):
|
||
|
tmpl = env.from_string(
|
||
|
'{{ 300|filesizeformat }}|'
|
||
|
'{{ 3000|filesizeformat }}|'
|
||
|
'{{ 3000000|filesizeformat }}|'
|
||
|
'{{ 3000000000|filesizeformat }}|'
|
||
|
'{{ 3000000000000|filesizeformat }}|'
|
||
|
'{{ 300|filesizeformat(true) }}|'
|
||
|
'{{ 3000|filesizeformat(true) }}|'
|
||
|
'{{ 3000000|filesizeformat(true) }}'
|
||
|
)
|
||
|
out = tmpl.render()
|
||
|
self.assert_equal(out, (
|
||
|
'300 Bytes|3.0 kB|3.0 MB|3.0 GB|3.0 TB|300 Bytes|'
|
||
|
'2.9 KiB|2.9 MiB'
|
||
|
))
|
||
|
|
||
|
|
||
|
def test_first(self):
|
||
|
tmpl = env.from_string('{{ foo|first }}')
|
||
|
out = tmpl.render(foo=list(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>", "<span>foo</span>"|safe]|join }}')
|
||
|
assert tmpl.render() == '<foo><span>foo</span>'
|
||
|
|
||
|
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=list(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 = list(range(1000))
|
||
|
assert tmpl.render(data=data) == pformat(data)
|
||
|
|
||
|
def test_random(self):
|
||
|
tmpl = env.from_string('''{{ seq|random }}''')
|
||
|
seq = list(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) == text_type(x)
|
||
|
|
||
|
def test_title(self):
|
||
|
tmpl = env.from_string('''{{ "foo bar"|title }}''')
|
||
|
assert tmpl.render() == "Foo Bar"
|
||
|
tmpl = env.from_string('''{{ "foo's bar"|title }}''')
|
||
|
assert tmpl.render() == "Foo's Bar"
|
||
|
tmpl = env.from_string('''{{ "foo bar"|title }}''')
|
||
|
assert tmpl.render() == "Foo Bar"
|
||
|
tmpl = env.from_string('''{{ "f bar f"|title }}''')
|
||
|
assert tmpl.render() == "F Bar F"
|
||
|
tmpl = env.from_string('''{{ "foo-bar"|title }}''')
|
||
|
assert tmpl.render() == "Foo-Bar"
|
||
|
tmpl = env.from_string('''{{ "foo\tbar"|title }}''')
|
||
|
assert tmpl.render() == "Foo\tBar"
|
||
|
|
||
|
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 <a href="http://www.example.com/">'\
|
||
|
'http://www.example.com/</a> 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 %}<HEHE>{% endfilter %}')
|
||
|
assert tmpl.render() == '<hehe>'
|
||
|
|
||
|
def test_chaining(self):
|
||
|
tmpl = env.from_string('''{{ ['<foo>', '<bar>']|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_sum_attributes_tuple(self):
|
||
|
tmpl = env.from_string('''{{ values.items()|sum('1') }}''')
|
||
|
assert tmpl.render(values={
|
||
|
'foo': 23,
|
||
|
'bar': 1,
|
||
|
'baz': 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):
|
||
|
@implements_to_string
|
||
|
class Magic(object):
|
||
|
def __init__(self, value):
|
||
|
self.value = value
|
||
|
def __str__(self):
|
||
|
return text_type(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='<foo>') == '<f4242>'
|
||
|
env = Environment(autoescape=True)
|
||
|
tmpl = env.from_string('{{ string|replace("o", 42) }}')
|
||
|
assert tmpl.render(string='<foo>') == '<f4242>'
|
||
|
tmpl = env.from_string('{{ string|replace("<", 42) }}')
|
||
|
assert tmpl.render(string='<foo>') == '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('<div />')) == u'<div />'
|
||
|
|
||
|
def test_safe(self):
|
||
|
env = Environment(autoescape=True)
|
||
|
tmpl = env.from_string('{{ "<div>foo</div>"|safe }}')
|
||
|
assert tmpl.render() == '<div>foo</div>'
|
||
|
tmpl = env.from_string('{{ "<div>foo</div>" }}')
|
||
|
assert tmpl.render() == '<div>foo</div>'
|
||
|
|
||
|
def test_urlencode(self):
|
||
|
env = Environment(autoescape=True)
|
||
|
tmpl = env.from_string('{{ "Hello, world!"|urlencode }}')
|
||
|
assert tmpl.render() == 'Hello%2C%20world%21'
|
||
|
tmpl = env.from_string('{{ o|urlencode }}')
|
||
|
assert tmpl.render(o=u"Hello, world\u203d") == "Hello%2C%20world%E2%80%BD"
|
||
|
assert tmpl.render(o=(("f", 1),)) == "f=1"
|
||
|
assert tmpl.render(o=(('f', 1), ("z", 2))) == "f=1&z=2"
|
||
|
assert tmpl.render(o=((u"\u203d", 1),)) == "%E2%80%BD=1"
|
||
|
assert tmpl.render(o={u"\u203d": 1}) == "%E2%80%BD=1"
|
||
|
assert tmpl.render(o={0: 1}) == "0=1"
|
||
|
|
||
|
def test_simple_map(self):
|
||
|
env = Environment()
|
||
|
tmpl = env.from_string('{{ ["1", "2", "3"]|map("int")|sum }}')
|
||
|
self.assertEqual(tmpl.render(), '6')
|
||
|
|
||
|
def test_attribute_map(self):
|
||
|
class User(object):
|
||
|
def __init__(self, name):
|
||
|
self.name = name
|
||
|
env = Environment()
|
||
|
users = [
|
||
|
User('john'),
|
||
|
User('jane'),
|
||
|
User('mike'),
|
||
|
]
|
||
|
tmpl = env.from_string('{{ users|map(attribute="name")|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(users=users), 'john|jane|mike')
|
||
|
|
||
|
def test_empty_map(self):
|
||
|
env = Environment()
|
||
|
tmpl = env.from_string('{{ none|map("upper")|list }}')
|
||
|
self.assertEqual(tmpl.render(), '[]')
|
||
|
|
||
|
def test_simple_select(self):
|
||
|
env = Environment()
|
||
|
tmpl = env.from_string('{{ [1, 2, 3, 4, 5]|select("odd")|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(), '1|3|5')
|
||
|
|
||
|
def test_bool_select(self):
|
||
|
env = Environment()
|
||
|
tmpl = env.from_string('{{ [none, false, 0, 1, 2, 3, 4, 5]|select|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(), '1|2|3|4|5')
|
||
|
|
||
|
def test_simple_reject(self):
|
||
|
env = Environment()
|
||
|
tmpl = env.from_string('{{ [1, 2, 3, 4, 5]|reject("odd")|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(), '2|4')
|
||
|
|
||
|
def test_bool_reject(self):
|
||
|
env = Environment()
|
||
|
tmpl = env.from_string('{{ [none, false, 0, 1, 2, 3, 4, 5]|reject|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(), 'None|False|0')
|
||
|
|
||
|
def test_simple_select_attr(self):
|
||
|
class User(object):
|
||
|
def __init__(self, name, is_active):
|
||
|
self.name = name
|
||
|
self.is_active = is_active
|
||
|
env = Environment()
|
||
|
users = [
|
||
|
User('john', True),
|
||
|
User('jane', True),
|
||
|
User('mike', False),
|
||
|
]
|
||
|
tmpl = env.from_string('{{ users|selectattr("is_active")|'
|
||
|
'map(attribute="name")|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(users=users), 'john|jane')
|
||
|
|
||
|
def test_simple_reject_attr(self):
|
||
|
class User(object):
|
||
|
def __init__(self, name, is_active):
|
||
|
self.name = name
|
||
|
self.is_active = is_active
|
||
|
env = Environment()
|
||
|
users = [
|
||
|
User('john', True),
|
||
|
User('jane', True),
|
||
|
User('mike', False),
|
||
|
]
|
||
|
tmpl = env.from_string('{{ users|rejectattr("is_active")|'
|
||
|
'map(attribute="name")|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(users=users), 'mike')
|
||
|
|
||
|
def test_func_select_attr(self):
|
||
|
class User(object):
|
||
|
def __init__(self, id, name):
|
||
|
self.id = id
|
||
|
self.name = name
|
||
|
env = Environment()
|
||
|
users = [
|
||
|
User(1, 'john'),
|
||
|
User(2, 'jane'),
|
||
|
User(3, 'mike'),
|
||
|
]
|
||
|
tmpl = env.from_string('{{ users|selectattr("id", "odd")|'
|
||
|
'map(attribute="name")|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(users=users), 'john|mike')
|
||
|
|
||
|
def test_func_reject_attr(self):
|
||
|
class User(object):
|
||
|
def __init__(self, id, name):
|
||
|
self.id = id
|
||
|
self.name = name
|
||
|
env = Environment()
|
||
|
users = [
|
||
|
User(1, 'john'),
|
||
|
User(2, 'jane'),
|
||
|
User(3, 'mike'),
|
||
|
]
|
||
|
tmpl = env.from_string('{{ users|rejectattr("id", "odd")|'
|
||
|
'map(attribute="name")|join("|") }}')
|
||
|
self.assertEqual(tmpl.render(users=users), 'jane')
|
||
|
|
||
|
|
||
|
def suite():
|
||
|
suite = unittest.TestSuite()
|
||
|
suite.addTest(unittest.makeSuite(FilterTestCase))
|
||
|
return suite
|