blob: 9e546c4869a1a509113a9f4984006f6b1647a272 [file] [log] [blame]
Armin Ronacherccf284b2007-05-21 16:44:26 +02001# -*- coding: utf-8 -*-
2"""
3 unit test for the parser
4 ~~~~~~~~~~~~~~~~~~~~~~~~
5
Armin Ronacher62ccd1b2009-01-04 14:26:19 +01006 :copyright: (c) 2009 by the Jinja Team.
Armin Ronacherccf284b2007-05-21 16:44:26 +02007 :license: BSD, see LICENSE for more details.
8"""
Armin Ronacher5dcb7242010-02-06 14:01:26 +01009from jinja2 import Environment, Template, TemplateSyntaxError
Armin Ronacherccf284b2007-05-21 16:44:26 +020010
Armin Ronacher42979eb2009-07-26 11:08:50 +020011env = Environment()
Rene Leonhardtc7e6c6d2009-04-20 23:08:53 +020012
Armin Ronacherccf284b2007-05-21 16:44:26 +020013
14PHP_SYNTAX = '''\
15<!-- I'm a comment, I'm not interesting -->\
16<? for item in seq -?>
17 <?= item ?>
18<?- endfor ?>'''
19
20ERB_SYNTAX = '''\
21<%# I'm a comment, I'm not interesting %>\
22<% for item in seq -%>
23 <%= item %>
24<%- endfor %>'''
25
26COMMENT_SYNTAX = '''\
27<!--# I'm a comment, I'm not interesting -->\
28<!-- for item in seq --->
29 ${item}
30<!--- endfor -->'''
31
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020032MAKO_SYNTAX = '''\
Armin Ronacher59b6bd52009-03-30 21:00:16 +020033<%# regular comment %>
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020034% for item in seq:
35 ${item}
36% endfor'''
Armin Ronacherccf284b2007-05-21 16:44:26 +020037
Armin Ronacher59b6bd52009-03-30 21:00:16 +020038MAKO_SYNTAX_LINECOMMENTS = '''\
39<%# regular comment %>
40% for item in seq:
41 ${item} ## the rest of the stuff
42% endfor'''
43
Armin Ronacherecc051b2007-06-01 18:25:28 +020044BALANCING = '''{{{'foo':'bar'}.foo}}'''
45
Armin Ronacher9b0545a2007-09-26 13:16:41 +020046STARTCOMMENT = '''{# foo comment
47and bar comment #}
48{% macro blub() %}foo{% endmacro %}
49{{ blub() }}'''
50
Armin Ronacherdb7985d2009-03-31 23:51:56 +020051LINE_SYNTAX_PRIORITY1 = '''\
52/* ignore me.
53 I'm a multiline comment */
54## for item in seq:
55* ${item} # this is just extra stuff
56## endfor
57'''
58
59LINE_SYNTAX_PRIORITY2 = '''\
Armin Ronacher59b6bd52009-03-30 21:00:16 +020060/* ignore me.
61 I'm a multiline comment */
62# for item in seq:
63* ${item} ## this is just extra stuff
Armin Ronacher3617a022009-04-01 19:17:31 +020064 ## extra stuff i just want to ignore
Armin Ronacher59b6bd52009-03-30 21:00:16 +020065# endfor
66'''
67
Armin Ronacherccf284b2007-05-21 16:44:26 +020068
Armin Ronacherccf284b2007-05-21 16:44:26 +020069def test_php_syntax():
70 env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->')
71 tmpl = env.from_string(PHP_SYNTAX)
72 assert tmpl.render(seq=range(5)) == '01234'
73
74
75def test_erb_syntax():
76 env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>')
77 tmpl = env.from_string(ERB_SYNTAX)
78 assert tmpl.render(seq=range(5)) == '01234'
79
80
81def test_comment_syntax():
82 env = Environment('<!--', '-->', '${', '}', '<!--#', '-->')
83 tmpl = env.from_string(COMMENT_SYNTAX)
84 assert tmpl.render(seq=range(5)) == '01234'
85
86
Armin Ronacher42979eb2009-07-26 11:08:50 +020087def test_balancing():
Armin Ronacherecc051b2007-06-01 18:25:28 +020088 tmpl = env.from_string(BALANCING)
89 assert tmpl.render() == 'bar'
Armin Ronacher9b0545a2007-09-26 13:16:41 +020090
91
Armin Ronacher42979eb2009-07-26 11:08:50 +020092def test_start_comment():
Armin Ronacher9b0545a2007-09-26 13:16:41 +020093 tmpl = env.from_string(STARTCOMMENT)
94 assert tmpl.render().strip() == 'foo'
Armin Ronacher4f7d2d52008-04-22 10:40:26 +020095
96
97def test_line_syntax():
98 env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%')
99 tmpl = env.from_string(MAKO_SYNTAX)
100 assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \
Rene Leonhardtc7e6c6d2009-04-20 23:08:53 +0200101 range(5)
Armin Ronacher59b6bd52009-03-30 21:00:16 +0200102
103 env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##')
104 tmpl = env.from_string(MAKO_SYNTAX_LINECOMMENTS)
105 assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \
106 range(5)
107
108
109def test_line_syntax_priority():
Armin Ronacherdb7985d2009-03-31 23:51:56 +0200110 # XXX: why is the whitespace there in front of the newline?
111 env = Environment('{%', '%}', '${', '}', '/*', '*/', '##', '#')
112 tmpl = env.from_string(LINE_SYNTAX_PRIORITY1)
Armin Ronacher1bb3ab72009-04-01 19:16:25 +0200113 assert tmpl.render(seq=[1, 2]).strip() == '* 1\n* 2'
Armin Ronacher59b6bd52009-03-30 21:00:16 +0200114 env = Environment('{%', '%}', '${', '}', '/*', '*/', '#', '##')
Armin Ronacherdb7985d2009-03-31 23:51:56 +0200115 tmpl = env.from_string(LINE_SYNTAX_PRIORITY2)
Armin Ronacher3617a022009-04-01 19:17:31 +0200116 assert tmpl.render(seq=[1, 2]).strip() == '* 1\n\n* 2'
Armin Ronacher5dcb7242010-02-06 14:01:26 +0100117
118
119def test_error_messages():
120 def assert_error(code, expected):
121 try:
122 Template(code)
123 except TemplateSyntaxError, e:
124 assert str(e) == expected, 'unexpected error message'
125 else:
126 assert False, 'that was suposed to be an error'
127
128 assert_error('{% for item in seq %}...{% endif %}',
129 "Encountered unknown tag 'endif'. Jinja was looking "
130 "for the following tags: 'endfor' or 'else'. The "
131 "innermost block that needs to be closed is 'for'.")
132 assert_error('{% if foo %}{% for item in seq %}...{% endfor %}{% endfor %}',
133 "Encountered unknown tag 'endfor'. Jinja was looking for "
134 "the following tags: 'elif' or 'else' or 'endif'. The "
135 "innermost block that needs to be closed is 'if'.")
136 assert_error('{% if foo %}',
137 "Unexpected end of template. Jinja was looking for the "
138 "following tags: 'elif' or 'else' or 'endif'. The "
139 "innermost block that needs to be closed is 'if'.")
140 assert_error('{% for item in seq %}',
141 "Unexpected end of template. Jinja was looking for the "
142 "following tags: 'endfor' or 'else'. The innermost block "
143 "that needs to be closed is 'for'.")
Armin Ronacher92622e92010-02-07 01:27:47 +0100144 assert_error('{% block foo-bar-baz %}',
145 "Block names in Jinja have to be valid Python identifiers "
146 "and may not contain hypens, use an underscore instead.")