~brad-marshall/charms/trusty/apache2-wsgi/fix-haproxy-relations

« back to all changes in this revision

Viewing changes to hooks/lib/jinja2/testsuite/lexnparse.py

  • Committer: Robin Winslow
  • Date: 2014-05-27 14:00:44 UTC
  • Revision ID: robin.winslow@canonical.com-20140527140044-8rpmb3wx4djzwa83
Add all files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
"""
 
3
    jinja2.testsuite.lexnparse
 
4
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
5
 
 
6
    All the unittests regarding lexing, parsing and syntax.
 
7
 
 
8
    :copyright: (c) 2010 by the Jinja Team.
 
9
    :license: BSD, see LICENSE for more details.
 
10
"""
 
11
import unittest
 
12
 
 
13
from jinja2.testsuite import JinjaTestCase
 
14
 
 
15
from jinja2 import Environment, Template, TemplateSyntaxError, \
 
16
     UndefinedError, nodes
 
17
from jinja2._compat import next, iteritems, text_type, PY2
 
18
from jinja2.lexer import Token, TokenStream, TOKEN_EOF, \
 
19
     TOKEN_BLOCK_BEGIN, TOKEN_BLOCK_END
 
20
 
 
21
env = Environment()
 
22
 
 
23
 
 
24
# how does a string look like in jinja syntax?
 
25
if PY2:
 
26
    def jinja_string_repr(string):
 
27
        return repr(string)[1:]
 
28
else:
 
29
    jinja_string_repr = repr
 
30
 
 
31
 
 
32
class TokenStreamTestCase(JinjaTestCase):
 
33
    test_tokens = [Token(1, TOKEN_BLOCK_BEGIN, ''),
 
34
                   Token(2, TOKEN_BLOCK_END, ''),
 
35
                  ]
 
36
 
 
37
    def test_simple(self):
 
38
        ts = TokenStream(self.test_tokens, "foo", "bar")
 
39
        assert ts.current.type is TOKEN_BLOCK_BEGIN
 
40
        assert bool(ts)
 
41
        assert not bool(ts.eos)
 
42
        next(ts)
 
43
        assert ts.current.type is TOKEN_BLOCK_END
 
44
        assert bool(ts)
 
45
        assert not bool(ts.eos)
 
46
        next(ts)
 
47
        assert ts.current.type is TOKEN_EOF
 
48
        assert not bool(ts)
 
49
        assert bool(ts.eos)
 
50
 
 
51
    def test_iter(self):
 
52
        token_types = [t.type for t in TokenStream(self.test_tokens, "foo", "bar")]
 
53
        assert token_types == ['block_begin', 'block_end', ]
 
54
 
 
55
 
 
56
class LexerTestCase(JinjaTestCase):
 
57
 
 
58
    def test_raw1(self):
 
59
        tmpl = env.from_string('{% raw %}foo{% endraw %}|'
 
60
                               '{%raw%}{{ bar }}|{% baz %}{%       endraw    %}')
 
61
        assert tmpl.render() == 'foo|{{ bar }}|{% baz %}'
 
62
 
 
63
    def test_raw2(self):
 
64
        tmpl = env.from_string('1  {%- raw -%}   2   {%- endraw -%}   3')
 
65
        assert tmpl.render() == '123'
 
66
 
 
67
    def test_balancing(self):
 
68
        env = Environment('{%', '%}', '${', '}')
 
69
        tmpl = env.from_string('''{% for item in seq
 
70
            %}${{'foo': item}|upper}{% endfor %}''')
 
71
        assert tmpl.render(seq=list(range(3))) == "{'FOO': 0}{'FOO': 1}{'FOO': 2}"
 
72
 
 
73
    def test_comments(self):
 
74
        env = Environment('<!--', '-->', '{', '}')
 
75
        tmpl = env.from_string('''\
 
76
<ul>
 
77
<!--- for item in seq -->
 
78
  <li>{item}</li>
 
79
<!--- endfor -->
 
80
</ul>''')
 
81
        assert tmpl.render(seq=list(range(3))) == ("<ul>\n  <li>0</li>\n  "
 
82
                                             "<li>1</li>\n  <li>2</li>\n</ul>")
 
83
 
 
84
    def test_string_escapes(self):
 
85
        for char in u'\0', u'\u2668', u'\xe4', u'\t', u'\r', u'\n':
 
86
            tmpl = env.from_string('{{ %s }}' % jinja_string_repr(char))
 
87
            assert tmpl.render() == char
 
88
        assert env.from_string('{{ "\N{HOT SPRINGS}" }}').render() == u'\u2668'
 
89
 
 
90
    def test_bytefallback(self):
 
91
        from pprint import pformat
 
92
        tmpl = env.from_string(u'''{{ 'foo'|pprint }}|{{ 'bär'|pprint }}''')
 
93
        assert tmpl.render() == pformat('foo') + '|' + pformat(u'bär')
 
94
 
 
95
    def test_operators(self):
 
96
        from jinja2.lexer import operators
 
97
        for test, expect in iteritems(operators):
 
98
            if test in '([{}])':
 
99
                continue
 
100
            stream = env.lexer.tokenize('{{ %s }}' % test)
 
101
            next(stream)
 
102
            assert stream.current.type == expect
 
103
 
 
104
    def test_normalizing(self):
 
105
        for seq in '\r', '\r\n', '\n':
 
106
            env = Environment(newline_sequence=seq)
 
107
            tmpl = env.from_string('1\n2\r\n3\n4\n')
 
108
            result = tmpl.render()
 
109
            assert result.replace(seq, 'X') == '1X2X3X4'
 
110
 
 
111
    def test_trailing_newline(self):
 
112
        for keep in [True, False]:
 
113
            env = Environment(keep_trailing_newline=keep)
 
114
            for template,expected in [
 
115
                    ('', {}),
 
116
                    ('no\nnewline', {}),
 
117
                    ('with\nnewline\n', {False: 'with\nnewline'}),
 
118
                    ('with\nseveral\n\n\n', {False: 'with\nseveral\n\n'}),
 
119
                    ]:
 
120
                tmpl = env.from_string(template)
 
121
                expect = expected.get(keep, template)
 
122
                result = tmpl.render()
 
123
                assert result == expect, (keep, template, result, expect)
 
124
 
 
125
class ParserTestCase(JinjaTestCase):
 
126
 
 
127
    def test_php_syntax(self):
 
128
        env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->')
 
129
        tmpl = env.from_string('''\
 
130
<!-- I'm a comment, I'm not interesting -->\
 
131
<? for item in seq -?>
 
132
    <?= item ?>
 
133
<?- endfor ?>''')
 
134
        assert tmpl.render(seq=list(range(5))) == '01234'
 
135
 
 
136
    def test_erb_syntax(self):
 
137
        env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>')
 
138
        tmpl = env.from_string('''\
 
139
<%# I'm a comment, I'm not interesting %>\
 
140
<% for item in seq -%>
 
141
    <%= item %>
 
142
<%- endfor %>''')
 
143
        assert tmpl.render(seq=list(range(5))) == '01234'
 
144
 
 
145
    def test_comment_syntax(self):
 
146
        env = Environment('<!--', '-->', '${', '}', '<!--#', '-->')
 
147
        tmpl = env.from_string('''\
 
148
<!--# I'm a comment, I'm not interesting -->\
 
149
<!-- for item in seq --->
 
150
    ${item}
 
151
<!--- endfor -->''')
 
152
        assert tmpl.render(seq=list(range(5))) == '01234'
 
153
 
 
154
    def test_balancing(self):
 
155
        tmpl = env.from_string('''{{{'foo':'bar'}.foo}}''')
 
156
        assert tmpl.render() == 'bar'
 
157
 
 
158
    def test_start_comment(self):
 
159
        tmpl = env.from_string('''{# foo comment
 
160
and bar comment #}
 
161
{% macro blub() %}foo{% endmacro %}
 
162
{{ blub() }}''')
 
163
        assert tmpl.render().strip() == 'foo'
 
164
 
 
165
    def test_line_syntax(self):
 
166
        env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%')
 
167
        tmpl = env.from_string('''\
 
168
<%# regular comment %>
 
169
% for item in seq:
 
170
    ${item}
 
171
% endfor''')
 
172
        assert [int(x.strip()) for x in tmpl.render(seq=list(range(5))).split()] == \
 
173
               list(range(5))
 
174
 
 
175
        env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##')
 
176
        tmpl = env.from_string('''\
 
177
<%# regular comment %>
 
178
% for item in seq:
 
179
    ${item} ## the rest of the stuff
 
180
% endfor''')
 
181
        assert [int(x.strip()) for x in tmpl.render(seq=list(range(5))).split()] == \
 
182
                list(range(5))
 
183
 
 
184
    def test_line_syntax_priority(self):
 
185
        # XXX: why is the whitespace there in front of the newline?
 
186
        env = Environment('{%', '%}', '${', '}', '/*', '*/', '##', '#')
 
187
        tmpl = env.from_string('''\
 
188
/* ignore me.
 
189
   I'm a multiline comment */
 
190
## for item in seq:
 
191
* ${item}          # this is just extra stuff
 
192
## endfor''')
 
193
        assert tmpl.render(seq=[1, 2]).strip() == '* 1\n* 2'
 
194
        env = Environment('{%', '%}', '${', '}', '/*', '*/', '#', '##')
 
195
        tmpl = env.from_string('''\
 
196
/* ignore me.
 
197
   I'm a multiline comment */
 
198
# for item in seq:
 
199
* ${item}          ## this is just extra stuff
 
200
    ## extra stuff i just want to ignore
 
201
# endfor''')
 
202
        assert tmpl.render(seq=[1, 2]).strip() == '* 1\n\n* 2'
 
203
 
 
204
    def test_error_messages(self):
 
205
        def assert_error(code, expected):
 
206
            try:
 
207
                Template(code)
 
208
            except TemplateSyntaxError as e:
 
209
                assert str(e) == expected, 'unexpected error message'
 
210
            else:
 
211
                assert False, 'that was supposed to be an error'
 
212
 
 
213
        assert_error('{% for item in seq %}...{% endif %}',
 
214
                     "Encountered unknown tag 'endif'. Jinja was looking "
 
215
                     "for the following tags: 'endfor' or 'else'. The "
 
216
                     "innermost block that needs to be closed is 'for'.")
 
217
        assert_error('{% if foo %}{% for item in seq %}...{% endfor %}{% endfor %}',
 
218
                     "Encountered unknown tag 'endfor'. Jinja was looking for "
 
219
                     "the following tags: 'elif' or 'else' or 'endif'. The "
 
220
                     "innermost block that needs to be closed is 'if'.")
 
221
        assert_error('{% if foo %}',
 
222
                     "Unexpected end of template. Jinja was looking for the "
 
223
                     "following tags: 'elif' or 'else' or 'endif'. The "
 
224
                     "innermost block that needs to be closed is 'if'.")
 
225
        assert_error('{% for item in seq %}',
 
226
                     "Unexpected end of template. Jinja was looking for the "
 
227
                     "following tags: 'endfor' or 'else'. The innermost block "
 
228
                     "that needs to be closed is 'for'.")
 
229
        assert_error('{% block foo-bar-baz %}',
 
230
                     "Block names in Jinja have to be valid Python identifiers "
 
231
                     "and may not contain hyphens, use an underscore instead.")
 
232
        assert_error('{% unknown_tag %}',
 
233
                     "Encountered unknown tag 'unknown_tag'.")
 
234
 
 
235
 
 
236
class SyntaxTestCase(JinjaTestCase):
 
237
 
 
238
    def test_call(self):
 
239
        env = Environment()
 
240
        env.globals['foo'] = lambda a, b, c, e, g: a + b + c + e + g
 
241
        tmpl = env.from_string("{{ foo('a', c='d', e='f', *['b'], **{'g': 'h'}) }}")
 
242
        assert tmpl.render() == 'abdfh'
 
243
 
 
244
    def test_slicing(self):
 
245
        tmpl = env.from_string('{{ [1, 2, 3][:] }}|{{ [1, 2, 3][::-1] }}')
 
246
        assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]'
 
247
 
 
248
    def test_attr(self):
 
249
        tmpl = env.from_string("{{ foo.bar }}|{{ foo['bar'] }}")
 
250
        assert tmpl.render(foo={'bar': 42}) == '42|42'
 
251
 
 
252
    def test_subscript(self):
 
253
        tmpl = env.from_string("{{ foo[0] }}|{{ foo[-1] }}")
 
254
        assert tmpl.render(foo=[0, 1, 2]) == '0|2'
 
255
 
 
256
    def test_tuple(self):
 
257
        tmpl = env.from_string('{{ () }}|{{ (1,) }}|{{ (1, 2) }}')
 
258
        assert tmpl.render() == '()|(1,)|(1, 2)'
 
259
 
 
260
    def test_math(self):
 
261
        tmpl = env.from_string('{{ (1 + 1 * 2) - 3 / 2 }}|{{ 2**3 }}')
 
262
        assert tmpl.render() == '1.5|8'
 
263
 
 
264
    def test_div(self):
 
265
        tmpl = env.from_string('{{ 3 // 2 }}|{{ 3 / 2 }}|{{ 3 % 2 }}')
 
266
        assert tmpl.render() == '1|1.5|1'
 
267
 
 
268
    def test_unary(self):
 
269
        tmpl = env.from_string('{{ +3 }}|{{ -3 }}')
 
270
        assert tmpl.render() == '3|-3'
 
271
 
 
272
    def test_concat(self):
 
273
        tmpl = env.from_string("{{ [1, 2] ~ 'foo' }}")
 
274
        assert tmpl.render() == '[1, 2]foo'
 
275
 
 
276
    def test_compare(self):
 
277
        tmpl = env.from_string('{{ 1 > 0 }}|{{ 1 >= 1 }}|{{ 2 < 3 }}|'
 
278
                               '{{ 2 == 2 }}|{{ 1 <= 1 }}')
 
279
        assert tmpl.render() == 'True|True|True|True|True'
 
280
 
 
281
    def test_inop(self):
 
282
        tmpl = env.from_string('{{ 1 in [1, 2, 3] }}|{{ 1 not in [1, 2, 3] }}')
 
283
        assert tmpl.render() == 'True|False'
 
284
 
 
285
    def test_literals(self):
 
286
        tmpl = env.from_string('{{ [] }}|{{ {} }}|{{ () }}')
 
287
        assert tmpl.render().lower() == '[]|{}|()'
 
288
 
 
289
    def test_bool(self):
 
290
        tmpl = env.from_string('{{ true and false }}|{{ false '
 
291
                               'or true }}|{{ not false }}')
 
292
        assert tmpl.render() == 'False|True|True'
 
293
 
 
294
    def test_grouping(self):
 
295
        tmpl = env.from_string('{{ (true and false) or (false and true) and not false }}')
 
296
        assert tmpl.render() == 'False'
 
297
 
 
298
    def test_django_attr(self):
 
299
        tmpl = env.from_string('{{ [1, 2, 3].0 }}|{{ [[1]].0.0 }}')
 
300
        assert tmpl.render() == '1|1'
 
301
 
 
302
    def test_conditional_expression(self):
 
303
        tmpl = env.from_string('''{{ 0 if true else 1 }}''')
 
304
        assert tmpl.render() == '0'
 
305
 
 
306
    def test_short_conditional_expression(self):
 
307
        tmpl = env.from_string('<{{ 1 if false }}>')
 
308
        assert tmpl.render() == '<>'
 
309
 
 
310
        tmpl = env.from_string('<{{ (1 if false).bar }}>')
 
311
        self.assert_raises(UndefinedError, tmpl.render)
 
312
 
 
313
    def test_filter_priority(self):
 
314
        tmpl = env.from_string('{{ "foo"|upper + "bar"|upper }}')
 
315
        assert tmpl.render() == 'FOOBAR'
 
316
 
 
317
    def test_function_calls(self):
 
318
        tests = [
 
319
            (True, '*foo, bar'),
 
320
            (True, '*foo, *bar'),
 
321
            (True, '*foo, bar=42'),
 
322
            (True, '**foo, *bar'),
 
323
            (True, '**foo, bar'),
 
324
            (False, 'foo, bar'),
 
325
            (False, 'foo, bar=42'),
 
326
            (False, 'foo, bar=23, *args'),
 
327
            (False, 'a, b=c, *d, **e'),
 
328
            (False, '*foo, **bar')
 
329
        ]
 
330
        for should_fail, sig in tests:
 
331
            if should_fail:
 
332
                self.assert_raises(TemplateSyntaxError,
 
333
                    env.from_string, '{{ foo(%s) }}' % sig)
 
334
            else:
 
335
                env.from_string('foo(%s)' % sig)
 
336
 
 
337
    def test_tuple_expr(self):
 
338
        for tmpl in [
 
339
            '{{ () }}',
 
340
            '{{ (1, 2) }}',
 
341
            '{{ (1, 2,) }}',
 
342
            '{{ 1, }}',
 
343
            '{{ 1, 2 }}',
 
344
            '{% for foo, bar in seq %}...{% endfor %}',
 
345
            '{% for x in foo, bar %}...{% endfor %}',
 
346
            '{% for x in foo, %}...{% endfor %}'
 
347
        ]:
 
348
            assert env.from_string(tmpl)
 
349
 
 
350
    def test_trailing_comma(self):
 
351
        tmpl = env.from_string('{{ (1, 2,) }}|{{ [1, 2,] }}|{{ {1: 2,} }}')
 
352
        assert tmpl.render().lower() == '(1, 2)|[1, 2]|{1: 2}'
 
353
 
 
354
    def test_block_end_name(self):
 
355
        env.from_string('{% block foo %}...{% endblock foo %}')
 
356
        self.assert_raises(TemplateSyntaxError, env.from_string,
 
357
                           '{% block x %}{% endblock y %}')
 
358
 
 
359
    def test_constant_casing(self):
 
360
        for const in True, False, None:
 
361
            tmpl = env.from_string('{{ %s }}|{{ %s }}|{{ %s }}' % (
 
362
                str(const), str(const).lower(), str(const).upper()
 
363
            ))
 
364
            assert tmpl.render() == '%s|%s|' % (const, const)
 
365
 
 
366
    def test_test_chaining(self):
 
367
        self.assert_raises(TemplateSyntaxError, env.from_string,
 
368
                           '{{ foo is string is sequence }}')
 
369
        assert env.from_string('{{ 42 is string or 42 is number }}'
 
370
            ).render() == 'True'
 
371
 
 
372
    def test_string_concatenation(self):
 
373
        tmpl = env.from_string('{{ "foo" "bar" "baz" }}')
 
374
        assert tmpl.render() == 'foobarbaz'
 
375
 
 
376
    def test_notin(self):
 
377
        bar = range(100)
 
378
        tmpl = env.from_string('''{{ not 42 in bar }}''')
 
379
        assert tmpl.render(bar=bar) == text_type(not 42 in bar)
 
380
 
 
381
    def test_implicit_subscribed_tuple(self):
 
382
        class Foo(object):
 
383
            def __getitem__(self, x):
 
384
                return x
 
385
        t = env.from_string('{{ foo[1, 2] }}')
 
386
        assert t.render(foo=Foo()) == u'(1, 2)'
 
387
 
 
388
    def test_raw2(self):
 
389
        tmpl = env.from_string('{% raw %}{{ FOO }} and {% BAR %}{% endraw %}')
 
390
        assert tmpl.render() == '{{ FOO }} and {% BAR %}'
 
391
 
 
392
    def test_const(self):
 
393
        tmpl = env.from_string('{{ true }}|{{ false }}|{{ none }}|'
 
394
                               '{{ none is defined }}|{{ missing is defined }}')
 
395
        assert tmpl.render() == 'True|False|None|True|False'
 
396
 
 
397
    def test_neg_filter_priority(self):
 
398
        node = env.parse('{{ -1|foo }}')
 
399
        assert isinstance(node.body[0].nodes[0], nodes.Filter)
 
400
        assert isinstance(node.body[0].nodes[0].node, nodes.Neg)
 
401
 
 
402
    def test_const_assign(self):
 
403
        constass1 = '''{% set true = 42 %}'''
 
404
        constass2 = '''{% for none in seq %}{% endfor %}'''
 
405
        for tmpl in constass1, constass2:
 
406
            self.assert_raises(TemplateSyntaxError, env.from_string, tmpl)
 
407
 
 
408
    def test_localset(self):
 
409
        tmpl = env.from_string('''{% set foo = 0 %}\
 
410
{% for item in [1, 2] %}{% set foo = 1 %}{% endfor %}\
 
411
{{ foo }}''')
 
412
        assert tmpl.render() == '0'
 
413
 
 
414
    def test_parse_unary(self):
 
415
        tmpl = env.from_string('{{ -foo["bar"] }}')
 
416
        assert tmpl.render(foo={'bar': 42}) == '-42'
 
417
        tmpl = env.from_string('{{ -foo["bar"]|abs }}')
 
418
        assert tmpl.render(foo={'bar': 42}) == '42'
 
419
 
 
420
 
 
421
class LstripBlocksTestCase(JinjaTestCase):
 
422
 
 
423
    def test_lstrip(self):
 
424
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
425
        tmpl = env.from_string('''    {% if True %}\n    {% endif %}''')
 
426
        assert tmpl.render() == "\n"
 
427
 
 
428
    def test_lstrip_trim(self):
 
429
        env = Environment(lstrip_blocks=True, trim_blocks=True)
 
430
        tmpl = env.from_string('''    {% if True %}\n    {% endif %}''')
 
431
        assert tmpl.render() == ""
 
432
 
 
433
    def test_no_lstrip(self):
 
434
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
435
        tmpl = env.from_string('''    {%+ if True %}\n    {%+ endif %}''')
 
436
        assert tmpl.render() == "    \n    "
 
437
 
 
438
    def test_lstrip_endline(self):
 
439
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
440
        tmpl = env.from_string('''    hello{% if True %}\n    goodbye{% endif %}''')
 
441
        assert tmpl.render() == "    hello\n    goodbye"
 
442
 
 
443
    def test_lstrip_inline(self):
 
444
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
445
        tmpl = env.from_string('''    {% if True %}hello    {% endif %}''')
 
446
        assert tmpl.render() == 'hello    '
 
447
 
 
448
    def test_lstrip_nested(self):
 
449
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
450
        tmpl = env.from_string('''    {% if True %}a {% if True %}b {% endif %}c {% endif %}''')
 
451
        assert tmpl.render() == 'a b c '
 
452
 
 
453
    def test_lstrip_left_chars(self):
 
454
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
455
        tmpl = env.from_string('''    abc {% if True %}
 
456
        hello{% endif %}''')
 
457
        assert tmpl.render() == '    abc \n        hello'
 
458
 
 
459
    def test_lstrip_embeded_strings(self):
 
460
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
461
        tmpl = env.from_string('''    {% set x = " {% str %} " %}{{ x }}''')
 
462
        assert tmpl.render() == ' {% str %} '
 
463
 
 
464
    def test_lstrip_preserve_leading_newlines(self):
 
465
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
466
        tmpl = env.from_string('''\n\n\n{% set hello = 1 %}''')
 
467
        assert tmpl.render() == '\n\n\n'
 
468
        
 
469
    def test_lstrip_comment(self):
 
470
        env = Environment(lstrip_blocks=True, trim_blocks=False)
 
471
        tmpl = env.from_string('''    {# if True #}
 
472
hello
 
473
    {#endif#}''')
 
474
        assert tmpl.render() == '\nhello\n'
 
475
 
 
476
    def test_lstrip_angle_bracket_simple(self):
 
477
        env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##',
 
478
            lstrip_blocks=True, trim_blocks=True)
 
479
        tmpl = env.from_string('''    <% if True %>hello    <% endif %>''')
 
480
        assert tmpl.render() == 'hello    '
 
481
 
 
482
    def test_lstrip_angle_bracket_comment(self):
 
483
        env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##',
 
484
            lstrip_blocks=True, trim_blocks=True)
 
485
        tmpl = env.from_string('''    <%# if True %>hello    <%# endif %>''')
 
486
        assert tmpl.render() == 'hello    '
 
487
 
 
488
    def test_lstrip_angle_bracket(self):
 
489
        env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##',
 
490
            lstrip_blocks=True, trim_blocks=True)
 
491
        tmpl = env.from_string('''\
 
492
    <%# regular comment %>
 
493
    <% for item in seq %>
 
494
${item} ## the rest of the stuff
 
495
   <% endfor %>''')
 
496
        assert tmpl.render(seq=range(5)) == \
 
497
                ''.join('%s\n' % x for x in range(5))
 
498
        
 
499
    def test_lstrip_angle_bracket_compact(self):
 
500
        env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##',
 
501
            lstrip_blocks=True, trim_blocks=True)
 
502
        tmpl = env.from_string('''\
 
503
    <%#regular comment%>
 
504
    <%for item in seq%>
 
505
${item} ## the rest of the stuff
 
506
   <%endfor%>''')
 
507
        assert tmpl.render(seq=range(5)) == \
 
508
                ''.join('%s\n' % x for x in range(5))
 
509
        
 
510
    def test_php_syntax_with_manual(self):
 
511
        env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->',
 
512
            lstrip_blocks=True, trim_blocks=True)
 
513
        tmpl = env.from_string('''\
 
514
    <!-- I'm a comment, I'm not interesting -->
 
515
    <? for item in seq -?>
 
516
        <?= item ?>
 
517
    <?- endfor ?>''')
 
518
        assert tmpl.render(seq=range(5)) == '01234'
 
519
 
 
520
    def test_php_syntax(self):
 
521
        env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->',
 
522
            lstrip_blocks=True, trim_blocks=True)
 
523
        tmpl = env.from_string('''\
 
524
    <!-- I'm a comment, I'm not interesting -->
 
525
    <? for item in seq ?>
 
526
        <?= item ?>
 
527
    <? endfor ?>''')
 
528
        assert tmpl.render(seq=range(5)) == ''.join('        %s\n' % x for x in range(5))
 
529
 
 
530
    def test_php_syntax_compact(self):
 
531
        env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->',
 
532
            lstrip_blocks=True, trim_blocks=True)
 
533
        tmpl = env.from_string('''\
 
534
    <!-- I'm a comment, I'm not interesting -->
 
535
    <?for item in seq?>
 
536
        <?=item?>
 
537
    <?endfor?>''')
 
538
        assert tmpl.render(seq=range(5)) == ''.join('        %s\n' % x for x in range(5))
 
539
 
 
540
    def test_erb_syntax(self):
 
541
        env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>',
 
542
            lstrip_blocks=True, trim_blocks=True)
 
543
        #env.from_string('')
 
544
        #for n,r in env.lexer.rules.iteritems():
 
545
        #    print n
 
546
        #print env.lexer.rules['root'][0][0].pattern
 
547
        #print "'%s'" % tmpl.render(seq=range(5))
 
548
        tmpl = env.from_string('''\
 
549
<%# I'm a comment, I'm not interesting %>
 
550
    <% for item in seq %>
 
551
    <%= item %>
 
552
    <% endfor %>
 
553
''')
 
554
        assert tmpl.render(seq=range(5)) == ''.join('    %s\n' % x for x in range(5))
 
555
 
 
556
    def test_erb_syntax_with_manual(self):
 
557
        env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>',
 
558
            lstrip_blocks=True, trim_blocks=True)
 
559
        tmpl = env.from_string('''\
 
560
<%# I'm a comment, I'm not interesting %>
 
561
    <% for item in seq -%>
 
562
        <%= item %>
 
563
    <%- endfor %>''')
 
564
        assert tmpl.render(seq=range(5)) == '01234'
 
565
 
 
566
    def test_erb_syntax_no_lstrip(self):
 
567
        env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>',
 
568
            lstrip_blocks=True, trim_blocks=True)
 
569
        tmpl = env.from_string('''\
 
570
<%# I'm a comment, I'm not interesting %>
 
571
    <%+ for item in seq -%>
 
572
        <%= item %>
 
573
    <%- endfor %>''')
 
574
        assert tmpl.render(seq=range(5)) == '    01234'
 
575
 
 
576
    def test_comment_syntax(self):
 
577
        env = Environment('<!--', '-->', '${', '}', '<!--#', '-->',
 
578
            lstrip_blocks=True, trim_blocks=True)
 
579
        tmpl = env.from_string('''\
 
580
<!--# I'm a comment, I'm not interesting -->\
 
581
<!-- for item in seq --->
 
582
    ${item}
 
583
<!--- endfor -->''')
 
584
        assert tmpl.render(seq=range(5)) == '01234'
 
585
 
 
586
def suite():
 
587
    suite = unittest.TestSuite()
 
588
    suite.addTest(unittest.makeSuite(TokenStreamTestCase))
 
589
    suite.addTest(unittest.makeSuite(LexerTestCase))
 
590
    suite.addTest(unittest.makeSuite(ParserTestCase))
 
591
    suite.addTest(unittest.makeSuite(SyntaxTestCase))
 
592
    suite.addTest(unittest.makeSuite(LstripBlocksTestCase))
 
593
    return suite