From fb267a1d85c22924231be8cec6c58c42ae57913f Mon Sep 17 00:00:00 2001 From: Preston Timmons Date: Sat, 11 Apr 2015 19:41:45 -0400 Subject: [PATCH] Updated template tests to create their own engine. This continues work to treat Django templates as a library. --- .../template_tests/syntax_tests/test_cache.py | 15 ++-- .../syntax_tests/test_if_changed.py | 14 ++- .../syntax_tests/test_include.py | 89 +++++-------------- .../template_tests/templatetags/inclusion.py | 22 ++--- tests/template_tests/test_callables.py | 31 ++++--- tests/template_tests/test_context.py | 23 ++--- tests/template_tests/test_custom.py | 50 ++++++----- tests/template_tests/test_logging.py | 4 +- tests/template_tests/test_nodelist.py | 20 +++-- tests/template_tests/test_unicode.py | 11 +-- tests/template_tests/tests.py | 45 +++++----- 11 files changed, 153 insertions(+), 171 deletions(-) diff --git a/tests/template_tests/syntax_tests/test_cache.py b/tests/template_tests/syntax_tests/test_cache.py index 1742b7111c..f088510d5d 100644 --- a/tests/template_tests/syntax_tests/test_cache.py +++ b/tests/template_tests/syntax_tests/test_cache.py @@ -1,5 +1,5 @@ from django.core.cache import cache -from django.template import Context, Template, TemplateSyntaxError +from django.template import Context, Engine, TemplateSyntaxError from django.test import SimpleTestCase, override_settings from ..utils import setup @@ -119,8 +119,13 @@ class CacheTagTests(SimpleTestCase): class CacheTests(SimpleTestCase): + @classmethod + def setUpClass(cls): + cls.engine = Engine() + super(CacheTests, cls).setUpClass() + def test_cache_regression_20130(self): - t = Template('{% load cache %}{% cache 1 regression_20130 %}foo{% endcache %}') + t = self.engine.from_string('{% load cache %}{% cache 1 regression_20130 %}foo{% endcache %}') cachenode = t.nodelist[1] self.assertEqual(cachenode.fragment_name, 'regression_20130') @@ -139,8 +144,8 @@ class CacheTests(SimpleTestCase): When a cache called "template_fragments" is present, the cache tag will use it in preference to 'default' """ - t1 = Template('{% load cache %}{% cache 1 fragment %}foo{% endcache %}') - t2 = Template('{% load cache %}{% cache 1 fragment using="default" %}bar{% endcache %}') + t1 = self.engine.from_string('{% load cache %}{% cache 1 fragment %}foo{% endcache %}') + t2 = self.engine.from_string('{% load cache %}{% cache 1 fragment using="default" %}bar{% endcache %}') ctx = Context() o1 = t1.render(ctx) @@ -154,7 +159,7 @@ class CacheTests(SimpleTestCase): When a cache that doesn't exist is specified, the cache tag will raise a TemplateSyntaxError '""" - t = Template('{% load cache %}{% cache 1 backend using="unknown" %}bar{% endcache %}') + t = self.engine.from_string('{% load cache %}{% cache 1 backend using="unknown" %}bar{% endcache %}') ctx = Context() with self.assertRaises(TemplateSyntaxError): diff --git a/tests/template_tests/syntax_tests/test_if_changed.py b/tests/template_tests/syntax_tests/test_if_changed.py index b06c0bbdd9..62f9563020 100644 --- a/tests/template_tests/syntax_tests/test_if_changed.py +++ b/tests/template_tests/syntax_tests/test_if_changed.py @@ -1,4 +1,4 @@ -from django.template import Context, Template +from django.template import Context, Engine from django.test import SimpleTestCase from ..utils import setup @@ -157,11 +157,19 @@ class IfChangedTagTests(SimpleTestCase): class IfChangedTests(SimpleTestCase): + @classmethod + def setUpClass(cls): + cls.engine = Engine() + super(IfChangedTests, cls).setUpClass() + def test_ifchanged_concurrency(self): """ #15849 -- ifchanged should be thread-safe. """ - template = Template('[0{% for x in foo %},{% with var=get_value %}{% ifchanged %}{{ var }}{% endifchanged %}{% endwith %}{% endfor %}]') + template = self.engine.from_string( + '[0{% for x in foo %},{% with var=get_value %}{% ifchanged %}' + '{{ var }}{% endifchanged %}{% endwith %}{% endfor %}]' + ) # Using generator to mimic concurrency. # The generator is not passed to the 'for' loop, because it does a list(values) @@ -184,6 +192,6 @@ class IfChangedTests(SimpleTestCase): """ #19890. The content of ifchanged template tag was rendered twice. """ - template = Template('{% ifchanged %}{% cycle "1st time" "2nd time" %}{% endifchanged %}') + template = self.engine.from_string('{% ifchanged %}{% cycle "1st time" "2nd time" %}{% endifchanged %}') output = template.render(Context({})) self.assertEqual(output, '1st time') diff --git a/tests/template_tests/syntax_tests/test_include.py b/tests/template_tests/syntax_tests/test_include.py index ecd3d59c29..5a05b32c33 100644 --- a/tests/template_tests/syntax_tests/test_include.py +++ b/tests/template_tests/syntax_tests/test_include.py @@ -1,7 +1,7 @@ from django.template import ( - Context, Template, TemplateDoesNotExist, TemplateSyntaxError, engines, + Context, Engine, TemplateDoesNotExist, TemplateSyntaxError, ) -from django.test import SimpleTestCase, override_settings +from django.test import SimpleTestCase from ..utils import setup from .test_basic import basic_templates @@ -205,110 +205,69 @@ class IncludeTagTests(SimpleTestCase): class IncludeTests(SimpleTestCase): - # Test the base loader class via the app loader. load_template - # from base is used by all shipped loaders excepting cached, - # which has its own test. - @override_settings(TEMPLATES=[{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'APP_DIRS': True, - 'OPTIONS': { - # Enable debug, otherwise the exception raised during - # {% include %} processing will be suppressed. - 'debug': True, - } - }]) def test_include_missing_template(self): """ Tests that the correct template is identified as not existing when {% include %} specifies a template that does not exist. """ - template = engines['django'].get_template('test_include_error.html') + engine = Engine(app_dirs=True, debug=True) + template = engine.get_template('test_include_error.html') with self.assertRaises(TemplateDoesNotExist) as e: - template.render() + template.render(Context()) self.assertEqual(e.exception.args[0], 'missing.html') - # Test the base loader class via the app loader. load_template - # from base is used by all shipped loaders excepting cached, - # which has its own test. - @override_settings(TEMPLATES=[{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'APP_DIRS': True, - 'OPTIONS': { - # Enable debug, otherwise the exception raised during - # {% include %} processing will be suppressed. - 'debug': True, - } - }]) def test_extends_include_missing_baseloader(self): """ #12787 -- Tests that the correct template is identified as not existing when {% extends %} specifies a template that does exist, but that template has an {% include %} of something that does not exist. """ - template = engines['django'].get_template('test_extends_error.html') + engine = Engine(app_dirs=True, debug=True) + template = engine.get_template('test_extends_error.html') with self.assertRaises(TemplateDoesNotExist) as e: - template.render() + template.render(Context()) self.assertEqual(e.exception.args[0], 'missing.html') - @override_settings(TEMPLATES=[{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'OPTIONS': { - 'debug': True, - 'loaders': [ - ('django.template.loaders.cached.Loader', [ - 'django.template.loaders.app_directories.Loader', - ]), - ], - }, - }]) def test_extends_include_missing_cachedloader(self): """ Test the cache loader separately since it overrides load_template. """ + engine = Engine(debug=True, loaders=[ + ('django.template.loaders.cached.Loader', [ + 'django.template.loaders.app_directories.Loader', + ]), + ]) - template = engines['django'].get_template('test_extends_error.html') + template = engine.get_template('test_extends_error.html') with self.assertRaises(TemplateDoesNotExist) as e: - template.render() + template.render(Context()) self.assertEqual(e.exception.args[0], 'missing.html') # Repeat to ensure it still works when loading from the cache - template = engines['django'].get_template('test_extends_error.html') + template = engine.get_template('test_extends_error.html') with self.assertRaises(TemplateDoesNotExist) as e: - template.render() + template.render(Context()) self.assertEqual(e.exception.args[0], 'missing.html') def test_include_template_argument(self): """ Support any render() supporting object """ + engine = Engine() ctx = Context({ - 'tmpl': Template('This worked!'), + 'tmpl': engine.from_string('This worked!'), }) - outer_tmpl = Template('{% include tmpl %}') + outer_tmpl = engine.from_string('{% include tmpl %}') output = outer_tmpl.render(ctx) self.assertEqual(output, 'This worked!') - @override_settings(TEMPLATES=[{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'OPTIONS': { - 'debug': True, - }, - }]) def test_include_immediate_missing(self): """ #16417 -- Include tags pointing to missing templates should not raise an error at parsing time. """ - template = Template('{% include "this_does_not_exist.html" %}') - self.assertIsInstance(template, Template) + Engine(debug=True).from_string('{% include "this_does_not_exist.html" %}') - @override_settings(TEMPLATES=[{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'APP_DIRS': True, - 'OPTIONS': { - 'debug': True, - }, - }]) def test_include_recursive(self): comments = [ { @@ -322,9 +281,9 @@ class IncludeTests(SimpleTestCase): ] } ] - - t = engines['django'].get_template('recursive_include.html') + engine = Engine(app_dirs=True) + t = engine.get_template('recursive_include.html') self.assertEqual( "Recursion! A1 Recursion! B1 B2 B3 Recursion! C1", - t.render({'comments': comments}).replace(' ', '').replace('\n', ' ').strip(), + t.render(Context({'comments': comments})).replace(' ', '').replace('\n', ' ').strip(), ) diff --git a/tests/template_tests/templatetags/inclusion.py b/tests/template_tests/templatetags/inclusion.py index 1631ce92b9..54cc81abe3 100644 --- a/tests/template_tests/templatetags/inclusion.py +++ b/tests/template_tests/templatetags/inclusion.py @@ -1,9 +1,9 @@ import operator -from django.template import Library -from django.template.loader import get_template +from django.template import Engine, Library from django.utils import six +engine = Engine(app_dirs=True) register = Library() @@ -14,7 +14,7 @@ def inclusion_no_params(): inclusion_no_params.anything = "Expected inclusion_no_params __dict__" -@register.inclusion_tag(get_template('inclusion.html')) +@register.inclusion_tag(engine.get_template('inclusion.html')) def inclusion_no_params_from_template(): """Expected inclusion_no_params_from_template __doc__""" return {"result": "inclusion_no_params_from_template - Expected result"} @@ -28,7 +28,7 @@ def inclusion_one_param(arg): inclusion_one_param.anything = "Expected inclusion_one_param __dict__" -@register.inclusion_tag(get_template('inclusion.html')) +@register.inclusion_tag(engine.get_template('inclusion.html')) def inclusion_one_param_from_template(arg): """Expected inclusion_one_param_from_template __doc__""" return {"result": "inclusion_one_param_from_template - Expected result: %s" % arg} @@ -42,7 +42,7 @@ def inclusion_explicit_no_context(arg): inclusion_explicit_no_context.anything = "Expected inclusion_explicit_no_context __dict__" -@register.inclusion_tag(get_template('inclusion.html'), takes_context=False) +@register.inclusion_tag(engine.get_template('inclusion.html'), takes_context=False) def inclusion_explicit_no_context_from_template(arg): """Expected inclusion_explicit_no_context_from_template __doc__""" return {"result": "inclusion_explicit_no_context_from_template - Expected result: %s" % arg} @@ -56,7 +56,7 @@ def inclusion_no_params_with_context(context): inclusion_no_params_with_context.anything = "Expected inclusion_no_params_with_context __dict__" -@register.inclusion_tag(get_template('inclusion.html'), takes_context=True) +@register.inclusion_tag(engine.get_template('inclusion.html'), takes_context=True) def inclusion_no_params_with_context_from_template(context): """Expected inclusion_no_params_with_context_from_template __doc__""" return {"result": "inclusion_no_params_with_context_from_template - Expected result (context value: %s)" % context['value']} @@ -70,7 +70,7 @@ def inclusion_params_and_context(context, arg): inclusion_params_and_context.anything = "Expected inclusion_params_and_context __dict__" -@register.inclusion_tag(get_template('inclusion.html'), takes_context=True) +@register.inclusion_tag(engine.get_template('inclusion.html'), takes_context=True) def inclusion_params_and_context_from_template(context, arg): """Expected inclusion_params_and_context_from_template __doc__""" return {"result": "inclusion_params_and_context_from_template - Expected result (context value: %s): %s" % (context['value'], arg)} @@ -84,7 +84,7 @@ def inclusion_two_params(one, two): inclusion_two_params.anything = "Expected inclusion_two_params __dict__" -@register.inclusion_tag(get_template('inclusion.html')) +@register.inclusion_tag(engine.get_template('inclusion.html')) def inclusion_two_params_from_template(one, two): """Expected inclusion_two_params_from_template __doc__""" return {"result": "inclusion_two_params_from_template - Expected result: %s, %s" % (one, two)} @@ -98,7 +98,7 @@ def inclusion_one_default(one, two='hi'): inclusion_one_default.anything = "Expected inclusion_one_default __dict__" -@register.inclusion_tag(get_template('inclusion.html')) +@register.inclusion_tag(engine.get_template('inclusion.html')) def inclusion_one_default_from_template(one, two='hi'): """Expected inclusion_one_default_from_template __doc__""" return {"result": "inclusion_one_default_from_template - Expected result: %s, %s" % (one, two)} @@ -112,7 +112,7 @@ def inclusion_unlimited_args(one, two='hi', *args): inclusion_unlimited_args.anything = "Expected inclusion_unlimited_args __dict__" -@register.inclusion_tag(get_template('inclusion.html')) +@register.inclusion_tag(engine.get_template('inclusion.html')) def inclusion_unlimited_args_from_template(one, two='hi', *args): """Expected inclusion_unlimited_args_from_template __doc__""" return {"result": "inclusion_unlimited_args_from_template - Expected result: %s" % (', '.join(six.text_type(arg) for arg in [one, two] + list(args)))} @@ -126,7 +126,7 @@ def inclusion_only_unlimited_args(*args): inclusion_only_unlimited_args.anything = "Expected inclusion_only_unlimited_args __dict__" -@register.inclusion_tag(get_template('inclusion.html')) +@register.inclusion_tag(engine.get_template('inclusion.html')) def inclusion_only_unlimited_args_from_template(*args): """Expected inclusion_only_unlimited_args_from_template __doc__""" return {"result": "inclusion_only_unlimited_args_from_template - Expected result: %s" % (', '.join(six.text_type(arg) for arg in args))} diff --git a/tests/template_tests/test_callables.py b/tests/template_tests/test_callables.py index 5536b382ff..b7ce294403 100644 --- a/tests/template_tests/test_callables.py +++ b/tests/template_tests/test_callables.py @@ -2,11 +2,16 @@ from __future__ import unicode_literals from unittest import TestCase -from django import template +from django.template import Context, Engine class CallableVariablesTests(TestCase): + @classmethod + def setUpClass(cls): + cls.engine = Engine() + super(CallableVariablesTests, cls).setUpClass() + def test_callable(self): class Doodad(object): @@ -19,12 +24,12 @@ class CallableVariablesTests(TestCase): return {"the_value": self.value} my_doodad = Doodad(42) - c = template.Context({"my_doodad": my_doodad}) + c = Context({"my_doodad": my_doodad}) # We can't access ``my_doodad.value`` in the template, because # ``my_doodad.__call__`` will be invoked first, yielding a dictionary # without a key ``value``. - t = template.Template('{{ my_doodad.value }}') + t = self.engine.from_string('{{ my_doodad.value }}') self.assertEqual(t.render(c), '') # We can confirm that the doodad has been called @@ -32,7 +37,7 @@ class CallableVariablesTests(TestCase): # But we can access keys on the dict that's returned # by ``__call__``, instead. - t = template.Template('{{ my_doodad.the_value }}') + t = self.engine.from_string('{{ my_doodad.the_value }}') self.assertEqual(t.render(c), '42') self.assertEqual(my_doodad.num_calls, 2) @@ -50,13 +55,13 @@ class CallableVariablesTests(TestCase): return {"the_value": self.value} my_doodad = Doodad(42) - c = template.Context({"my_doodad": my_doodad}) + c = Context({"my_doodad": my_doodad}) # Since ``my_doodad.alters_data`` is True, the template system will not # try to call our doodad but will use string_if_invalid - t = template.Template('{{ my_doodad.value }}') + t = self.engine.from_string('{{ my_doodad.value }}') self.assertEqual(t.render(c), '') - t = template.Template('{{ my_doodad.the_value }}') + t = self.engine.from_string('{{ my_doodad.the_value }}') self.assertEqual(t.render(c), '') # Double-check that the object was really never called during the @@ -77,15 +82,15 @@ class CallableVariablesTests(TestCase): return {"the_value": self.value} my_doodad = Doodad(42) - c = template.Context({"my_doodad": my_doodad}) + c = Context({"my_doodad": my_doodad}) # Since ``my_doodad.do_not_call_in_templates`` is True, the template # system will not try to call our doodad. We can access its attributes # as normal, and we don't have access to the dict that it returns when # called. - t = template.Template('{{ my_doodad.value }}') + t = self.engine.from_string('{{ my_doodad.value }}') self.assertEqual(t.render(c), '42') - t = template.Template('{{ my_doodad.the_value }}') + t = self.engine.from_string('{{ my_doodad.the_value }}') self.assertEqual(t.render(c), '') # Double-check that the object was really never called during the @@ -110,11 +115,11 @@ class CallableVariablesTests(TestCase): return {"the_value": self.value} my_doodad = Doodad(42) - c = template.Context({"my_doodad": my_doodad}) + c = Context({"my_doodad": my_doodad}) - t = template.Template('{{ my_doodad.value }}') + t = self.engine.from_string('{{ my_doodad.value }}') self.assertEqual(t.render(c), '42') - t = template.Template('{{ my_doodad.the_value }}') + t = self.engine.from_string('{{ my_doodad.the_value }}') self.assertEqual(t.render(c), '') # Double-check that the object was really never called during the diff --git a/tests/template_tests/test_context.py b/tests/template_tests/test_context.py index f7959e6415..9440f218cd 100644 --- a/tests/template_tests/test_context.py +++ b/tests/template_tests/test_context.py @@ -2,10 +2,10 @@ from django.http import HttpRequest from django.template import ( - Context, RequestContext, Template, Variable, VariableDoesNotExist, + Context, Engine, RequestContext, Variable, VariableDoesNotExist, ) from django.template.context import RenderContext -from django.test import RequestFactory, SimpleTestCase, override_settings +from django.test import RequestFactory, SimpleTestCase class ContextTests(SimpleTestCase): @@ -131,25 +131,20 @@ class ContextTests(SimpleTestCase): class RequestContextTests(SimpleTestCase): - @override_settings(TEMPLATES=[{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'OPTIONS': { - 'loaders': [ - ('django.template.loaders.locmem.Loader', { - 'child': '{{ var|default:"none" }}', - }), - ], - }, - }]) def test_include_only(self): """ #15721 -- ``{% include %}`` and ``RequestContext`` should work together. """ + engine = Engine(loaders=[ + ('django.template.loaders.locmem.Loader', { + 'child': '{{ var|default:"none" }}', + }), + ]) request = RequestFactory().get('/') ctx = RequestContext(request, {'var': 'parent'}) - self.assertEqual(Template('{% include "child" %}').render(ctx), 'parent') - self.assertEqual(Template('{% include "child" only %}').render(ctx), 'none') + self.assertEqual(engine.from_string('{% include "child" %}').render(ctx), 'parent') + self.assertEqual(engine.from_string('{% include "child" only %}').render(ctx), 'none') def test_stack_size(self): """ diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index fae8fc4e0b..b5c125c61c 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import os -from django.template import Context, Engine, Template, TemplateSyntaxError +from django.template import Context, Engine, TemplateSyntaxError from django.template.base import Node from django.test import SimpleTestCase, ignore_warnings from django.test.utils import extend_sys_path @@ -15,7 +15,7 @@ from .utils import ROOT class CustomFilterTests(SimpleTestCase): def test_filter(self): - t = Template("{% load custom %}{{ string|trim:5 }}") + t = Engine().from_string("{% load custom %}{{ string|trim:5 }}") self.assertEqual( t.render(Context({"string": "abcdefghijklmnopqrstuvwxyz"})), "abcde" @@ -24,6 +24,11 @@ class CustomFilterTests(SimpleTestCase): class TagTestCase(SimpleTestCase): + @classmethod + def setUpClass(cls): + cls.engine = Engine(app_dirs=True) + super(TagTestCase, cls).setUpClass() + def verify_tag(self, tag, name): self.assertEqual(tag.__name__, name) self.assertEqual(tag.__doc__, 'Expected %s __doc__' % name) @@ -62,11 +67,11 @@ class SimpleTagTests(TagTestCase): ] for entry in templates: - t = Template(entry[0]) + t = self.engine.from_string(entry[0]) self.assertEqual(t.render(c), entry[1]) for entry in templates: - t = Template("%s as var %%}Result: {{ var }}" % entry[0][0:-2]) + t = self.engine.from_string("%s as var %%}Result: {{ var }}" % entry[0][0:-2]) self.assertEqual(t.render(c), "Result: %s" % entry[1]) def test_simple_tag_errors(self): @@ -85,11 +90,11 @@ class SimpleTagTests(TagTestCase): for entry in errors: with self.assertRaisesMessage(TemplateSyntaxError, entry[0]): - Template(entry[1]) + self.engine.from_string(entry[1]) for entry in errors: with self.assertRaisesMessage(TemplateSyntaxError, entry[0]): - Template("%s as var %%}" % entry[1][0:-2]) + self.engine.from_string("%s as var %%}" % entry[1][0:-2]) def test_simple_tag_registration(self): # Test that the decorators preserve the decorated function's docstring, name and attributes. @@ -108,7 +113,7 @@ class SimpleTagTests(TagTestCase): "takes_context=True so it must have a first argument of 'context'" ) with self.assertRaisesMessage(TemplateSyntaxError, msg): - Template('{% load custom %}{% simple_tag_without_context_parameter 123 %}') + self.engine.from_string('{% load custom %}{% simple_tag_without_context_parameter 123 %}') class InclusionTagTests(TagTestCase): @@ -147,7 +152,7 @@ class InclusionTagTests(TagTestCase): ] for entry in templates: - t = Template(entry[0]) + t = self.engine.from_string(entry[0]) self.assertEqual(t.render(c), entry[1]) def test_inclusion_tag_errors(self): @@ -173,7 +178,7 @@ class InclusionTagTests(TagTestCase): for entry in errors: with self.assertRaisesMessage(TemplateSyntaxError, entry[0]): - Template(entry[1]) + self.engine.from_string(entry[1]) def test_include_tag_missing_context(self): # The 'context' parameter must be present when takes_context is True @@ -182,7 +187,7 @@ class InclusionTagTests(TagTestCase): "takes_context=True so it must have a first argument of 'context'" ) with self.assertRaisesMessage(TemplateSyntaxError, msg): - Template('{% load inclusion %}{% inclusion_tag_without_context_parameter 123 %}') + self.engine.from_string('{% load inclusion %}{% inclusion_tag_without_context_parameter 123 %}') def test_inclusion_tags_from_template(self): c = Context({'value': 42}) @@ -215,7 +220,7 @@ class InclusionTagTests(TagTestCase): ] for entry in templates: - t = Template(entry[0]) + t = self.engine.from_string(entry[0]) self.assertEqual(t.render(c), entry[1]) def test_inclusion_tag_registration(self): @@ -241,7 +246,7 @@ class InclusionTagTests(TagTestCase): Context of the included/rendered template as well. """ c = Context({}) - t = Template('{% load inclusion %}{% inclusion_tag_current_app %}') + t = self.engine.from_string('{% load inclusion %}{% inclusion_tag_current_app %}') self.assertEqual(t.render(c).strip(), 'None') # That part produces the deprecation warning @@ -254,7 +259,7 @@ class InclusionTagTests(TagTestCase): Context of the included/rendered template as well. """ c = Context({}) - t = Template('{% load inclusion %}{% inclusion_tag_use_l10n %}') + t = self.engine.from_string('{% load inclusion %}{% inclusion_tag_use_l10n %}') self.assertEqual(t.render(c).strip(), 'None') c.use_l10n = True @@ -286,7 +291,7 @@ class AssignmentTagTests(TagTestCase): def test_assignment_tags(self): c = Context({'value': 42}) - t = Template('{% load custom %}{% assignment_no_params as var %}The result is: {{ var }}') + t = self.engine.from_string('{% load custom %}{% assignment_no_params as var %}The result is: {{ var }}') self.assertEqual(t.render(c), 'The result is: assignment_no_params - Expected result') def test_assignment_tag_registration(self): @@ -300,18 +305,21 @@ class AssignmentTagTests(TagTestCase): "takes_context=True so it must have a first argument of 'context'" ) with self.assertRaisesMessage(TemplateSyntaxError, msg): - Template('{% load custom %}{% assignment_tag_without_context_parameter 123 as var %}') + self.engine.from_string('{% load custom %}{% assignment_tag_without_context_parameter 123 as var %}') class TemplateTagLoadingTests(SimpleTestCase): - def setUp(self): - self.egg_dir = os.path.join(ROOT, 'eggs') + @classmethod + def setUpClass(cls): + cls.egg_dir = os.path.join(ROOT, 'eggs') + cls.engine = Engine() + super(TemplateTagLoadingTests, cls).setUpClass() def test_load_error(self): ttext = "{% load broken_tag %}" with self.assertRaises(TemplateSyntaxError) as e: - Template(ttext) + self.engine.from_string(ttext) self.assertIn('ImportError', e.exception.args[0]) self.assertIn('Xtemplate', e.exception.args[0]) @@ -322,10 +330,10 @@ class TemplateTagLoadingTests(SimpleTestCase): with extend_sys_path(egg_name): with self.assertRaises(TemplateSyntaxError): with self.settings(INSTALLED_APPS=['tagsegg']): - Template(ttext) + self.engine.from_string(ttext) try: with self.settings(INSTALLED_APPS=['tagsegg']): - Template(ttext) + self.engine.from_string(ttext) except TemplateSyntaxError as e: self.assertIn('ImportError', e.args[0]) self.assertIn('Xtemplate', e.args[0]) @@ -335,4 +343,4 @@ class TemplateTagLoadingTests(SimpleTestCase): egg_name = '%s/tagsegg.egg' % self.egg_dir with extend_sys_path(egg_name): with self.settings(INSTALLED_APPS=['tagsegg']): - Template(ttext) + self.engine.from_string(ttext) diff --git a/tests/template_tests/test_logging.py b/tests/template_tests/test_logging.py index a8ac82ecba..f6a9bcb672 100644 --- a/tests/template_tests/test_logging.py +++ b/tests/template_tests/test_logging.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import logging -from django.template import Template, Variable, VariableDoesNotExist +from django.template import Engine, Variable, VariableDoesNotExist from django.test import SimpleTestCase @@ -38,7 +38,7 @@ class VariableResolveLoggingTests(SimpleTestCase): @property def template(self): - return Template('') + return Engine().from_string('') @property def article(self): diff --git a/tests/template_tests/test_nodelist.py b/tests/template_tests/test_nodelist.py index fd21d828af..3f28aff92c 100644 --- a/tests/template_tests/test_nodelist.py +++ b/tests/template_tests/test_nodelist.py @@ -1,29 +1,33 @@ from unittest import TestCase -from django.template import Context, Template +from django.template import Context, Engine from django.template.base import VariableNode -from django.test import override_settings class NodelistTest(TestCase): + @classmethod + def setUpClass(cls): + cls.engine = Engine() + super(NodelistTest, cls).setUpClass() + def test_for(self): - template = Template('{% for i in 1 %}{{ a }}{% endfor %}') + template = self.engine.from_string('{% for i in 1 %}{{ a }}{% endfor %}') vars = template.nodelist.get_nodes_by_type(VariableNode) self.assertEqual(len(vars), 1) def test_if(self): - template = Template('{% if x %}{{ a }}{% endif %}') + template = self.engine.from_string('{% if x %}{{ a }}{% endif %}') vars = template.nodelist.get_nodes_by_type(VariableNode) self.assertEqual(len(vars), 1) def test_ifequal(self): - template = Template('{% ifequal x y %}{{ a }}{% endifequal %}') + template = self.engine.from_string('{% ifequal x y %}{{ a }}{% endifequal %}') vars = template.nodelist.get_nodes_by_type(VariableNode) self.assertEqual(len(vars), 1) def test_ifchanged(self): - template = Template('{% ifchanged x %}{{ a }}{% endifchanged %}') + template = self.engine.from_string('{% ifchanged x %}{{ a }}{% endifchanged %}') vars = template.nodelist.get_nodes_by_type(VariableNode) self.assertEqual(len(vars), 1) @@ -33,7 +37,6 @@ class ErrorIndexTest(TestCase): Checks whether index of error is calculated correctly in template debugger in for loops. Refs ticket #5831 """ - @override_settings(DEBUG=True) def test_correct_exception_index(self): tests = [ ('{% load bad_tag %}{% for i in range %}{% badsimpletag %}{% endfor %}', (38, 56)), @@ -46,8 +49,9 @@ class ErrorIndexTest(TestCase): 'range': range(5), 'five': 5, }) + engine = Engine(debug=True) for source, expected_error_source_index in tests: - template = Template(source) + template = engine.from_string(source) try: template.render(context) except (RuntimeError, TypeError) as e: diff --git a/tests/template_tests/test_unicode.py b/tests/template_tests/test_unicode.py index b692bfe31c..169f15a6ed 100644 --- a/tests/template_tests/test_unicode.py +++ b/tests/template_tests/test_unicode.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals from unittest import TestCase -from django.template import Context, Template +from django.template import Context, Engine from django.template.base import TemplateEncodingError from django.utils import six from django.utils.safestring import SafeData @@ -12,13 +12,14 @@ from django.utils.safestring import SafeData class UnicodeTests(TestCase): def test_template(self): # Templates can be created from unicode strings. - t1 = Template('ŠĐĆŽćžšđ {{ var }}') + engine = Engine() + t1 = engine.from_string('ŠĐĆŽćžšđ {{ var }}') # Templates can also be created from bytestrings. These are assumed to # be encoded using UTF-8. s = b'\xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91 {{ var }}' - t2 = Template(s) - s = b'\x80\xc5\xc0' - self.assertRaises(TemplateEncodingError, Template, s) + t2 = engine.from_string(s) + with self.assertRaises(TemplateEncodingError): + engine.from_string(b'\x80\xc5\xc0') # Contexts can be constructed from unicode or UTF-8 bytestrings. Context({b"var": b"foo"}) diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py index 6fc6a03972..dec21559ae 100644 --- a/tests/template_tests/tests.py +++ b/tests/template_tests/tests.py @@ -5,37 +5,33 @@ import sys from django.contrib.auth.models import Group from django.core import urlresolvers -from django.template import ( - Context, Engine, Template, TemplateSyntaxError, engines, loader, -) +from django.template import Context, Engine, TemplateSyntaxError from django.test import SimpleTestCase, override_settings class TemplateTests(SimpleTestCase): - @override_settings(DEBUG=True) def test_string_origin(self): - template = Template('string template') + template = Engine().from_string('string template') self.assertEqual(template.origin.source, 'string template') - @override_settings(SETTINGS_MODULE=None, DEBUG=True) + @override_settings(SETTINGS_MODULE=None) def test_url_reverse_no_settings_module(self): - # Regression test for #9005 - t = Template('{% url will_not_match %}') + """ + #9005 -- url tag shouldn't require settings.SETTINGS_MODULE to + be set. + """ + t = Engine(debug=True).from_string('{% url will_not_match %}') c = Context() with self.assertRaises(urlresolvers.NoReverseMatch): t.render(c) - @override_settings( - TEMPLATES=[{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'OPTIONS': {'string_if_invalid': '%s is invalid'}, - }], - SETTINGS_MODULE='also_something', - ) def test_url_reverse_view_name(self): - # Regression test for #19827 - t = Template('{% url will_not_match %}') + """ + #19827 -- url tag should keep original strack trace when reraising + exception. + """ + t = Engine().from_string('{% url will_not_match %}') c = Context() try: t.render(c) @@ -107,9 +103,10 @@ class TemplateTests(SimpleTestCase): """ #18169 -- NoReverseMatch should not be silence in block.super. """ - t = loader.get_template('included_content.html') + engine = Engine(app_dirs=True) + t = engine.get_template('included_content.html') with self.assertRaises(urlresolvers.NoReverseMatch): - t.render() + t.render(Context()) def test_debug_tag_non_ascii(self): """ @@ -117,7 +114,7 @@ class TemplateTests(SimpleTestCase): """ Group.objects.create(name="清風") c1 = Context({"objs": Group.objects.all()}) - t1 = Template('{% debug %}') + t1 = Engine().from_string('{% debug %}') self.assertIn("清風", t1.render(c1)) def test_extends_generic_template(self): @@ -125,8 +122,8 @@ class TemplateTests(SimpleTestCase): #24338 -- Allow extending django.template.backends.django.Template objects. """ - parent = engines['django'].from_string( - '{% block content %}parent{% endblock %}') - child = engines['django'].from_string( + engine = Engine() + parent = engine.from_string('{% block content %}parent{% endblock %}') + child = engine.from_string( '{% extends parent %}{% block content %}child{% endblock %}') - self.assertEqual(child.render({'parent': parent}), 'child') + self.assertEqual(child.render(Context({'parent': parent})), 'child')