15
16
from django import template
16
17
from django.core import urlresolvers
17
18
from django.template import loader
18
from django.template.loaders import app_directories, filesystem
19
from django.template.loaders import app_directories, filesystem, cached
19
20
from django.utils.translation import activate, deactivate, ugettext as _
20
21
from django.utils.safestring import mark_safe
21
22
from django.utils.tzinfo import LocalTimezone
23
24
from context import context_tests
24
25
from custom import custom_filters
25
from parser import filter_parsing, variable_parsing
26
from parser import token_parsing, filter_parsing, variable_parsing
26
27
from unicode import unicode_tests
28
from nodelist import NodelistTest
29
32
from loaders import *
101
126
class Templates(unittest.TestCase):
102
127
def test_loaders_security(self):
128
ad_loader = app_directories.Loader()
129
fs_loader = filesystem.Loader()
103
130
def test_template_sources(path, template_dirs, expected_sources):
104
131
if isinstance(expected_sources, list):
105
132
# Fix expected sources so they are normcased and abspathed
106
133
expected_sources = [os.path.normcase(os.path.abspath(s)) for s in expected_sources]
107
134
# Test the two loaders (app_directores and filesystem).
108
func1 = lambda p, t: list(app_directories.get_template_sources(p, t))
109
func2 = lambda p, t: list(filesystem.get_template_sources(p, t))
135
func1 = lambda p, t: list(ad_loader.get_template_sources(p, t))
136
func2 = lambda p, t: list(fs_loader.get_template_sources(p, t))
110
137
for func in (func1, func2):
111
138
if isinstance(expected_sources, list):
112
139
self.assertEqual(func(path, template_dirs), expected_sources)
150
177
test_template_sources('/DIR1/index.HTML', template_dirs,
151
178
['/dir1/index.html'])
180
def test_loader_debug_origin(self):
181
# Turn TEMPLATE_DEBUG on, so that the origin file name will be kept with
182
# the compiled templates.
183
old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, True
184
old_loaders = loader.template_source_loaders
187
loader.template_source_loaders = (filesystem.Loader(),)
189
# We rely on the fact that runtests.py sets up TEMPLATE_DIRS to
190
# point to a directory containing a 404.html file. Also that
191
# the file system and app directories loaders both inherit the
192
# load_template method from the BaseLoader class, so we only need
193
# to test one of them.
194
load_name = '404.html'
195
template = loader.get_template(load_name)
196
template_name = template.nodelist[0].source[0].name
197
self.assertTrue(template_name.endswith(load_name),
198
'Template loaded by filesystem loader has incorrect name for debug page: %s' % template_name)
200
# Aso test the cached loader, since it overrides load_template
201
cache_loader = cached.Loader(('',))
202
cache_loader._cached_loaders = loader.template_source_loaders
203
loader.template_source_loaders = (cache_loader,)
205
template = loader.get_template(load_name)
206
template_name = template.nodelist[0].source[0].name
207
self.assertTrue(template_name.endswith(load_name),
208
'Template loaded through cached loader has incorrect name for debug page: %s' % template_name)
210
template = loader.get_template(load_name)
211
template_name = template.nodelist[0].source[0].name
212
self.assertTrue(template_name.endswith(load_name),
213
'Cached template loaded through cached loader has incorrect name for debug page: %s' % template_name)
215
loader.template_source_loaders = old_loaders
216
settings.TEMPLATE_DEBUG = old_td
218
def test_extends_include_missing_baseloader(self):
220
Tests that the correct template is identified as not existing
221
when {% extends %} specifies a template that does exist, but
222
that template has an {% include %} of something that does not
226
# TEMPLATE_DEBUG must be true, otherwise the exception raised
227
# during {% include %} processing will be suppressed.
228
old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, True
229
old_loaders = loader.template_source_loaders
232
# Test the base loader class via the app loader. load_template
233
# from base is used by all shipped loaders excepting cached,
234
# which has its own test.
235
loader.template_source_loaders = (app_directories.Loader(),)
237
load_name = 'test_extends_error.html'
238
tmpl = loader.get_template(load_name)
241
r = tmpl.render(template.Context({}))
242
except template.TemplateSyntaxError, e:
243
settings.TEMPLATE_DEBUG = old_td
244
self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html')
245
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
247
loader.template_source_loaders = old_loaders
248
settings.TEMPLATE_DEBUG = old_td
250
def test_extends_include_missing_cachedloader(self):
252
Same as test_extends_include_missing_baseloader, only tests
253
behavior of the cached loader instead of BaseLoader.
256
old_td, settings.TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG, True
257
old_loaders = loader.template_source_loaders
260
cache_loader = cached.Loader(('',))
261
cache_loader._cached_loaders = (app_directories.Loader(),)
262
loader.template_source_loaders = (cache_loader,)
264
load_name = 'test_extends_error.html'
265
tmpl = loader.get_template(load_name)
268
r = tmpl.render(template.Context({}))
269
except template.TemplateSyntaxError, e:
270
self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html')
271
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
273
# For the cached loader, repeat the test, to ensure the first attempt did not cache a
274
# result that behaves incorrectly on subsequent attempts.
275
tmpl = loader.get_template(load_name)
277
tmpl.render(template.Context({}))
278
except template.TemplateSyntaxError, e:
279
self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html')
280
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
282
loader.template_source_loaders = old_loaders
283
settings.TEMPLATE_DEBUG = old_td
153
285
def test_token_smart_split(self):
154
286
# Regression test for #7027
155
287
token = template.Token(template.TOKEN_BLOCK, 'sometag _("Page not found") value|yesno:_("yes,no")')
173
305
except TemplateSyntaxError, e:
174
306
# Assert that we are getting the template syntax error and not the
175
307
# string encoding error.
176
self.assertEquals(e.args[0], "Caught an exception while rendering: Reverse for 'will_not_match' with arguments '()' and keyword arguments '{}' not found.")
308
self.assertEquals(e.args[0], "Caught NoReverseMatch while rendering: Reverse for 'will_not_match' with arguments '()' and keyword arguments '{}' not found.")
178
310
settings.SETTINGS_MODULE = old_settings_module
179
311
settings.TEMPLATE_DEBUG = old_template_debug
313
def test_invalid_block_suggestion(self):
315
from django.template import Template, TemplateSyntaxError
317
t = Template("{% if 1 %}lala{% endblock %}{% endif %}")
318
except TemplateSyntaxError, e:
319
self.assertEquals(e.args[0], "Invalid block tag: 'endblock', expected 'else' or 'endif'")
181
321
def test_templates(self):
182
322
template_tests = self.get_template_tests()
183
323
filter_tests = filters.get_filter_tests()
231
379
for invalid_str, result in [('', normal_string_result),
232
380
(expected_invalid_str, invalid_string_result)]:
233
381
settings.TEMPLATE_STRING_IF_INVALID = invalid_str
235
test_template = loader.get_template(name)
236
output = self.render(test_template, vals)
237
except ContextStackException:
238
failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Context stack was left imbalanced" % (invalid_str, name))
241
exc_type, exc_value, exc_tb = sys.exc_info()
242
if exc_type != result:
243
tb = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb))
244
failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s\n%s" % (invalid_str, name, exc_type, exc_value, tb))
247
failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % (invalid_str, name, result, output))
382
for is_cached in (False, True):
384
start = datetime.now()
385
test_template = loader.get_template(name)
387
if end-start > timedelta(seconds=0.2):
388
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to parse test" % (is_cached, invalid_str, name))
390
start = datetime.now()
391
output = self.render(test_template, vals)
393
if end-start > timedelta(seconds=0.2):
394
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to render test" % (is_cached, invalid_str, name))
395
except ContextStackException:
396
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Context stack was left imbalanced" % (is_cached, invalid_str, name))
399
exc_type, exc_value, exc_tb = sys.exc_info()
400
if exc_type != result:
401
tb = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb))
402
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s\n%s" % (is_cached, invalid_str, name, exc_type, exc_value, tb))
405
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % (is_cached, invalid_str, name, result, output))
249
408
if 'LANGUAGE_CODE' in vals[1]:
341
500
'basic-syntax26': (r'{{ "\"fred\"" }}', {}, "\"fred\""),
342
501
'basic-syntax27': (r'{{ _("\"fred\"") }}', {}, "\"fred\""),
503
# regression test for ticket #12554
504
# make sure a silent_variable_failure Exception is supressed
505
# on dictionary and attribute lookup
506
'basic-syntax28': ("{{ a.b }}", {'a': SilentGetItemClass()}, ('', 'INVALID')),
507
'basic-syntax29': ("{{ a.b }}", {'a': SilentAttrClass()}, ('', 'INVALID')),
344
509
# List-index syntax allows a template to access a certain item of a subscriptable object.
345
510
'list-index01': ("{{ var.1 }}", {"var": ["first item", "second item"]}, "second item"),
474
639
### EXCEPTIONS ############################################################
476
641
# Raise exception for invalid template name
477
'exception01': ("{% extends 'nonexistent' %}", {}, template.TemplateSyntaxError),
642
'exception01': ("{% extends 'nonexistent' %}", {}, template.TemplateDoesNotExist),
479
644
# Raise exception for invalid template name (in variable)
480
'exception02': ("{% extends nonexistent %}", {}, template.TemplateSyntaxError),
645
'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)),
482
647
# Raise exception for extra {% extends %} tags
483
648
'exception03': ("{% extends 'inheritance01' %}{% block first %}2{% endblock %}{% extends 'inheritance16' %}", {}, template.TemplateSyntaxError),
534
699
'if-tag02': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": False}, "no"),
535
700
'if-tag03': ("{% if foo %}yes{% else %}no{% endif %}", {}, "no"),
703
'if-tag-filter01': ("{% if foo|length == 5 %}yes{% else %}no{% endif %}", {'foo': 'abcde'}, "yes"),
704
'if-tag-filter02': ("{% if foo|upper == 'ABC' %}yes{% else %}no{% endif %}", {}, "no"),
707
'if-tag-eq01': ("{% if foo == bar %}yes{% else %}no{% endif %}", {}, "yes"),
708
'if-tag-eq02': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1}, "no"),
709
'if-tag-eq03': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1, 'bar': 1}, "yes"),
710
'if-tag-eq04': ("{% if foo == bar %}yes{% else %}no{% endif %}", {'foo': 1, 'bar': 2}, "no"),
711
'if-tag-eq05': ("{% if foo == '' %}yes{% else %}no{% endif %}", {}, "no"),
714
'if-tag-gt-01': ("{% if 2 > 1 %}yes{% else %}no{% endif %}", {}, "yes"),
715
'if-tag-gt-02': ("{% if 1 > 1 %}yes{% else %}no{% endif %}", {}, "no"),
716
'if-tag-gte-01': ("{% if 1 >= 1 %}yes{% else %}no{% endif %}", {}, "yes"),
717
'if-tag-gte-02': ("{% if 1 >= 2 %}yes{% else %}no{% endif %}", {}, "no"),
718
'if-tag-lt-01': ("{% if 1 < 2 %}yes{% else %}no{% endif %}", {}, "yes"),
719
'if-tag-lt-02': ("{% if 1 < 1 %}yes{% else %}no{% endif %}", {}, "no"),
720
'if-tag-lte-01': ("{% if 1 <= 1 %}yes{% else %}no{% endif %}", {}, "yes"),
721
'if-tag-lte-02': ("{% if 2 <= 1 %}yes{% else %}no{% endif %}", {}, "no"),
724
'if-tag-in-01': ("{% if 1 in x %}yes{% else %}no{% endif %}", {'x':[1]}, "yes"),
725
'if-tag-in-02': ("{% if 2 in x %}yes{% else %}no{% endif %}", {'x':[1]}, "no"),
726
'if-tag-not-in-01': ("{% if 1 not in x %}yes{% else %}no{% endif %}", {'x':[1]}, "no"),
727
'if-tag-not-in-02': ("{% if 2 not in x %}yes{% else %}no{% endif %}", {'x':[1]}, "yes"),
538
730
'if-tag-and01': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'yes'),
539
731
'if-tag-and02': ("{% if foo and bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': False}, 'no'),
554
746
'if-tag-or07': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True}, 'yes'),
555
747
'if-tag-or08': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': True}, 'yes'),
750
'if-tag-or09': ("{% if foo or bar or baz %}yes{% else %}no{% endif %}", {'baz': True}, 'yes'),
560
753
'if-tag-not01': ("{% if not foo %}no{% else %}yes{% endif %}", {'foo': True}, 'yes'),
561
'if-tag-not02': ("{% if not %}yes{% else %}no{% endif %}", {'foo': True}, 'no'),
562
'if-tag-not03': ("{% if not %}yes{% else %}no{% endif %}", {'not': True}, 'yes'),
563
'if-tag-not04': ("{% if not not %}no{% else %}yes{% endif %}", {'not': True}, 'yes'),
564
'if-tag-not05': ("{% if not not %}no{% else %}yes{% endif %}", {}, 'no'),
754
'if-tag-not02': ("{% if not not foo %}no{% else %}yes{% endif %}", {'foo': True}, 'no'),
755
# not03 to not05 removed, now TemplateSyntaxErrors
566
757
'if-tag-not06': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {}, 'no'),
567
758
'if-tag-not07': ("{% if foo and not bar %}yes{% else %}no{% endif %}", {'foo': True, 'bar': True}, 'no'),
599
790
'if-tag-not34': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': True}, 'yes'),
600
791
'if-tag-not35': ("{% if not foo or not bar %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, 'yes'),
602
# AND and OR raises a TemplateSyntaxError
603
'if-tag-error01': ("{% if foo or bar and baz %}yes{% else %}no{% endif %}", {'foo': False, 'bar': False}, template.TemplateSyntaxError),
793
# Various syntax errors
794
'if-tag-error01': ("{% if %}yes{% endif %}", {}, template.TemplateSyntaxError),
604
795
'if-tag-error02': ("{% if foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),
605
796
'if-tag-error03': ("{% if foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),
606
797
'if-tag-error04': ("{% if not foo and %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),
607
798
'if-tag-error05': ("{% if not foo or %}yes{% else %}no{% endif %}", {'foo': True}, template.TemplateSyntaxError),
799
'if-tag-error06': ("{% if abc def %}yes{% endif %}", {}, template.TemplateSyntaxError),
800
'if-tag-error07': ("{% if not %}yes{% endif %}", {}, template.TemplateSyntaxError),
801
'if-tag-error08': ("{% if and %}yes{% endif %}", {}, template.TemplateSyntaxError),
802
'if-tag-error09': ("{% if or %}yes{% endif %}", {}, template.TemplateSyntaxError),
803
'if-tag-error10': ("{% if == %}yes{% endif %}", {}, template.TemplateSyntaxError),
804
'if-tag-error11': ("{% if 1 == %}yes{% endif %}", {}, template.TemplateSyntaxError),
805
'if-tag-error12': ("{% if a not b %}yes{% endif %}", {}, template.TemplateSyntaxError),
807
# If evaluations are shortcircuited where possible
808
# These tests will fail by taking too long to run. When the if clause
809
# is shortcircuiting correctly, the is_bad() function shouldn't be
810
# evaluated, and the deliberate sleep won't happen.
811
'if-tag-shortcircuit01': ('{% if x.is_true or x.is_bad %}yes{% else %}no{% endif %}', {'x': TestObj()}, "yes"),
812
'if-tag-shortcircuit02': ('{% if x.is_false and x.is_bad %}yes{% else %}no{% endif %}', {'x': TestObj()}, "no"),
815
'if-tag-badarg01':("{% if x|default_if_none:y %}yes{% endif %}", {}, ''),
816
'if-tag-badarg02':("{% if x|default_if_none:y %}yes{% endif %}", {'y': 0}, ''),
817
'if-tag-badarg03':("{% if x|default_if_none:y %}yes{% endif %}", {'y': 1}, 'yes'),
818
'if-tag-badarg04':("{% if x|default_if_none:y %}yes{% else %}no{% endif %}", {}, 'no'),
820
# Additional, more precise parsing tests are in SmartIfTests
609
822
### IFCHANGED TAG #########################################################
610
823
'ifchanged01': ('{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}', {'num': (1,2,3)}, '123'),
802
1015
# Inheritance from a template with a space in its name should work.
803
1016
'inheritance29': ("{% extends 'inheritance 28' %}", {}, '!'),
1018
# Base template, putting block in a conditional {% if %} tag
1019
'inheritance30': ("1{% if optional %}{% block opt %}2{% endblock %}{% endif %}3", {'optional': True}, '123'),
1021
# Inherit from a template with block wrapped in an {% if %} tag (in parent), still gets overridden
1022
'inheritance31': ("{% extends 'inheritance30' %}{% block opt %}two{% endblock %}", {'optional': True}, '1two3'),
1023
'inheritance32': ("{% extends 'inheritance30' %}{% block opt %}two{% endblock %}", {}, '13'),
1025
# Base template, putting block in a conditional {% ifequal %} tag
1026
'inheritance33': ("1{% ifequal optional 1 %}{% block opt %}2{% endblock %}{% endifequal %}3", {'optional': 1}, '123'),
1028
# Inherit from a template with block wrapped in an {% ifequal %} tag (in parent), still gets overridden
1029
'inheritance34': ("{% extends 'inheritance33' %}{% block opt %}two{% endblock %}", {'optional': 1}, '1two3'),
1030
'inheritance35': ("{% extends 'inheritance33' %}{% block opt %}two{% endblock %}", {'optional': 2}, '13'),
1032
# Base template, putting block in a {% for %} tag
1033
'inheritance36': ("{% for n in numbers %}_{% block opt %}{{ n }}{% endblock %}{% endfor %}_", {'numbers': '123'}, '_1_2_3_'),
1035
# Inherit from a template with block wrapped in an {% for %} tag (in parent), still gets overridden
1036
'inheritance37': ("{% extends 'inheritance36' %}{% block opt %}X{% endblock %}", {'numbers': '123'}, '_X_X_X_'),
1037
'inheritance38': ("{% extends 'inheritance36' %}{% block opt %}X{% endblock %}", {}, '_'),
1039
# The super block will still be found.
1040
'inheritance39': ("{% extends 'inheritance30' %}{% block opt %}new{{ block.super }}{% endblock %}", {'optional': True}, '1new23'),
1041
'inheritance40': ("{% extends 'inheritance33' %}{% block opt %}new{{ block.super }}{% endblock %}", {'optional': 1}, '1new23'),
1042
'inheritance41': ("{% extends 'inheritance36' %}{% block opt %}new{{ block.super }}{% endblock %}", {'numbers': '123'}, '_new1_new2_new3_'),
805
1044
### I18N ##################################################################
807
1046
# {% spaceless %} tag
860
1099
'i18n21': ('{% load i18n %}{% blocktrans %}{{ andrew }}{% endblocktrans %}', {'andrew': mark_safe('a & b')}, u'a & b'),
861
1100
'i18n22': ('{% load i18n %}{% trans andrew %}', {'andrew': mark_safe('a & b')}, u'a & b'),
1102
# Use filters with the {% trans %} tag, #5972
1103
'i18n23': ('{% load i18n %}{% trans "Page not found"|capfirst|slice:"6:" %}', {'LANGUAGE_CODE': 'de'}, u'nicht gefunden'),
1104
'i18n24': ("{% load i18n %}{% trans 'Page not found'|upper %}", {'LANGUAGE_CODE': 'de'}, u'SEITE NICHT GEFUNDEN'),
1105
'i18n25': ('{% load i18n %}{% trans somevar|upper %}', {'somevar': 'Page not found', 'LANGUAGE_CODE': 'de'}, u'SEITE NICHT GEFUNDEN'),
863
1107
### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
865
1109
'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')),
969
1213
### URL TAG ########################################################
1215
'legacyurl02': ('{% url regressiontests.templates.views.client_action id=client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
1216
'legacyurl02a': ('{% url regressiontests.templates.views.client_action client.id,"update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
1217
'legacyurl02b': ("{% url regressiontests.templates.views.client_action id=client.id,action='update' %}", {'client': {'id': 1}}, '/url_tag/client/1/update/'),
1218
'legacyurl02c': ("{% url regressiontests.templates.views.client_action client.id,'update' %}", {'client': {'id': 1}}, '/url_tag/client/1/update/'),
1219
'legacyurl10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'),
1220
'legacyurl13': ('{% url regressiontests.templates.views.client_action id=client.id, action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
1221
'legacyurl14': ('{% url regressiontests.templates.views.client_action client.id, arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
1222
'legacyurl16': ('{% url regressiontests.templates.views.client_action action="update",id="1" %}', {}, '/url_tag/client/1/update/'),
1223
'legacyurl16a': ("{% url regressiontests.templates.views.client_action action='update',id='1' %}", {}, '/url_tag/client/1/update/'),
1224
'legacyurl17': ('{% url regressiontests.templates.views.client_action client_id=client.my_id,action=action %}', {'client': {'my_id': 1}, 'action': 'update'}, '/url_tag/client/1/update/'),
971
1226
'url01': ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'),
972
'url02': ('{% url regressiontests.templates.views.client_action id=client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
973
'url02a': ('{% url regressiontests.templates.views.client_action client.id,"update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
1227
'url02': ('{% url regressiontests.templates.views.client_action id=client.id action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
1228
'url02a': ('{% url regressiontests.templates.views.client_action client.id "update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
1229
'url02b': ("{% url regressiontests.templates.views.client_action id=client.id action='update' %}", {'client': {'id': 1}}, '/url_tag/client/1/update/'),
1230
'url02c': ("{% url regressiontests.templates.views.client_action client.id 'update' %}", {'client': {'id': 1}}, '/url_tag/client/1/update/'),
974
1231
'url03': ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'),
975
1232
'url04': ('{% url named.client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'),
976
1233
'url05': (u'{% url метка_оператора v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
978
1235
'url07': (u'{% url regressiontests.templates.views.client2 tag=v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
979
1236
'url08': (u'{% url метка_оператора v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
980
1237
'url09': (u'{% url метка_оператора_2 tag=v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
981
'url10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'),
1238
'url10': ('{% url regressiontests.templates.views.client_action id=client.id action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'),
1239
'url11': ('{% url regressiontests.templates.views.client_action id=client.id action="==" %}', {'client': {'id': 1}}, '/url_tag/client/1/==/'),
1240
'url12': ('{% url regressiontests.templates.views.client_action id=client.id action="," %}', {'client': {'id': 1}}, '/url_tag/client/1/,/'),
1241
'url13': ('{% url regressiontests.templates.views.client_action id=client.id action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
1242
'url14': ('{% url regressiontests.templates.views.client_action client.id arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
1243
'url15': ('{% url regressiontests.templates.views.client_action 12 "test" %}', {}, '/url_tag/client/12/test/'),
1244
'url18': ('{% url regressiontests.templates.views.client "1,2" %}', {}, '/url_tag/client/1,2/'),
984
1247
'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
985
1248
'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch),
986
1249
'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch),
1250
'url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError),
1251
'url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError),
1252
'url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError),
1253
'url-fail07': ('{% url view a.id!id %}', {}, template.TemplateSyntaxError),
1254
'url-fail08': ('{% url view id="unterminatedstring %}', {}, template.TemplateSyntaxError),
1255
'url-fail09': ('{% url view id=", %}', {}, template.TemplateSyntaxError),
988
1257
# {% url ... as var %}
989
1258
'url-asvar01': ('{% url regressiontests.templates.views.index as url %}', {}, ''),
1047
1316
'autoescape-filtertag01': ("{{ first }}{% filter safe %}{{ first }} x<y{% endfilter %}", {"first": "<a>"}, template.TemplateSyntaxError),
1320
class TemplateTagLoading(unittest.TestCase):
1323
self.old_path = sys.path
1324
self.old_apps = settings.INSTALLED_APPS
1325
self.egg_dir = '%s/eggs' % os.path.dirname(__file__)
1326
self.old_tag_modules = template.templatetags_modules
1327
template.templatetags_modules = []
1330
settings.INSTALLED_APPS = self.old_apps
1331
sys.path = self.old_path
1332
template.templatetags_modules = self.old_tag_modules
1334
def test_load_error(self):
1335
ttext = "{% load broken_tag %}"
1336
self.assertRaises(template.TemplateSyntaxError, template.Template, ttext)
1338
template.Template(ttext)
1339
except template.TemplateSyntaxError, e:
1340
self.assertTrue('ImportError' in e.args[0])
1341
self.assertTrue('Xtemplate' in e.args[0])
1343
def test_load_error_egg(self):
1344
ttext = "{% load broken_egg %}"
1345
egg_name = '%s/tagsegg.egg' % self.egg_dir
1346
sys.path.append(egg_name)
1347
settings.INSTALLED_APPS = ('tagsegg',)
1348
self.assertRaises(template.TemplateSyntaxError, template.Template, ttext)
1350
template.Template(ttext)
1351
except template.TemplateSyntaxError, e:
1352
self.assertTrue('ImportError' in e.args[0])
1353
self.assertTrue('Xtemplate' in e.args[0])
1355
def test_load_working_egg(self):
1356
ttext = "{% load working_egg %}"
1357
egg_name = '%s/tagsegg.egg' % self.egg_dir
1358
sys.path.append(egg_name)
1359
settings.INSTALLED_APPS = ('tagsegg',)
1360
t = template.Template(ttext)
1050
1362
if __name__ == "__main__":
1051
1363
unittest.main()