blob: e7e9f346df79729e1455312f553bac3cf14fe312 [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 }))
153 t = env.from_string('{% extends "master.html" %}{% block item %}{{ item }}{% endblock %}')
154 assert t.render(seq=range(5)) == '[0][1][2][3][4]'
155
156 def test_super_in_scoped_block(self):
157 env = Environment(loader=DictLoader({
158 'master.html': '{% for item in seq %}[{% block item scoped %}'
159 '{{ item }}{% endblock %}]{% endfor %}'
160 }))
161 t = env.from_string('{% extends "master.html" %}{% block item %}'
162 '{{ super() }}|{{ item * 2 }}{% endblock %}')
163 assert t.render(seq=range(5)) == '[0|0][1|2][2|4][3|6][4|8]'
164
165
166class BugFixTestCase(JinjaTestCase):
167
168 def test_fixed_macro_scoping_bug(self):
169 assert Environment(loader=DictLoader({
170 'test.html': '''\
171 {% extends 'details.html' %}
172
173 {% macro my_macro() %}
174 my_macro
175 {% endmacro %}
176
177 {% block inner_box %}
178 {{ my_macro() }}
179 {% endblock %}
180 ''',
181 'details.html': '''\
182 {% extends 'standard.html' %}
183
184 {% macro my_macro() %}
185 my_macro
186 {% endmacro %}
187
188 {% block content %}
189 {% block outer_box %}
190 outer_box
191 {% block inner_box %}
192 inner_box
193 {% endblock %}
194 {% endblock %}
195 {% endblock %}
196 ''',
197 'standard.html': '''
198 {% block content %} {% endblock %}
199 '''
200 })).get_template("test.html").render().split() == [u'outer_box', u'my_macro']
201
202
203def suite():
204 suite = unittest.TestSuite()
205 suite.addTest(unittest.makeSuite(InheritanceTestCase))
206 suite.addTest(unittest.makeSuite(BugFixTestCase))
207 return suite