blob: 942c1c3f9ca7502ec2ecb12a93a2800ef9e6cfee [file] [log] [blame]
Armin Ronacher93e14c22007-03-20 16:17:48 +01001# -*- coding: utf-8 -*-
2"""
3 unit test for various things
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
Armin Ronacher62ccd1b2009-01-04 14:26:19 +01006 :copyright: (c) 2009 by the Jinja Team.
Armin Ronacher93e14c22007-03-20 16:17:48 +01007 :license: BSD, see LICENSE for more details.
8"""
Armin Ronacher9f258ff2008-05-24 22:28:52 +02009import gc
Armin Ronacher42979eb2009-07-26 11:08:50 +020010from jinja2 import escape, is_undefined, Environment
Armin Ronacherccae0552008-10-05 23:08:58 +020011from jinja2.utils import Cycler
Christoph Hacke9e43bb2008-04-13 23:35:48 +020012from jinja2.exceptions import TemplateSyntaxError
Armin Ronacher93e14c22007-03-20 16:17:48 +010013
Armin Ronacher9e6400e2009-09-14 14:58:01 -070014from nose import SkipTest
Armin Ronacher42979eb2009-07-26 11:08:50 +020015from nose.tools import assert_raises
16
17env = Environment()
Rene Leonhardtc7e6c6d2009-04-20 23:08:53 +020018
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020019
Armin Ronacher93e14c22007-03-20 16:17:48 +010020UNPACKING = '''{% for a, b, c in [[1, 2, 3]] %}{{ a }}|{{ b }}|{{ c }}{% endfor %}'''
Armin Ronacher93e14c22007-03-20 16:17:48 +010021RAW = '''{% raw %}{{ FOO }} and {% BAR %}{% endraw %}'''
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020022CONST = '''{{ true }}|{{ false }}|{{ none }}|\
23{{ none is defined }}|{{ missing is defined }}'''
Armin Ronacher0a2ac692008-05-13 01:03:08 +020024LOCALSET = '''{% set foo = 0 %}\
25{% for item in [1, 2] %}{% set foo = 1 %}{% endfor %}\
Armin Ronacher1cc232c2007-09-07 17:52:41 +020026{{ foo }}'''
Armin Ronacher0a2ac692008-05-13 01:03:08 +020027CONSTASS1 = '''{% set true = 42 %}'''
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020028CONSTASS2 = '''{% for none in seq %}{% endfor %}'''
Armin Ronacher93e14c22007-03-20 16:17:48 +010029
30
Armin Ronacher42979eb2009-07-26 11:08:50 +020031def test_unpacking():
Armin Ronacher93e14c22007-03-20 16:17:48 +010032 tmpl = env.from_string(UNPACKING)
33 assert tmpl.render() == '1|2|3'
34
35
Armin Ronacher42979eb2009-07-26 11:08:50 +020036def test_raw():
Armin Ronacher93e14c22007-03-20 16:17:48 +010037 tmpl = env.from_string(RAW)
38 assert tmpl.render() == '{{ FOO }} and {% BAR %}'
39
40
Armin Ronacher42979eb2009-07-26 11:08:50 +020041def test_const():
Armin Ronacherecc051b2007-06-01 18:25:28 +020042 tmpl = env.from_string(CONST)
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020043 assert tmpl.render() == 'True|False|None|True|False'
Armin Ronacherecc051b2007-06-01 18:25:28 +020044
45
Armin Ronacher42979eb2009-07-26 11:08:50 +020046def test_const_assign():
Armin Ronacherecc051b2007-06-01 18:25:28 +020047 for tmpl in CONSTASS1, CONSTASS2:
Armin Ronacher42979eb2009-07-26 11:08:50 +020048 assert_raises(TemplateSyntaxError, env.from_string, tmpl)
Armin Ronacher1cc232c2007-09-07 17:52:41 +020049
50
Armin Ronacher42979eb2009-07-26 11:08:50 +020051def test_localset():
Armin Ronacher1cc232c2007-09-07 17:52:41 +020052 tmpl = env.from_string(LOCALSET)
53 assert tmpl.render() == '0'
Armin Ronacher9f258ff2008-05-24 22:28:52 +020054
55
56def test_markup_leaks():
Armin Ronacher9e6400e2009-09-14 14:58:01 -070057 # this test only tests the c extension
58 if hasattr(escape, 'func_code'):
59 raise SkipTest()
Armin Ronacher9f258ff2008-05-24 22:28:52 +020060 counts = set()
61 for count in xrange(20):
62 for item in xrange(1000):
63 escape("foo")
64 escape("<foo>")
65 escape(u"foo")
66 escape(u"<foo>")
67 counts.add(len(gc.get_objects()))
68 assert len(counts) == 1, 'ouch, c extension seems to leak objects'
Armin Ronacherf15f5f72008-05-26 12:21:45 +020069
70
Armin Ronacher6dc6f292008-06-12 08:50:07 +020071def test_item_and_attribute():
Armin Ronacherf15f5f72008-05-26 12:21:45 +020072 from jinja2.sandbox import SandboxedEnvironment
73
74 for env in Environment(), SandboxedEnvironment():
75 tmpl = env.from_string('{{ foo.items() }}')
Armin Ronacher6dc6f292008-06-12 08:50:07 +020076 assert tmpl.render(foo={'items': 42}) == "[('items', 42)]"
Armin Ronachere3290ea2008-06-12 10:30:01 +020077 tmpl = env.from_string('{{ foo|attr("items")() }}')
Armin Ronacher6dc6f292008-06-12 08:50:07 +020078 assert tmpl.render(foo={'items': 42}) == "[('items', 42)]"
79 tmpl = env.from_string('{{ foo["items"] }}')
80 assert tmpl.render(foo={'items': 42}) == '42'
Armin Ronacher665bfb82008-07-14 13:41:46 +020081
82
83def test_finalizer():
Armin Ronacher665bfb82008-07-14 13:41:46 +020084 def finalize_none_empty(value):
85 if value is None:
86 value = u''
87 return value
88 env = Environment(finalize=finalize_none_empty)
89 tmpl = env.from_string('{% for item in seq %}|{{ item }}{% endfor %}')
90 assert tmpl.render(seq=(None, 1, "foo")) == '||1|foo'
91 tmpl = env.from_string('<{{ none }}>')
92 assert tmpl.render() == '<>'
Armin Ronacherccae0552008-10-05 23:08:58 +020093
94
95def test_cycler():
96 items = 1, 2, 3
97 c = Cycler(*items)
98 for item in items + items:
99 assert c.current == item
100 assert c.next() == item
101 c.next()
102 assert c.current == 2
103 c.reset()
104 assert c.current == 1
Armin Ronacherba6e25a2008-11-02 15:58:14 +0100105
106
Armin Ronacher42979eb2009-07-26 11:08:50 +0200107def test_expressions():
Armin Ronacherba6e25a2008-11-02 15:58:14 +0100108 expr = env.compile_expression("foo")
109 assert expr() is None
110 assert expr(foo=42) == 42
111 expr2 = env.compile_expression("foo", undefined_to_none=False)
112 assert is_undefined(expr2())
113
114 expr = env.compile_expression("42 + foo")
115 assert expr(foo=42) == 84