Commit fb267a1d authored by Preston Timmons's avatar Preston Timmons
Browse files

Updated template tests to create their own engine.

This continues work to treat Django templates as a library.
parent d84f01ff
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
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):
+11 −3
Original line number Diff line number Diff line
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')
+25 −66
Original line number Diff line number Diff line
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)

    @override_settings(TEMPLATES=[{
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'APP_DIRS': True,
        'OPTIONS': {
            'debug': True,
        },
    }])
        Engine(debug=True).from_string('{% include "this_does_not_exist.html" %}')

    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(),
        )
+11 −11
Original line number Diff line number Diff line
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))}
+18 −13
Original line number Diff line number Diff line
@@ -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
Loading