378 lines
17 KiB
Python
378 lines
17 KiB
Python
from django.template import Context, Template
|
|
|
|
|
|
def test_get():
|
|
t = Template('{{ foo|get:"foo-bar" }}')
|
|
context = Context({'foo': {'foo-bar': 'hello'}})
|
|
assert t.render(context) == 'hello'
|
|
context = Context({'foo': {'bar-foo': 'hello'}})
|
|
assert t.render(context) == 'None'
|
|
context = Context({'foo': None})
|
|
assert t.render(context) == 'None'
|
|
|
|
t = Template('{{ foo|get:"foo-bar"|default:"" }}')
|
|
context = Context({'foo': {'rab': 'hello'}})
|
|
assert t.render(context) == ''
|
|
|
|
t = Template('{{ foo|get:key }}')
|
|
context = Context({'foo': {'foo-bar': 'hello'}, 'key': 'foo-bar'})
|
|
assert t.render(context) == 'hello'
|
|
|
|
|
|
def test_getlist():
|
|
# nothing in context
|
|
t = Template('{% for v in values|getlist:"foo" %}{{ v }},{% endfor %}')
|
|
context = Context()
|
|
assert t.render(context) == ''
|
|
# non value
|
|
t = Template('{% for v in values|getlist:"foo" %}{{ v }},{% endfor %}')
|
|
context = Context({'values': None})
|
|
assert t.render(context) == ''
|
|
# not a list
|
|
t = Template('{% for v in values|getlist:"foo" %}{{ v }},{% endfor %}')
|
|
context = Context({'values': 'foo'})
|
|
assert t.render(context) == 'None,None,None,'
|
|
# not a list of dict
|
|
t = Template('{% for v in values|getlist:"foo" %}{{ v }},{% endfor %}')
|
|
context = Context({'values': ['foo']})
|
|
assert t.render(context) == 'None,'
|
|
|
|
t = Template('{% for v in values|getlist:"foo" %}{{ v }},{% endfor %}')
|
|
context = Context({'values': [{'foo': 'bar'}, {'foo': 'baz'}]})
|
|
assert t.render(context) == 'bar,baz,'
|
|
t = Template('{% for v in values|getlist:"unknown" %}{{ v }},{% endfor %}')
|
|
context = Context({'values': [{'foo': 'bar'}, {'foo': 'baz'}]})
|
|
assert t.render(context) == 'None,None,'
|
|
t = Template('{% for v in values|getlist:"k"|getlist:"v" %}{{ v }},{% endfor %}')
|
|
context = Context({'values': [{'k': {'v': 'bar'}}, {'k': {'v': 'baz'}}]})
|
|
assert t.render(context) == 'bar,baz,'
|
|
t = Template('{% for v in values|getlist:"k"|getlist:"unknown" %}{{ v }},{% endfor %}')
|
|
context = Context({'values': [{'k': {'v': 'bar'}}, {'k': {'v': 'baz'}}]})
|
|
assert t.render(context) == 'None,None,'
|
|
t = Template('{% for v in values|getlist:"k"|getlist:"v" %}{{ v }},{% endfor %}')
|
|
context = Context({'values': [{'k': None}, {'k': {'v': 'baz'}}]})
|
|
assert t.render(context) == 'None,baz,'
|
|
|
|
|
|
def test_split():
|
|
t = Template('{% for x in plop|split %}{{x}}<br>{% endfor %}')
|
|
assert t.render(Context({'plop': 'ab cd ef'})) == 'ab<br>cd<br>ef<br>'
|
|
t = Template('{% for x in plop|split:"|" %}{{x}} {% endfor %}')
|
|
assert t.render(Context({'plop': 'ab|cd|ef'})) == 'ab cd ef '
|
|
t = Template('{% for x in plop|split:"|" %}{{x}} {% endfor %}')
|
|
assert t.render(Context({'plop': 42})) == '42 '
|
|
|
|
|
|
def test_removeprefix():
|
|
t = Template('{{ foo|removeprefix }}')
|
|
assert t.render(Context({})) == ''
|
|
assert t.render(Context({'foo': None})) == ''
|
|
assert t.render(Context({'foo': 'foo bar'})) == 'foo bar'
|
|
t = Template('{{ foo|removeprefix:"" }}')
|
|
assert t.render(Context({'foo': 'foo bar'})) == 'foo bar'
|
|
t = Template('{{ foo|removeprefix:"XY" }}')
|
|
assert t.render(Context({'foo': 'XYfoo barXY'})) == 'foo barXY'
|
|
assert t.render(Context({'foo': 'foo bar'})) == 'foo bar'
|
|
assert t.render(Context({'foo': 'xyfoo barXY'})) == 'xyfoo barXY'
|
|
assert t.render(Context({'foo': ' XYfoo barXY'})) == ' XYfoo barXY'
|
|
assert t.render(Context({'foo': 'XYXYfoo barXY'})) == 'XYfoo barXY'
|
|
|
|
|
|
def test_removesuffix():
|
|
t = Template('{{ foo|removesuffix }}')
|
|
assert t.render(Context()) == ''
|
|
assert t.render(Context({'foo': None})) == ''
|
|
assert t.render(Context({'foo': 'foo bar'})) == 'foo bar'
|
|
t = Template('{{ foo|removesuffix:"" }}')
|
|
assert t.render(Context({'foo': 'foo bar'})) == 'foo bar'
|
|
t = Template('{{ foo|removesuffix:"XY" }}')
|
|
assert t.render(Context({'foo': 'XYfoo barXY'})) == 'XYfoo bar'
|
|
assert t.render(Context({'foo': 'foo bar'})) == 'foo bar'
|
|
assert t.render(Context({'foo': 'XYfoo barxy'})) == 'XYfoo barxy'
|
|
assert t.render(Context({'foo': 'XYfoo barXY '})) == 'XYfoo barXY '
|
|
assert t.render(Context({'foo': 'XYfoo barXYXY'})) == 'XYfoo barXY'
|
|
|
|
|
|
def test_first():
|
|
t = Template('{{ foo|first }}')
|
|
|
|
context = Context({'foo': ['foo']})
|
|
assert t.render(context) == 'foo'
|
|
|
|
context = Context({'foo': 'foo'})
|
|
assert t.render(context) == 'f'
|
|
|
|
context = Context({'foo': ''})
|
|
assert t.render(context) == ''
|
|
|
|
context = Context({'foo': None})
|
|
assert t.render(context) == ''
|
|
|
|
context = Context({'foo': {}})
|
|
assert t.render(context) == ''
|
|
|
|
|
|
def test_last():
|
|
t = Template('{{ foo|last }}')
|
|
|
|
context = Context({'foo': ['foo']})
|
|
assert t.render(context) == 'foo'
|
|
|
|
context = Context({'foo': 'foo'})
|
|
assert t.render(context) == 'o'
|
|
|
|
context = Context({'foo': ''})
|
|
assert t.render(context) == ''
|
|
|
|
context = Context({'foo': None})
|
|
assert t.render(context) == ''
|
|
|
|
context = Context({'foo': {}})
|
|
assert t.render(context) == ''
|
|
|
|
|
|
def test_decimal():
|
|
tmpl = Template('{{ plop|decimal }}')
|
|
assert tmpl.render(Context({'plop': 'toto'})) == '0'
|
|
assert tmpl.render(Context({'plop': '3.14'})) == '3.14'
|
|
assert tmpl.render(Context({'plop': '3,14'})) == '3.14'
|
|
assert tmpl.render(Context({'plop': 3.14})) == '3.14'
|
|
assert tmpl.render(Context({'plop': 12345.678})) == '12345.678'
|
|
assert tmpl.render(Context({'plop': None})) == '0'
|
|
assert tmpl.render(Context({'plop': 0})) == '0'
|
|
|
|
tmpl = Template('{{ plop|decimal:3 }}')
|
|
assert tmpl.render(Context({'plop': '3.14'})) == '3.140'
|
|
assert tmpl.render(Context({'plop': None})) == '0.000'
|
|
tmpl = Template('{{ plop|decimal:"3" }}')
|
|
assert tmpl.render(Context({'plop': '3.14'})) == '3.140'
|
|
assert tmpl.render(Context({'plop': None})) == '0.000'
|
|
|
|
tmpl = Template('{% if plop|decimal > 2 %}hello{% endif %}')
|
|
assert tmpl.render(Context({'plop': 3})) == 'hello'
|
|
assert tmpl.render(Context({'plop': '3'})) == 'hello'
|
|
assert tmpl.render(Context({'plop': 2.001})) == 'hello'
|
|
assert tmpl.render(Context({'plop': '2.001'})) == 'hello'
|
|
assert tmpl.render(Context({'plop': 1})) == ''
|
|
assert tmpl.render(Context({'plop': 1.99})) == ''
|
|
assert tmpl.render(Context({'plop': '1.99'})) == ''
|
|
assert tmpl.render(Context({'plop': 'x'})) == ''
|
|
assert tmpl.render(Context({'plop': None})) == ''
|
|
assert tmpl.render(Context({'plop': 0})) == ''
|
|
|
|
tmpl = Template('{% if "3"|decimal == 3 %}hello{% endif %}')
|
|
assert tmpl.render(Context()) == 'hello'
|
|
tmpl = Template('{% if "3"|decimal == 3.0 %}hello{% endif %}')
|
|
assert tmpl.render(Context()) == 'hello'
|
|
tmpl = Template('{% if 3|decimal == 3 %}hello{% endif %}')
|
|
assert tmpl.render(Context()) == 'hello'
|
|
tmpl = Template('{% if 3.0|decimal == 3 %}hello{% endif %}')
|
|
assert tmpl.render(Context()) == 'hello'
|
|
tmpl = Template('{% if 3|decimal|decimal == 3 %}hello{% endif %}')
|
|
assert tmpl.render(Context()) == 'hello'
|
|
|
|
|
|
def test_add():
|
|
tmpl = Template('{{ term1|add:term2 }}')
|
|
|
|
# using strings
|
|
assert tmpl.render(Context({'term1': '1.1', 'term2': 0})) == '1.1'
|
|
assert tmpl.render(Context({'term1': 'not a number', 'term2': 1.2})) == ''
|
|
assert tmpl.render(Context({'term1': 0.3, 'term2': '1'})) == '1.3'
|
|
assert tmpl.render(Context({'term1': 1.4, 'term2': 'not a number'})) == ''
|
|
|
|
# add
|
|
assert tmpl.render(Context({'term1': 4, 'term2': -0.9})) == '3.1'
|
|
assert tmpl.render(Context({'term1': '4', 'term2': -0.8})) == '3.2'
|
|
assert tmpl.render(Context({'term1': 4, 'term2': '-0.7'})) == '3.3'
|
|
assert tmpl.render(Context({'term1': '4', 'term2': '-0.6'})) == '3.4'
|
|
assert tmpl.render(Context({'term1': '', 'term2': 3.5})) == '3.5'
|
|
assert tmpl.render(Context({'term1': None, 'term2': 3.5})) == '3.5'
|
|
assert tmpl.render(Context({'term1': 3.6, 'term2': ''})) == '3.6'
|
|
assert tmpl.render(Context({'term1': '', 'term2': ''})) == ''
|
|
assert tmpl.render(Context({'term1': 3.6, 'term2': None})) == '3.6'
|
|
assert tmpl.render(Context({'term1': 0, 'term2': ''})) == '0'
|
|
assert tmpl.render(Context({'term1': '', 'term2': 0})) == '0'
|
|
assert tmpl.render(Context({'term1': 0, 'term2': 0})) == '0'
|
|
|
|
# if term is '' or None and other term is decimal
|
|
assert tmpl.render(Context({'term1': '', 'term2': 2.2})) == '2.2'
|
|
assert tmpl.render(Context({'term1': None, 'term2': 2.2})) == '2.2'
|
|
assert tmpl.render(Context({'term1': 2.2, 'term2': ''})) == '2.2'
|
|
assert tmpl.render(Context({'term1': 2.2, 'term2': None})) == '2.2'
|
|
|
|
# add using ',' instead of '.' decimal separator
|
|
assert tmpl.render(Context({'term1': '1,1', 'term2': '2,2'})) == '3.3'
|
|
assert tmpl.render(Context({'term1': '1,1', 'term2': '2.2'})) == '3.3'
|
|
assert tmpl.render(Context({'term1': '1,1', 'term2': 2.2})) == '3.3'
|
|
assert tmpl.render(Context({'term1': '1,1', 'term2': 0})) == '1.1'
|
|
assert tmpl.render(Context({'term1': '1,1', 'term2': ''})) == '1.1'
|
|
assert tmpl.render(Context({'term1': '1,1', 'term2': None})) == '1.1'
|
|
assert tmpl.render(Context({'term1': '1.1', 'term2': '2,2'})) == '3.3'
|
|
assert tmpl.render(Context({'term1': 1.1, 'term2': '2,2'})) == '3.3'
|
|
assert tmpl.render(Context({'term1': 0, 'term2': '2,2'})) == '2.2'
|
|
assert tmpl.render(Context({'term1': '', 'term2': '2,2'})) == '2.2'
|
|
assert tmpl.render(Context({'term1': None, 'term2': '2,2'})) == '2.2'
|
|
|
|
# fallback to Django native add filter
|
|
assert tmpl.render(Context({'term1': 'foo', 'term2': 'bar'})) == 'foobar'
|
|
assert tmpl.render(Context({'term1': 'foo', 'term2': ''})) == 'foo'
|
|
assert tmpl.render(Context({'term1': 'foo', 'term2': None})) == 'foo'
|
|
assert tmpl.render(Context({'term1': 'foo', 'term2': 0})) == ''
|
|
assert tmpl.render(Context({'term1': '', 'term2': 'bar'})) == 'bar'
|
|
assert tmpl.render(Context({'term1': '', 'term2': ''})) == ''
|
|
assert tmpl.render(Context({'term1': '', 'term2': None})) == ''
|
|
assert tmpl.render(Context({'term1': None, 'term2': 'bar'})) == 'bar'
|
|
assert tmpl.render(Context({'term1': None, 'term2': ''})) == ''
|
|
assert tmpl.render(Context({'term1': None, 'term2': None})) == ''
|
|
assert tmpl.render(Context({'term1': 0, 'term2': 'bar'})) == ''
|
|
|
|
|
|
def test_substract():
|
|
tmpl = Template('{{ term1|subtract:term2 }}')
|
|
assert tmpl.render(Context({'term1': 5.1, 'term2': 1})) == '4.1'
|
|
assert tmpl.render(Context({'term1': '5.2', 'term2': 1})) == '4.2'
|
|
assert tmpl.render(Context({'term1': 5.3, 'term2': '1'})) == '4.3'
|
|
assert tmpl.render(Context({'term1': '5.4', 'term2': '1'})) == '4.4'
|
|
assert tmpl.render(Context({'term1': '', 'term2': -4.5})) == '4.5'
|
|
assert tmpl.render(Context({'term1': 4.6, 'term2': ''})) == '4.6'
|
|
assert tmpl.render(Context({'term1': '', 'term2': ''})) == '0'
|
|
assert tmpl.render(Context({'term1': 0, 'term2': ''})) == '0'
|
|
assert tmpl.render(Context({'term1': '', 'term2': 0})) == '0'
|
|
assert tmpl.render(Context({'term1': 0, 'term2': 0})) == '0'
|
|
|
|
|
|
def test_multiply():
|
|
tmpl = Template('{{ term1|multiply:term2 }}')
|
|
assert tmpl.render(Context({'term1': '3', 'term2': '2'})) == '6'
|
|
assert tmpl.render(Context({'term1': 2.5, 'term2': 2})) == '5.0'
|
|
assert tmpl.render(Context({'term1': '2.5', 'term2': 2})) == '5.0'
|
|
assert tmpl.render(Context({'term1': 2.5, 'term2': '2'})) == '5.0'
|
|
assert tmpl.render(Context({'term1': '2.5', 'term2': '2'})) == '5.0'
|
|
assert tmpl.render(Context({'term1': '', 'term2': '2'})) == '0'
|
|
assert tmpl.render(Context({'term1': 2.5, 'term2': ''})) == '0.0'
|
|
assert tmpl.render(Context({'term1': '', 'term2': ''})) == '0'
|
|
assert tmpl.render(Context({'term1': 0, 'term2': ''})) == '0'
|
|
assert tmpl.render(Context({'term1': '', 'term2': 0})) == '0'
|
|
assert tmpl.render(Context({'term1': 0, 'term2': 0})) == '0'
|
|
|
|
|
|
def test_divide():
|
|
tmpl = Template('{{ term1|divide:term2 }}')
|
|
assert tmpl.render(Context({'term1': 16, 'term2': 2})) == '8'
|
|
assert tmpl.render(Context({'term1': 6, 'term2': 0.75})) == '8'
|
|
assert tmpl.render(Context({'term1': '6', 'term2': 0.75})) == '8'
|
|
assert tmpl.render(Context({'term1': 6, 'term2': '0.75'})) == '8'
|
|
assert tmpl.render(Context({'term1': '6', 'term2': '0.75'})) == '8'
|
|
assert tmpl.render(Context({'term1': '', 'term2': '2'})) == '0'
|
|
assert tmpl.render(Context({'term1': 6, 'term2': ''})) == ''
|
|
assert tmpl.render(Context({'term1': '', 'term2': ''})) == ''
|
|
assert tmpl.render(Context({'term1': 0, 'term2': ''})) == ''
|
|
assert tmpl.render(Context({'term1': '', 'term2': 0})) == ''
|
|
assert tmpl.render(Context({'term1': 0, 'term2': 0})) == ''
|
|
tmpl = Template('{{ term1|divide:term2|decimal:2 }}')
|
|
assert tmpl.render(Context({'term1': 2, 'term2': 3})) == '0.67'
|
|
|
|
|
|
def test_ceil():
|
|
# ceil
|
|
tmpl = Template('{{ value|ceil }}')
|
|
assert tmpl.render(Context({'value': 3.14})) == '4'
|
|
assert tmpl.render(Context({'value': 3.99})) == '4'
|
|
assert tmpl.render(Context({'value': -3.14})) == '-3'
|
|
assert tmpl.render(Context({'value': -3.99})) == '-3'
|
|
assert tmpl.render(Context({'value': 0})) == '0'
|
|
assert tmpl.render(Context({'value': '3.14'})) == '4'
|
|
assert tmpl.render(Context({'value': '3.99'})) == '4'
|
|
assert tmpl.render(Context({'value': '-3.14'})) == '-3'
|
|
assert tmpl.render(Context({'value': '-3.99'})) == '-3'
|
|
assert tmpl.render(Context({'value': '0'})) == '0'
|
|
assert tmpl.render(Context({'value': 'not a number'})) == '0'
|
|
assert tmpl.render(Context({'value': ''})) == '0'
|
|
assert tmpl.render(Context({'value': None})) == '0'
|
|
|
|
|
|
def test_floor():
|
|
# floor
|
|
tmpl = Template('{{ value|floor }}')
|
|
assert tmpl.render(Context({'value': 3.14})) == '3'
|
|
assert tmpl.render(Context({'value': 3.99})) == '3'
|
|
assert tmpl.render(Context({'value': -3.14})) == '-4'
|
|
assert tmpl.render(Context({'value': -3.99})) == '-4'
|
|
assert tmpl.render(Context({'value': 0})) == '0'
|
|
assert tmpl.render(Context({'value': '3.14'})) == '3'
|
|
assert tmpl.render(Context({'value': '3.99'})) == '3'
|
|
assert tmpl.render(Context({'value': '-3.14'})) == '-4'
|
|
assert tmpl.render(Context({'value': '-3.99'})) == '-4'
|
|
assert tmpl.render(Context({'value': '0'})) == '0'
|
|
assert tmpl.render(Context({'value': 'not a number'})) == '0'
|
|
assert tmpl.render(Context({'value': ''})) == '0'
|
|
assert tmpl.render(Context({'value': None})) == '0'
|
|
|
|
|
|
def test_abs():
|
|
tmpl = Template('{{ value|abs }}')
|
|
assert tmpl.render(Context({'value': 3.14})) == '3.14'
|
|
assert tmpl.render(Context({'value': -3.14})) == '3.14'
|
|
assert tmpl.render(Context({'value': 0})) == '0'
|
|
assert tmpl.render(Context({'value': '3.14'})) == '3.14'
|
|
assert tmpl.render(Context({'value': '-3.14'})) == '3.14'
|
|
assert tmpl.render(Context({'value': '0'})) == '0'
|
|
assert tmpl.render(Context({'value': 'not a number'})) == '0'
|
|
assert tmpl.render(Context({'value': ''})) == '0'
|
|
assert tmpl.render(Context({'value': None})) == '0'
|
|
|
|
|
|
def test_sum():
|
|
t = Template('{{ "2 29.5 9,5 .5"|split|sum }}')
|
|
assert t.render(Context()) == '41.5'
|
|
t = Template('{{ list|sum }}')
|
|
assert t.render(Context({'list': [1, 2, '3']})) == '6'
|
|
assert t.render(Context({'list': [1, 2, 'x']})) == '3'
|
|
assert t.render(Context({'list': [None, 2.0, 'x']})) == '2'
|
|
assert t.render(Context({'list': []})) == '0'
|
|
assert t.render(Context({'list': None})) == '' # list is not iterable
|
|
assert t.render(Context({'list': '123'})) == '' # consider string as not iterable
|
|
assert t.render(Context()) == ''
|
|
|
|
|
|
def test_duration():
|
|
context = Context({'value': 120})
|
|
assert Template('{{ value|duration }}').render(context) == '2min'
|
|
assert Template('{{ value|duration:"long" }}').render(context) == '2 minutes'
|
|
|
|
context = Context({'value': 4800})
|
|
assert Template('{{ value|duration }}').render(context) == '1h20'
|
|
assert Template('{{ value|duration:"long" }}').render(context) == '1 hour and 20 minutes'
|
|
|
|
context = Context({'value': 2400})
|
|
assert Template('{{ value|duration }}').render(context) == '40min'
|
|
assert Template('{{ value|duration:"long" }}').render(context) == '40 minutes'
|
|
|
|
context = Context({'value': 7200})
|
|
assert Template('{{ value|duration }}').render(context) == '2h'
|
|
assert Template('{{ value|duration:"long" }}').render(context) == '2 hours'
|
|
|
|
context = Context({'value': 90600})
|
|
assert Template('{{ value|duration }}').render(context) == '1 day and 1h10'
|
|
assert Template('{{ value|duration:"long" }}').render(context) == '1 day, 1 hour and 10 minutes'
|
|
|
|
context = Context({'value': 3660})
|
|
assert Template('{{ value|duration }}').render(context) == '1h01'
|
|
|
|
context = Context({'value': 'xx'})
|
|
assert Template('{{ value|duration }}').render(context) == ''
|
|
assert Template('{{ value|duration:"long" }}').render(context) == ''
|
|
|
|
context = Context({'value': 10_000_000})
|
|
assert (
|
|
Template('{{ value|duration:"long" }}').render(context)
|
|
== '3 months, 22 days, 17 hours, 46 minutes and 40 seconds'
|
|
)
|
|
|
|
context = Context({'value': 100_000_000})
|
|
assert (
|
|
Template('{{ value|duration:"long" }}').render(context)
|
|
== '3 years, 1 month, 30 days, 15 hours, 46 minutes and 40 seconds'
|
|
)
|