1 # -*- coding: utf-8 -*-
6 Tests for the extensions.
8 :copyright: (c) 2010 by the Jinja Team.
9 :license: BSD, see LICENSE for more details.
14 from jinja2.testsuite import JinjaTestCase, filesystem_loader
16 from jinja2 import Environment, nodes
17 from jinja2.ext import Extension
18 from jinja2.lexer import Token, count_newlines
21 importable_object = 23
23 _gettext_re = re.compile(r'_\((.*?)\)(?s)')
26 class TestExtension(Extension):
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)
38 def _dump(self, sandboxed, ext_attr, imported_object, context):
39 return '%s|%s|%s|%s' % (
47 class PreprocessorExtension(Extension):
49 def preprocess(self, source, name, filename=None):
50 return source.replace('[[TEST]]', '({{ foo }})')
53 class StreamFilterExtension(Extension):
55 def filter_stream(self, stream):
57 if token.type == 'data':
58 for t in self.interpolate(token):
63 def interpolate(self, token):
65 end = len(token.value)
68 match = _gettext_re.search(token.value, pos)
71 value = token.value[pos:match.start()]
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)
83 yield Token(lineno, 'data', token.value[pos:])
86 class ExtensionsTestCase(JinjaTestCase):
88 def test_loop_controls(self):
89 env = Environment(extensions=['jinja2.ext.loopcontrols'])
91 tmpl = env.from_string('''
92 {%- for item in [1, 2, 3, 4] %}
93 {%- if item % 2 == 0 %}{% continue %}{% endif -%}
96 assert tmpl.render() == '13'
98 tmpl = env.from_string('''
99 {%- for item in [1, 2, 3, 4] %}
100 {%- if item > 2 %}{% break %}{% endif -%}
103 assert tmpl.render() == '12'
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'
115 env = Environment(extensions=['jinja2.ext.with_'])
116 tmpl = env.from_string('''\
117 {% with a=42, b=23 -%}
122 assert [x.strip() for x in tmpl.render(a=1, b=2).splitlines()] \
123 == ['42 = 23', '1 = 2']
125 def test_extension_nodes(self):
126 env = Environment(extensions=[TestExtension])
127 tmpl = env.from_string('{% test %}')
128 assert tmpl.render() == 'False|42|23|{}'
130 def test_identifier(self):
131 assert TestExtension.identifier == __name__ + '.TestExtension'
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
140 def test_preprocessor_extension(self):
141 env = Environment(extensions=[PreprocessorExtension])
142 tmpl = env.from_string('{[[TEST]]}')
143 assert tmpl.render(foo=42) == '{(42)}'
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')
150 assert out == 'Foo BAR Baz'
154 suite = unittest.TestSuite()
155 suite.addTest(unittest.makeSuite(ExtensionsTestCase))