blob: 57298ac6c395c0ff4898353778a9abc372434af4 [file] [log] [blame]
Armin Ronacher7af781c2010-02-09 16:05:08 +01001# -*- coding: utf-8 -*-
2"""
3 jinja2.testsuite.ext
4 ~~~~~~~~~~~~~~~~~~~~
5
6 Tests for the extensions.
7
8 :copyright: (c) 2010 by the Jinja Team.
9 :license: BSD, see LICENSE for more details.
10"""
11import re
12import unittest
13
14from jinja2.testsuite import JinjaTestCase, filesystem_loader
15
16from jinja2 import Environment, nodes
17from jinja2.ext import Extension
18from jinja2.lexer import Token, count_newlines
19
20
21importable_object = 23
22
23_gettext_re = re.compile(r'_\((.*?)\)(?s)')
24
25
26class TestExtension(Extension):
27 tags = set(['test'])
28 ext_attr = 42
29
30 def parse(self, parser):
31 return nodes.Output([self.call_method('_dump', [
32 nodes.EnvironmentAttribute('sandboxed'),
33 self.attr('ext_attr'),
34 nodes.ImportedName(__name__ + '.importable_object'),
35 nodes.ContextReference()
36 ])]).set_lineno(parser.stream.next().lineno)
37
38 def _dump(self, sandboxed, ext_attr, imported_object, context):
39 return '%s|%s|%s|%s' % (
40 sandboxed,
41 ext_attr,
42 imported_object,
43 context.blocks
44 )
45
46
47class PreprocessorExtension(Extension):
48
49 def preprocess(self, source, name, filename=None):
50 return source.replace('[[TEST]]', '({{ foo }})')
51
52
53class StreamFilterExtension(Extension):
54
55 def filter_stream(self, stream):
56 for token in stream:
57 if token.type == 'data':
58 for t in self.interpolate(token):
59 yield t
60 else:
61 yield token
62
63 def interpolate(self, token):
64 pos = 0
65 end = len(token.value)
66 lineno = token.lineno
67 while 1:
68 match = _gettext_re.search(token.value, pos)
69 if match is None:
70 break
71 value = token.value[pos:match.start()]
72 if value:
73 yield Token(lineno, 'data', value)
74 lineno += count_newlines(token.value)
75 yield Token(lineno, 'variable_begin', None)
76 yield Token(lineno, 'name', 'gettext')
77 yield Token(lineno, 'lparen', None)
78 yield Token(lineno, 'string', match.group(1))
79 yield Token(lineno, 'rparen', None)
80 yield Token(lineno, 'variable_end', None)
81 pos = match.end()
82 if pos < end:
83 yield Token(lineno, 'data', token.value[pos:])
84
85
86class ExtensionsTestCase(JinjaTestCase):
87
88 def test_loop_controls(self):
89 env = Environment(extensions=['jinja2.ext.loopcontrols'])
90
91 tmpl = env.from_string('''
92 {%- for item in [1, 2, 3, 4] %}
93 {%- if item % 2 == 0 %}{% continue %}{% endif -%}
94 {{ item }}
95 {%- endfor %}''')
96 assert tmpl.render() == '13'
97
98 tmpl = env.from_string('''
99 {%- for item in [1, 2, 3, 4] %}
100 {%- if item > 2 %}{% break %}{% endif -%}
101 {{ item }}
102 {%- endfor %}''')
103 assert tmpl.render() == '12'
104
105 def test_do(self):
106 env = Environment(extensions=['jinja2.ext.do'])
107 tmpl = env.from_string('''
108 {%- set items = [] %}
109 {%- for char in "foo" %}
110 {%- do items.append(loop.index0 ~ char) %}
111 {%- endfor %}{{ items|join(', ') }}''')
112 assert tmpl.render() == '0f, 1o, 2o'
113
114 def test_with(self):
115 env = Environment(extensions=['jinja2.ext.with_'])
116 tmpl = env.from_string('''\
117 {% with a=42, b=23 -%}
118 {{ a }} = {{ b }}
119 {% endwith -%}
120 {{ a }} = {{ b }}\
121 ''')
122 assert [x.strip() for x in tmpl.render(a=1, b=2).splitlines()] \
123 == ['42 = 23', '1 = 2']
124
125 def test_extension_nodes(self):
126 env = Environment(extensions=[TestExtension])
127 tmpl = env.from_string('{% test %}')
128 assert tmpl.render() == 'False|42|23|{}'
129
130 def test_identifier(self):
131 assert TestExtension.identifier == __name__ + '.TestExtension'
132
133 def test_rebinding(self):
134 original = Environment(extensions=[TestExtension])
135 overlay = original.overlay()
136 for env in original, overlay:
137 for ext in env.extensions.itervalues():
138 assert ext.environment is env
139
140 def test_preprocessor_extension(self):
141 env = Environment(extensions=[PreprocessorExtension])
142 tmpl = env.from_string('{[[TEST]]}')
143 assert tmpl.render(foo=42) == '{(42)}'
144
145 def test_streamfilter_extension(self):
146 env = Environment(extensions=[StreamFilterExtension])
147 env.globals['gettext'] = lambda x: x.upper()
148 tmpl = env.from_string('Foo _(bar) Baz')
149 out = tmpl.render()
150 assert out == 'Foo BAR Baz'
151
152
153def suite():
154 suite = unittest.TestSuite()
155 suite.addTest(unittest.makeSuite(ExtensionsTestCase))
156 return suite