blob: b425e18d32dc112c3d5520f654b54bf7fc427f24 [file] [log] [blame]
Armin Ronacher3da90312008-05-23 16:37:28 +02001# -*- coding: utf-8 -*-
2"""
3 unit test for some extensions
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 :copyright: 2008 by Armin Ronacher.
7 :license: BSD, see LICENSE for more details.
8"""
Armin Ronacher3e3a9be2008-06-14 12:44:15 +02009import re
Armin Ronacher6df604e2008-05-23 22:18:38 +020010from jinja2 import Environment, nodes
Armin Ronacherd02fc7d2008-06-14 14:19:47 +020011from jinja2.ext import Extension
12from jinja2.lexer import Token, count_newlines
Armin Ronacher6df604e2008-05-23 22:18:38 +020013
14
15importable_object = 23
16
17
Armin Ronacherd02fc7d2008-06-14 14:19:47 +020018_gettext_re = re.compile(r'_\((.*?)\)')
Armin Ronacher3e3a9be2008-06-14 12:44:15 +020019
20
Armin Ronacher6df604e2008-05-23 22:18:38 +020021class TestExtension(Extension):
22 tags = set(['test'])
23 ext_attr = 42
24
25 def parse(self, parser):
26 return nodes.Output([self.call_method('_dump', [
27 nodes.EnvironmentAttribute('sandboxed'),
28 self.attr('ext_attr'),
29 nodes.ImportedName(__name__ + '.importable_object'),
30 nodes.ContextReference()
31 ])]).set_lineno(parser.stream.next().lineno)
32
33 def _dump(self, sandboxed, ext_attr, imported_object, context):
34 return '%s|%s|%s|%s' % (
35 sandboxed,
36 ext_attr,
37 imported_object,
38 context.blocks
39 )
Armin Ronacher3da90312008-05-23 16:37:28 +020040
41
Armin Ronacher3e3a9be2008-06-14 12:44:15 +020042class PreprocessorExtension(Extension):
43
44 def preprocess(self, source, name, filename=None):
45 return source.replace('[[TEST]]', '({{ foo }})')
46
47
48class StreamFilterExtension(Extension):
49
50 def filter_stream(self, stream):
51 for token in stream:
52 if token.type is 'data':
53 for t in self.interpolate(token):
54 yield t
55 else:
56 yield token
57
Armin Ronacher3e3a9be2008-06-14 12:44:15 +020058 def interpolate(self, token):
59 pos = 0
60 end = len(token.value)
61 lineno = token.lineno
62 while 1:
63 match = _gettext_re.search(token.value, pos)
64 if match is None:
65 break
66 value = token.value[pos:match.start()]
67 if value:
68 yield Token(lineno, 'data', value)
Armin Ronacherd02fc7d2008-06-14 14:19:47 +020069 lineno += count_newlines(token.value)
Armin Ronacher3e3a9be2008-06-14 12:44:15 +020070 yield Token(lineno, 'variable_begin', None)
71 yield Token(lineno, 'name', 'gettext')
72 yield Token(lineno, 'lparen', None)
73 yield Token(lineno, 'string', match.group(1))
74 yield Token(lineno, 'rparen', None)
75 yield Token(lineno, 'variable_end', None)
76 pos = match.end()
77 if pos < end:
78 yield Token(lineno, 'data', token.value[pos:])
79
80
Armin Ronacher3da90312008-05-23 16:37:28 +020081def test_loop_controls():
82 env = Environment(extensions=['jinja2.ext.loopcontrols'])
83
84 tmpl = env.from_string('''
85 {%- for item in [1, 2, 3, 4] %}
86 {%- if item % 2 == 0 %}{% continue %}{% endif -%}
87 {{ item }}
88 {%- endfor %}''')
89 assert tmpl.render() == '13'
90
91 tmpl = env.from_string('''
92 {%- for item in [1, 2, 3, 4] %}
93 {%- if item > 2 %}{% break %}{% endif -%}
94 {{ item }}
95 {%- endfor %}''')
96 assert tmpl.render() == '12'
97
98
99def test_do():
100 env = Environment(extensions=['jinja2.ext.do'])
101 tmpl = env.from_string('''
102 {%- set items = [] %}
103 {%- for char in "foo" %}
104 {%- do items.append(loop.index0 ~ char) %}
105 {%- endfor %}{{ items|join(', ') }}''')
106 assert tmpl.render() == '0f, 1o, 2o'
Armin Ronacher6df604e2008-05-23 22:18:38 +0200107
108
109def test_extension_nodes():
110 env = Environment(extensions=[TestExtension])
111 tmpl = env.from_string('{% test %}')
112 assert tmpl.render() == 'False|42|23|{}'
Armin Ronacher9cf95912008-05-24 19:54:43 +0200113
114
115def test_identifier():
116 assert TestExtension.identifier == __name__ + '.TestExtension'
Armin Ronacher9f258ff2008-05-24 22:28:52 +0200117
118
119def test_rebinding():
120 original = Environment(extensions=[TestExtension])
121 overlay = original.overlay()
122 for env in original, overlay:
123 for ext in env.extensions.itervalues():
124 assert ext.environment is env
Armin Ronacher3e3a9be2008-06-14 12:44:15 +0200125
126
127def test_preprocessor_extension():
128 env = Environment(extensions=[PreprocessorExtension])
129 tmpl = env.from_string('{[[TEST]]}')
130 assert tmpl.render(foo=42) == '{(42)}'
131
132
133def test_streamfilter_extension():
134 env = Environment(extensions=[StreamFilterExtension])
135 env.globals['gettext'] = lambda x: x.title()
136 tmpl = env.from_string('Foo _(bar) Baz')
137 assert tmpl.render() == 'Foo Bar Baz'