blob: 87b4a59aa063ed5e836fd7178887eeb30761bd05 [file] [log] [blame]
Armin Ronacher21082442010-02-09 16:48:10 +01001# -*- coding: utf-8 -*-
2"""
3 jinja2.testsuite.inheritance
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 Tests the template inheritance feature.
7
8 :copyright: (c) 2010 by the Jinja Team.
9 :license: BSD, see LICENSE for more details.
10"""
11import os
12import time
13import tempfile
14import unittest
15
16from jinja2.testsuite import JinjaTestCase
17
18from jinja2 import Environment, DictLoader
19from jinja2.exceptions import TemplateSyntaxError
20
21
22LAYOUTTEMPLATE = '''\
23|{% block block1 %}block 1 from layout{% endblock %}
24|{% block block2 %}block 2 from layout{% endblock %}
25|{% block block3 %}
26{% block block4 %}nested block 4 from layout{% endblock %}
27{% endblock %}|'''
28
29LEVEL1TEMPLATE = '''\
30{% extends "layout" %}
31{% block block1 %}block 1 from level1{% endblock %}'''
32
33LEVEL2TEMPLATE = '''\
34{% extends "level1" %}
35{% block block2 %}{% block block5 %}nested block 5 from level2{%
36endblock %}{% endblock %}'''
37
38LEVEL3TEMPLATE = '''\
39{% extends "level2" %}
40{% block block5 %}block 5 from level3{% endblock %}
41{% block block4 %}block 4 from level3{% endblock %}
42'''
43
44LEVEL4TEMPLATE = '''\
45{% extends "level3" %}
46{% block block3 %}block 3 from level4{% endblock %}
47'''
48
49WORKINGTEMPLATE = '''\
50{% extends "layout" %}
51{% block block1 %}
52 {% if false %}
53 {% block block2 %}
54 this should workd
55 {% endblock %}
56 {% endif %}
57{% endblock %}
58'''
59
60env = Environment(loader=DictLoader({
61 'layout': LAYOUTTEMPLATE,
62 'level1': LEVEL1TEMPLATE,
63 'level2': LEVEL2TEMPLATE,
64 'level3': LEVEL3TEMPLATE,
65 'level4': LEVEL4TEMPLATE,
66 'working': WORKINGTEMPLATE
67}), trim_blocks=True)
68
69
70class InheritanceTestCase(JinjaTestCase):
71
72 def test_layout(self):
73 tmpl = env.get_template('layout')
74 assert tmpl.render() == ('|block 1 from layout|block 2 from '
75 'layout|nested block 4 from layout|')
76
77 def test_level1(self):
78 tmpl = env.get_template('level1')
79 assert tmpl.render() == ('|block 1 from level1|block 2 from '
80 'layout|nested block 4 from layout|')
81
82 def test_level2(self):
83 tmpl = env.get_template('level2')
84 assert tmpl.render() == ('|block 1 from level1|nested block 5 from '
85 'level2|nested block 4 from layout|')
86
87 def test_level3(self):
88 tmpl = env.get_template('level3')
89 assert tmpl.render() == ('|block 1 from level1|block 5 from level3|'
90 'block 4 from level3|')
91
92 def test_level4(sel):
93 tmpl = env.get_template('level4')
94 assert tmpl.render() == ('|block 1 from level1|block 5 from '
95 'level3|block 3 from level4|')
96
97 def test_super(self):
98 env = Environment(loader=DictLoader({
99 'a': '{% block intro %}INTRO{% endblock %}|'
100 'BEFORE|{% block data %}INNER{% endblock %}|AFTER',
101 'b': '{% extends "a" %}{% block data %}({{ '
102 'super() }}){% endblock %}',
103 'c': '{% extends "b" %}{% block intro %}--{{ '
104 'super() }}--{% endblock %}\n{% block data '
105 '%}[{{ super() }}]{% endblock %}'
106 }))
107 tmpl = env.get_template('c')
108 assert tmpl.render() == '--INTRO--|BEFORE|[(INNER)]|AFTER'
109
110 def test_working(self):
111 tmpl = env.get_template('working')
112
113 def test_reuse_blocks(self):
114 tmpl = env.from_string('{{ self.foo() }}|{% block foo %}42'
115 '{% endblock %}|{{ self.foo() }}')
116 assert tmpl.render() == '42|42|42'
117
118 def test_preserve_blocks(self):
119 env = Environment(loader=DictLoader({
120 'a': '{% if false %}{% block x %}A{% endblock %}{% endif %}{{ self.x() }}',
121 'b': '{% extends "a" %}{% block x %}B{{ super() }}{% endblock %}'
122 }))
123 tmpl = env.get_template('b')
124 assert tmpl.render() == 'BA'
125
126 def test_dynamic_inheritance(self):
127 env = Environment(loader=DictLoader({
128 'master1': 'MASTER1{% block x %}{% endblock %}',
129 'master2': 'MASTER2{% block x %}{% endblock %}',
130 'child': '{% extends master %}{% block x %}CHILD{% endblock %}'
131 }))
132 tmpl = env.get_template('child')
133 for m in range(1, 3):
134 assert tmpl.render(master='master%d' % m) == 'MASTER%dCHILD' % m
135
136 def test_multi_inheritance(self):
137 env = Environment(loader=DictLoader({
138 'master1': 'MASTER1{% block x %}{% endblock %}',
139 'master2': 'MASTER2{% block x %}{% endblock %}',
140 'child': '''{% if master %}{% extends master %}{% else %}{% extends
141 'master1' %}{% endif %}{% block x %}CHILD{% endblock %}'''
142 }))
143 tmpl = env.get_template('child')
144 assert tmpl.render(master='master2') == 'MASTER2CHILD'
145 assert tmpl.render(master='master1') == 'MASTER1CHILD'
146 assert tmpl.render() == 'MASTER1CHILD'
147
148 def test_scoped_block(self):
149 env = Environment(loader=DictLoader({
150 'master.html': '{% for item in seq %}[{% block item scoped %}'
151 '{% endblock %}]{% endfor %}'
152 }))
Armin Ronacher10f4bcc2010-02-09 16:52:49 +0100153 t = env.from_string('{% extends "master.html" %}{% block item %}'
154 '{{ item }}{% endblock %}')
Armin Ronacher21082442010-02-09 16:48:10 +0100155 assert t.render(seq=range(5)) == '[0][1][2][3][4]'
156
157 def test_super_in_scoped_block(self):
158 env = Environment(loader=DictLoader({
159 'master.html': '{% for item in seq %}[{% block item scoped %}'
160 '{{ item }}{% endblock %}]{% endfor %}'
161 }))
162 t = env.from_string('{% extends "master.html" %}{% block item %}'
163 '{{ super() }}|{{ item * 2 }}{% endblock %}')
164 assert t.render(seq=range(5)) == '[0|0][1|2][2|4][3|6][4|8]'
165
166
167class BugFixTestCase(JinjaTestCase):
168
169 def test_fixed_macro_scoping_bug(self):
170 assert Environment(loader=DictLoader({
171 'test.html': '''\
172 {% extends 'details.html' %}
173
174 {% macro my_macro() %}
175 my_macro
176 {% endmacro %}
177
178 {% block inner_box %}
179 {{ my_macro() }}
180 {% endblock %}
181 ''',
182 'details.html': '''\
183 {% extends 'standard.html' %}
184
185 {% macro my_macro() %}
186 my_macro
187 {% endmacro %}
188
189 {% block content %}
190 {% block outer_box %}
191 outer_box
192 {% block inner_box %}
193 inner_box
194 {% endblock %}
195 {% endblock %}
196 {% endblock %}
197 ''',
198 'standard.html': '''
199 {% block content %} {% endblock %}
200 '''
201 })).get_template("test.html").render().split() == [u'outer_box', u'my_macro']
202
203
204def suite():
205 suite = unittest.TestSuite()
206 suite.addTest(unittest.makeSuite(InheritanceTestCase))
207 suite.addTest(unittest.makeSuite(BugFixTestCase))
208 return suite