diff options
| author | Preston Timmons <prestontimmons@gmail.com> | 2015-05-08 15:10:36 -0500 |
|---|---|---|
| committer | Preston Timmons <prestontimmons@gmail.com> | 2015-05-21 09:12:06 -0500 |
| commit | 655f52491505932ef04264de2bce21a03f3a7cd0 (patch) | |
| tree | c38eca24b887466fc2385fc773ff34247567c732 /tests | |
| parent | 7b8008a078ffdfd18ebbe78fecbb92cdddf2f304 (diff) | |
Fixed #17085, #24783 -- Refactored template library registration.
* Converted the ``libraries`` and ``builtins`` globals of
``django.template.base`` into properties of the Engine class.
* Added a public API for explicit registration of libraries and builtins.
Diffstat (limited to 'tests')
35 files changed, 326 insertions, 79 deletions
diff --git a/tests/template_backends/apps/__init__.py b/tests/template_backends/apps/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template_backends/apps/__init__.py diff --git a/tests/template_backends/apps/good/__init__.py b/tests/template_backends/apps/good/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template_backends/apps/good/__init__.py diff --git a/tests/template_backends/apps/good/templatetags/__init__.py b/tests/template_backends/apps/good/templatetags/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template_backends/apps/good/templatetags/__init__.py diff --git a/tests/template_backends/apps/good/templatetags/empty.py b/tests/template_backends/apps/good/templatetags/empty.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template_backends/apps/good/templatetags/empty.py diff --git a/tests/template_backends/apps/good/templatetags/good_tags.py b/tests/template_backends/apps/good/templatetags/good_tags.py new file mode 100644 index 0000000000..9bec93d8e5 --- /dev/null +++ b/tests/template_backends/apps/good/templatetags/good_tags.py @@ -0,0 +1,3 @@ +from django.template import Library + +register = Library() diff --git a/tests/template_backends/apps/good/templatetags/override.py b/tests/template_backends/apps/good/templatetags/override.py new file mode 100644 index 0000000000..9bec93d8e5 --- /dev/null +++ b/tests/template_backends/apps/good/templatetags/override.py @@ -0,0 +1,3 @@ +from django.template import Library + +register = Library() diff --git a/tests/template_backends/apps/good/templatetags/subpackage/__init__.py b/tests/template_backends/apps/good/templatetags/subpackage/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template_backends/apps/good/templatetags/subpackage/__init__.py diff --git a/tests/template_backends/apps/good/templatetags/subpackage/tags.py b/tests/template_backends/apps/good/templatetags/subpackage/tags.py new file mode 100644 index 0000000000..9bec93d8e5 --- /dev/null +++ b/tests/template_backends/apps/good/templatetags/subpackage/tags.py @@ -0,0 +1,3 @@ +from django.template import Library + +register = Library() diff --git a/tests/template_backends/apps/importerror/__init__.py b/tests/template_backends/apps/importerror/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template_backends/apps/importerror/__init__.py diff --git a/tests/template_backends/apps/importerror/templatetags/__init__.py b/tests/template_backends/apps/importerror/templatetags/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/template_backends/apps/importerror/templatetags/__init__.py diff --git a/tests/template_backends/apps/importerror/templatetags/broken_tags.py b/tests/template_backends/apps/importerror/templatetags/broken_tags.py new file mode 100644 index 0000000000..4f240e5923 --- /dev/null +++ b/tests/template_backends/apps/importerror/templatetags/broken_tags.py @@ -0,0 +1 @@ +import DoesNotExist # noqa diff --git a/tests/template_backends/test_django.py b/tests/template_backends/test_django.py index a8cc0d58b8..2a21b04b5a 100644 --- a/tests/template_backends/test_django.py +++ b/tests/template_backends/test_django.py @@ -2,7 +2,8 @@ from template_tests.test_response import test_processor_name from django.template import RequestContext from django.template.backends.django import DjangoTemplates -from django.test import RequestFactory, ignore_warnings +from django.template.library import InvalidTemplateLibrary +from django.test import RequestFactory, ignore_warnings, override_settings from django.utils.deprecation import RemovedInDjango20Warning from .test_dummy import TemplateStringsTests @@ -51,3 +52,78 @@ class DjangoTemplatesTests(TemplateStringsTests): "the two arguments refer to the same request.") with self.assertRaisesMessage(ValueError, msg): template.render(request_context, other_request) + + @override_settings(INSTALLED_APPS=['template_backends.apps.good']) + def test_templatetag_discovery(self): + engine = DjangoTemplates({ + 'DIRS': [], + 'APP_DIRS': False, + 'NAME': 'django', + 'OPTIONS': { + 'libraries': { + 'alternate': 'template_backends.apps.good.templatetags.good_tags', + 'override': 'template_backends.apps.good.templatetags.good_tags', + }, + }, + }) + + # libraries are discovered from installed applications + self.assertEqual( + engine.engine.libraries['good_tags'], + 'template_backends.apps.good.templatetags.good_tags', + ) + self.assertEqual( + engine.engine.libraries['subpackage.tags'], + 'template_backends.apps.good.templatetags.subpackage.tags', + ) + # libraries are discovered from django.templatetags + self.assertEqual( + engine.engine.libraries['static'], + 'django.templatetags.static', + ) + # libraries passed in OPTIONS are registered + self.assertEqual( + engine.engine.libraries['alternate'], + 'template_backends.apps.good.templatetags.good_tags', + ) + # libraries passed in OPTIONS take precedence over discovered ones + self.assertEqual( + engine.engine.libraries['override'], + 'template_backends.apps.good.templatetags.good_tags', + ) + + @override_settings(INSTALLED_APPS=['template_backends.apps.importerror']) + def test_templatetag_discovery_import_error(self): + """ + Import errors in tag modules should be reraised with a helpful message. + """ + with self.assertRaisesMessage( + InvalidTemplateLibrary, + "ImportError raised when trying to load " + "'template_backends.apps.importerror.templatetags.broken_tags'" + ): + DjangoTemplates({ + 'DIRS': [], + 'APP_DIRS': False, + 'NAME': 'django', + 'OPTIONS': {}, + }) + + def test_builtins_discovery(self): + engine = DjangoTemplates({ + 'DIRS': [], + 'APP_DIRS': False, + 'NAME': 'django', + 'OPTIONS': { + 'builtins': ['template_backends.apps.good.templatetags.good_tags'], + }, + }) + + self.assertEqual( + engine.engine.builtins, [ + 'django.template.defaulttags', + 'django.template.defaultfilters', + 'django.template.loader_tags', + 'template_backends.apps.good.templatetags.good_tags', + ] + ) diff --git a/tests/template_tests/templatetags/broken_tag.py b/tests/template_tests/broken_tag.py index 414dc8412f..414dc8412f 100644 --- a/tests/template_tests/templatetags/broken_tag.py +++ b/tests/template_tests/broken_tag.py diff --git a/tests/template_tests/syntax_tests/test_cache.py b/tests/template_tests/syntax_tests/test_cache.py index f088510d5d..2039e7808c 100644 --- a/tests/template_tests/syntax_tests/test_cache.py +++ b/tests/template_tests/syntax_tests/test_cache.py @@ -6,6 +6,10 @@ from ..utils import setup class CacheTagTests(SimpleTestCase): + libraries = { + 'cache': 'django.templatetags.cache', + 'custom': 'template_tests.templatetags.custom', + } def tearDown(self): cache.clear() @@ -121,7 +125,7 @@ class CacheTests(SimpleTestCase): @classmethod def setUpClass(cls): - cls.engine = Engine() + cls.engine = Engine(libraries={'cache': 'django.templatetags.cache'}) super(CacheTests, cls).setUpClass() def test_cache_regression_20130(self): diff --git a/tests/template_tests/syntax_tests/test_cycle.py b/tests/template_tests/syntax_tests/test_cycle.py index e2edf94c8d..c478faff52 100644 --- a/tests/template_tests/syntax_tests/test_cycle.py +++ b/tests/template_tests/syntax_tests/test_cycle.py @@ -6,6 +6,7 @@ from ..utils import setup class CycleTagTests(SimpleTestCase): + libraries = {'future': 'django.templatetags.future'} @setup({'cycle01': '{% cycle a %}'}) def test_cycle01(self): diff --git a/tests/template_tests/syntax_tests/test_extends.py b/tests/template_tests/syntax_tests/test_extends.py index 1b0ff36a3c..3e65f4bf90 100644 --- a/tests/template_tests/syntax_tests/test_extends.py +++ b/tests/template_tests/syntax_tests/test_extends.py @@ -56,6 +56,7 @@ inheritance_templates = { class InheritanceTests(SimpleTestCase): + libraries = {'testtags': 'template_tests.templatetags.testtags'} @setup(inheritance_templates) def test_inheritance01(self): diff --git a/tests/template_tests/syntax_tests/test_firstof.py b/tests/template_tests/syntax_tests/test_firstof.py index a3c8c83151..79eb381c69 100644 --- a/tests/template_tests/syntax_tests/test_firstof.py +++ b/tests/template_tests/syntax_tests/test_firstof.py @@ -6,6 +6,7 @@ from ..utils import setup class FirstOfTagTests(SimpleTestCase): + libraries = {'future': 'django.templatetags.future'} @setup({'firstof01': '{% firstof a b c %}'}) def test_firstof01(self): diff --git a/tests/template_tests/syntax_tests/test_for.py b/tests/template_tests/syntax_tests/test_for.py index 566b86f3d8..8045ea4990 100644 --- a/tests/template_tests/syntax_tests/test_for.py +++ b/tests/template_tests/syntax_tests/test_for.py @@ -6,6 +6,7 @@ from ..utils import setup class ForTagTests(SimpleTestCase): + libraries = {'custom': 'template_tests.templatetags.custom'} @setup({'for-tag01': '{% for val in values %}{{ val }}{% endfor %}'}) def test_for_tag01(self): diff --git a/tests/template_tests/syntax_tests/test_i18n.py b/tests/template_tests/syntax_tests/test_i18n.py index da53a8c279..1d0f83478a 100644 --- a/tests/template_tests/syntax_tests/test_i18n.py +++ b/tests/template_tests/syntax_tests/test_i18n.py @@ -10,6 +10,10 @@ from ..utils import setup class I18nTagTests(SimpleTestCase): + libraries = { + 'custom': 'template_tests.templatetags.custom', + 'i18n': 'django.templatetags.i18n', + } @setup({'i18n01': '{% load i18n %}{% trans \'xxxyyyxxx\' %}'}) def test_i18n01(self): diff --git a/tests/template_tests/syntax_tests/test_if_changed.py b/tests/template_tests/syntax_tests/test_if_changed.py index 62f9563020..09cdc34a88 100644 --- a/tests/template_tests/syntax_tests/test_if_changed.py +++ b/tests/template_tests/syntax_tests/test_if_changed.py @@ -5,6 +5,7 @@ from ..utils import setup class IfChangedTagTests(SimpleTestCase): + libraries = {'custom': 'template_tests.templatetags.custom'} @setup({'ifchanged01': '{% for n in num %}{% ifchanged %}{{ n }}{% endifchanged %}{% endfor %}'}) def test_ifchanged01(self): diff --git a/tests/template_tests/syntax_tests/test_include.py b/tests/template_tests/syntax_tests/test_include.py index 5a05b32c33..fc1554a17e 100644 --- a/tests/template_tests/syntax_tests/test_include.py +++ b/tests/template_tests/syntax_tests/test_include.py @@ -13,6 +13,7 @@ include_fail_templates = { class IncludeTagTests(SimpleTestCase): + libraries = {'bad_tag': 'template_tests.templatetags.bad_tag'} @setup({'include01': '{% include "basic-syntax01" %}'}, basic_templates) def test_include01(self): diff --git a/tests/template_tests/syntax_tests/test_invalid_string.py b/tests/template_tests/syntax_tests/test_invalid_string.py index 2bb8c71fd1..18520aa7bf 100644 --- a/tests/template_tests/syntax_tests/test_invalid_string.py +++ b/tests/template_tests/syntax_tests/test_invalid_string.py @@ -4,6 +4,7 @@ from ..utils import setup class InvalidStringTests(SimpleTestCase): + libraries = {'i18n': 'django.templatetags.i18n'} @setup({'invalidstr01': '{{ var|default:"Foo" }}'}) def test_invalidstr01(self): diff --git a/tests/template_tests/syntax_tests/test_load.py b/tests/template_tests/syntax_tests/test_load.py index 711a9da632..919bbf1346 100644 --- a/tests/template_tests/syntax_tests/test_load.py +++ b/tests/template_tests/syntax_tests/test_load.py @@ -5,6 +5,10 @@ from ..utils import setup class LoadTagTests(SimpleTestCase): + libraries = { + 'subpackage.echo': 'template_tests.templatetags.subpackage.echo', + 'testtags': 'template_tests.templatetags.testtags', + } @setup({'load01': '{% load testtags subpackage.echo %}{% echo test %} {% echo2 "test" %}'}) def test_load01(self): @@ -42,30 +46,30 @@ class LoadTagTests(SimpleTestCase): # {% load %} tag errors @setup({'load07': '{% load echo other_echo bad_tag from testtags %}'}) def test_load07(self): - with self.assertRaises(TemplateSyntaxError): + msg = "'bad_tag' is not a valid tag or filter in tag library 'testtags'" + with self.assertRaisesMessage(TemplateSyntaxError, msg): self.engine.get_template('load07') @setup({'load08': '{% load echo other_echo bad_tag from %}'}) def test_load08(self): - with self.assertRaises(TemplateSyntaxError): + msg = "'echo' is not a registered tag library. Must be one of:\nsubpackage.echo\ntesttags" + with self.assertRaisesMessage(TemplateSyntaxError, msg): self.engine.get_template('load08') @setup({'load09': '{% load from testtags %}'}) def test_load09(self): - with self.assertRaises(TemplateSyntaxError): + msg = "'from' is not a registered tag library. Must be one of:\nsubpackage.echo\ntesttags" + with self.assertRaisesMessage(TemplateSyntaxError, msg): self.engine.get_template('load09') @setup({'load10': '{% load echo from bad_library %}'}) def test_load10(self): - with self.assertRaises(TemplateSyntaxError): + msg = "'bad_library' is not a registered tag library. Must be one of:\nsubpackage.echo\ntesttags" + with self.assertRaisesMessage(TemplateSyntaxError, msg): self.engine.get_template('load10') - @setup({'load11': '{% load subpackage.echo_invalid %}'}) - def test_load11(self): - with self.assertRaises(TemplateSyntaxError): - self.engine.get_template('load11') - @setup({'load12': '{% load subpackage.missing %}'}) def test_load12(self): - with self.assertRaises(TemplateSyntaxError): + msg = "'subpackage.missing' is not a registered tag library. Must be one of:\nsubpackage.echo\ntesttags" + with self.assertRaisesMessage(TemplateSyntaxError, msg): self.engine.get_template('load12') diff --git a/tests/template_tests/syntax_tests/test_simple_tag.py b/tests/template_tests/syntax_tests/test_simple_tag.py index b89af4c72b..5e6ce4733e 100644 --- a/tests/template_tests/syntax_tests/test_simple_tag.py +++ b/tests/template_tests/syntax_tests/test_simple_tag.py @@ -5,6 +5,7 @@ from ..utils import setup class SimpleTagTests(SimpleTestCase): + libraries = {'custom': 'template_tests.templatetags.custom'} @setup({'simpletag-renamed01': '{% load custom %}{% minusone 7 %}'}) def test_simpletag_renamed01(self): diff --git a/tests/template_tests/syntax_tests/test_static.py b/tests/template_tests/syntax_tests/test_static.py index b646ac2bb8..8ff90f5a5c 100644 --- a/tests/template_tests/syntax_tests/test_static.py +++ b/tests/template_tests/syntax_tests/test_static.py @@ -7,6 +7,7 @@ from ..utils import setup @override_settings(MEDIA_URL="/media/", STATIC_URL="/static/") class StaticTagTests(SimpleTestCase): + libraries = {'static': 'django.templatetags.static'} @setup({'static-prefixtag01': '{% load static %}{% get_static_prefix %}'}) def test_static_prefixtag01(self): diff --git a/tests/template_tests/syntax_tests/test_width_ratio.py b/tests/template_tests/syntax_tests/test_width_ratio.py index 9799b7d6ab..8206b83c58 100644 --- a/tests/template_tests/syntax_tests/test_width_ratio.py +++ b/tests/template_tests/syntax_tests/test_width_ratio.py @@ -6,6 +6,7 @@ from ..utils import setup class WidthRatioTagTests(SimpleTestCase): + libraries = {'custom': 'template_tests.templatetags.custom'} @setup({'widthratio01': '{% widthratio a b 0 %}'}) def test_widthratio01(self): diff --git a/tests/template_tests/templatetags/subpackage/echo_invalid.py b/tests/template_tests/templatetags/subpackage/echo_invalid.py deleted file mode 100644 index 0764b9c8fa..0000000000 --- a/tests/template_tests/templatetags/subpackage/echo_invalid.py +++ /dev/null @@ -1 +0,0 @@ -import nonexistent.module # NOQA diff --git a/tests/template_tests/templatetags/testtags.py b/tests/template_tests/templatetags/testtags.py new file mode 100644 index 0000000000..41b65a2ed1 --- /dev/null +++ b/tests/template_tests/templatetags/testtags.py @@ -0,0 +1,22 @@ +from django.template import Library, Node + +register = Library() + + +class EchoNode(Node): + def __init__(self, contents): + self.contents = contents + + def render(self, context): + return ' '.join(self.contents) + + +@register.tag +def echo(parser, token): + return EchoNode(token.contents.split()[1:]) +register.tag('other_echo', echo) + + +@register.filter +def upper(value): + return value.upper() diff --git a/tests/template_tests/test_custom.py b/tests/template_tests/test_custom.py index b5c125c61c..11c04f870c 100644 --- a/tests/template_tests/test_custom.py +++ b/tests/template_tests/test_custom.py @@ -4,18 +4,26 @@ import os from django.template import Context, Engine, TemplateSyntaxError from django.template.base import Node +from django.template.library import InvalidTemplateLibrary from django.test import SimpleTestCase, ignore_warnings from django.test.utils import extend_sys_path +from django.utils import six from django.utils.deprecation import RemovedInDjango20Warning from .templatetags import custom, inclusion from .utils import ROOT +LIBRARIES = { + 'custom': 'template_tests.templatetags.custom', + 'inclusion': 'template_tests.templatetags.inclusion', +} + class CustomFilterTests(SimpleTestCase): def test_filter(self): - t = Engine().from_string("{% load custom %}{{ string|trim:5 }}") + engine = Engine(libraries=LIBRARIES) + t = engine.from_string("{% load custom %}{{ string|trim:5 }}") self.assertEqual( t.render(Context({"string": "abcdefghijklmnopqrstuvwxyz"})), "abcde" @@ -26,7 +34,7 @@ class TagTestCase(SimpleTestCase): @classmethod def setUpClass(cls): - cls.engine = Engine(app_dirs=True) + cls.engine = Engine(app_dirs=True, libraries=LIBRARIES) super(TagTestCase, cls).setUpClass() def verify_tag(self, tag, name): @@ -269,7 +277,7 @@ class InclusionTagTests(TagTestCase): """ #23441 -- InclusionNode shouldn't modify its nodelist at render time. """ - engine = Engine(app_dirs=True) + engine = Engine(app_dirs=True, libraries=LIBRARIES) template = engine.from_string('{% load inclusion %}{% inclusion_no_params %}') count = template.nodelist.get_nodes_by_type(Node) template.render(Context({})) @@ -281,7 +289,7 @@ class InclusionTagTests(TagTestCase): when rendering. Otherwise, leftover values such as blocks from extending can interfere with subsequent rendering. """ - engine = Engine(app_dirs=True) + engine = Engine(app_dirs=True, libraries=LIBRARIES) template = engine.from_string('{% load inclusion %}{% inclusion_extends1 %}{% inclusion_extends2 %}') self.assertEqual(template.render(Context({})).strip(), 'one\ntwo') @@ -313,34 +321,37 @@ class TemplateTagLoadingTests(SimpleTestCase): @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: - self.engine.from_string(ttext) - - self.assertIn('ImportError', e.exception.args[0]) - self.assertIn('Xtemplate', e.exception.args[0]) + msg = ( + "Invalid template library specified. ImportError raised when " + "trying to load 'template_tests.broken_tag': cannot import name " + "'?Xtemplate'?" + ) + with six.assertRaisesRegex(self, InvalidTemplateLibrary, msg): + Engine(libraries={ + 'broken_tag': 'template_tests.broken_tag', + }) def test_load_error_egg(self): - ttext = "{% load broken_egg %}" egg_name = '%s/tagsegg.egg' % self.egg_dir + msg = ( + "Invalid template library specified. ImportError raised when " + "trying to load 'tagsegg.templatetags.broken_egg': cannot " + "import name '?Xtemplate'?" + ) with extend_sys_path(egg_name): - with self.assertRaises(TemplateSyntaxError): - with self.settings(INSTALLED_APPS=['tagsegg']): - self.engine.from_string(ttext) - try: - with self.settings(INSTALLED_APPS=['tagsegg']): - self.engine.from_string(ttext) - except TemplateSyntaxError as e: - self.assertIn('ImportError', e.args[0]) - self.assertIn('Xtemplate', e.args[0]) + with six.assertRaisesRegex(self, InvalidTemplateLibrary, msg): + Engine(libraries={ + 'broken_egg': 'tagsegg.templatetags.broken_egg', + }) def test_load_working_egg(self): ttext = "{% load working_egg %}" egg_name = '%s/tagsegg.egg' % self.egg_dir with extend_sys_path(egg_name): - with self.settings(INSTALLED_APPS=['tagsegg']): - self.engine.from_string(ttext) + engine = Engine(libraries={ + 'working_egg': 'tagsegg.templatetags.working_egg', + }) + engine.from_string(ttext) diff --git a/tests/template_tests/test_engine.py b/tests/template_tests/test_engine.py index d9929660cc..a72a430e3e 100644 --- a/tests/template_tests/test_engine.py +++ b/tests/template_tests/test_engine.py @@ -14,7 +14,10 @@ OTHER_DIR = os.path.join(ROOT, 'other_templates') class DeprecatedRenderToStringTest(SimpleTestCase): def setUp(self): - self.engine = Engine(dirs=[TEMPLATE_DIR]) + self.engine = Engine( + dirs=[TEMPLATE_DIR], + libraries={'custom': 'template_tests.templatetags.custom'}, + ) def test_basic_context(self): self.assertEqual( diff --git a/tests/template_tests/test_library.py b/tests/template_tests/test_library.py new file mode 100644 index 0000000000..50a00ca082 --- /dev/null +++ b/tests/template_tests/test_library.py @@ -0,0 +1,132 @@ +from django.template import Library +from django.template.base import Node +from django.test import TestCase + + +class FilterRegistrationTests(TestCase): + + def setUp(self): + self.library = Library() + + def test_filter(self): + @self.library.filter + def func(): + return '' + self.assertEqual(self.library.filters['func'], func) + + def test_filter_parens(self): + @self.library.filter() + def func(): + return '' + self.assertEqual(self.library.filters['func'], func) + + def test_filter_name_arg(self): + @self.library.filter('name') + def func(): + return '' + self.assertEqual(self.library.filters['name'], func) + + def test_filter_name_kwarg(self): + @self.library.filter(name='name') + def func(): + return '' + self.assertEqual(self.library.filters['name'], func) + + def test_filter_call(self): + def func(): + return '' + self.library.filter('name', func) + self.assertEqual(self.library.filters['name'], func) + + def test_filter_invalid(self): + msg = "Unsupported arguments to Library.filter: (None, '')" + with self.assertRaisesMessage(ValueError, msg): + self.library.filter(None, '') + + +class InclusionTagRegistrationTests(TestCase): + + def setUp(self): + self.library = Library() + + def test_inclusion_tag(self): + @self.library.inclusion_tag('template.html') + def func(): + return '' + self.assertIn('func', self.library.tags) + + def test_inclusion_tag_name(self): + @self.library.inclusion_tag('template.html', name='name') + def func(): + return '' + self.assertIn('name', self.library.tags) + + +class SimpleTagRegistrationTests(TestCase): + + def setUp(self): + self.library = Library() + + def test_simple_tag(self): + @self.library.simple_tag + def func(): + return '' + self.assertIn('func', self.library.tags) + + def test_simple_tag_parens(self): + @self.library.simple_tag() + def func(): + return '' + self.assertIn('func', self.library.tags) + + def test_simple_tag_name_kwarg(self): + @self.library.simple_tag(name='name') + def func(): + return '' + self.assertIn('name', self.library.tags) + + def test_simple_tag_invalid(self): + msg = "Invalid arguments provided to simple_tag" + with self.assertRaisesMessage(ValueError, msg): + self.library.simple_tag('invalid') + + +class TagRegistrationTests(TestCase): + + def setUp(self): + self.library = Library() + + def test_tag(self): + @self.library.tag + def func(parser, token): + return Node() + self.assertEqual(self.library.tags['func'], func) + + def test_tag_parens(self): + @self.library.tag() + def func(parser, token): + return Node() + self.assertEqual(self.library.tags['func'], func) + + def test_tag_name_arg(self): + @self.library.tag('name') + def func(parser, token): + return Node() + self.assertEqual(self.library.tags['name'], func) + + def test_tag_name_kwarg(self): + @self.library.tag(name='name') + def func(parser, token): + return Node() + self.assertEqual(self.library.tags['name'], func) + + def test_tag_call(self): + def func(parser, token): + return Node() + self.library.tag('name', func) + self.assertEqual(self.library.tags['name'], func) + + def test_tag_invalid(self): + msg = "Unsupported arguments to Library.tag: (None, '')" + with self.assertRaisesMessage(ValueError, msg): + self.library.tag(None, '') diff --git a/tests/template_tests/test_nodelist.py b/tests/template_tests/test_nodelist.py index 3f28aff92c..3070c9d68a 100644 --- a/tests/template_tests/test_nodelist.py +++ b/tests/template_tests/test_nodelist.py @@ -49,7 +49,7 @@ class ErrorIndexTest(TestCase): 'range': range(5), 'five': 5, }) - engine = Engine(debug=True) + engine = Engine(debug=True, libraries={'bad_tag': 'template_tests.templatetags.bad_tag'}) for source, expected_error_source_index in tests: template = engine.from_string(source) try: diff --git a/tests/template_tests/test_parser.py b/tests/template_tests/test_parser.py index dd22c83836..6ff57c2cf5 100644 --- a/tests/template_tests/test_parser.py +++ b/tests/template_tests/test_parser.py @@ -9,6 +9,7 @@ from django.template import Library, TemplateSyntaxError from django.template.base import ( TOKEN_BLOCK, FilterExpression, Parser, Token, Variable, ) +from django.template.defaultfilters import register as filter_library from django.utils import six @@ -24,7 +25,7 @@ class ParserTests(TestCase): def test_filter_parsing(self): c = {"article": {"section": "News"}} - p = Parser("") + p = Parser("", builtins=[filter_library]) def fe_test(s, val): self.assertEqual(FilterExpression(s, p).resolve(c), val) diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py index 436502305e..39f0b427d6 100644 --- a/tests/template_tests/tests.py +++ b/tests/template_tests/tests.py @@ -97,7 +97,10 @@ class TemplateTests(SimpleTestCase): Errors raised while compiling nodes should include the token information. """ - engine = Engine(debug=True) + engine = Engine( + debug=True, + libraries={'bad_tag': 'template_tests.templatetags.bad_tag'}, + ) with self.assertRaises(RuntimeError) as e: engine.from_string("{% load bad_tag %}{% badtag %}") self.assertEqual(e.exception.template_debug['during'], '{% badtag %}') diff --git a/tests/template_tests/utils.py b/tests/template_tests/utils.py index 36f4d95678..d78f0eac6c 100644 --- a/tests/template_tests/utils.py +++ b/tests/template_tests/utils.py @@ -5,9 +5,6 @@ from __future__ import unicode_literals import functools import os -from django import template -from django.template import Library -from django.template.base import libraries from django.template.engine import Engine from django.test.utils import override_settings from django.utils._os import upath @@ -49,14 +46,17 @@ def setup(templates, *args, **kwargs): ] def decorator(func): - @register_test_tags # Make Engine.get_default() raise an exception to ensure that tests # are properly isolated from Django's global settings. @override_settings(TEMPLATES=None) @functools.wraps(func) def inner(self): + # Set up custom template tag libraries if specified + libraries = getattr(self, 'libraries', {}) + self.engine = Engine( allowed_include_roots=[ROOT], + libraries=libraries, loaders=loaders, ) func(self) @@ -66,6 +66,7 @@ def setup(templates, *args, **kwargs): self.engine = Engine( allowed_include_roots=[ROOT], + libraries=libraries, loaders=loaders, string_if_invalid='INVALID', ) @@ -75,6 +76,7 @@ def setup(templates, *args, **kwargs): self.engine = Engine( allowed_include_roots=[ROOT], debug=True, + libraries=libraries, loaders=loaders, ) func(self) @@ -85,43 +87,9 @@ def setup(templates, *args, **kwargs): return decorator -# Custom template tag for tests - -register = Library() - - -class EchoNode(template.Node): - def __init__(self, contents): - self.contents = contents - - def render(self, context): - return ' '.join(self.contents) - - -@register.tag -def echo(parser, token): - return EchoNode(token.contents.split()[1:]) -register.tag('other_echo', echo) - - -@register.filter -def upper(value): - return value.upper() - - -def register_test_tags(func): - @functools.wraps(func) - def inner(self): - libraries['testtags'] = register - try: - func(self) - finally: - del libraries['testtags'] - return inner - - # Helper objects + class SomeException(Exception): silent_variable_failure = True |
