mirror of
https://github.com/django/django.git
synced 2025-01-03 06:55:47 +00:00
55f12f8709
This patch does three major things: * Merges the django.template.debug implementation into django.template.base. * Simplifies the debug implementation. The old implementation copied debug information to every token and node. The django_template_source attribute was set in multiple places, some quite hacky, like django.template.defaulttags.ForNode. Debug information is now annotated in two high-level places: * Template.compile_nodelist for errors during parsing * Node.render_annotated for errors during rendering These were chosen because they have access to the template and context as well as to all exceptions that happen during either the parse or render phase. * Moves the contextual line traceback information creation from django.views.debug into django.template.base.Template. The debug views now only deal with the presentation of the debug information.
118 lines
3.9 KiB
Python
118 lines
3.9 KiB
Python
"""
|
|
Testing some internals of the template processing. These are *not* examples to be copied in user code.
|
|
"""
|
|
from __future__ import unicode_literals
|
|
|
|
from unittest import TestCase
|
|
|
|
from django.template import Library, TemplateSyntaxError
|
|
from django.template.base import (
|
|
TOKEN_BLOCK, FilterExpression, Parser, Token, Variable,
|
|
)
|
|
from django.utils import six
|
|
|
|
|
|
class ParserTests(TestCase):
|
|
|
|
def test_token_smart_split(self):
|
|
"""
|
|
#7027 -- _() syntax should work with spaces
|
|
"""
|
|
token = Token(TOKEN_BLOCK, 'sometag _("Page not found") value|yesno:_("yes,no")')
|
|
split = token.split_contents()
|
|
self.assertEqual(split, ["sometag", '_("Page not found")', 'value|yesno:_("yes,no")'])
|
|
|
|
def test_filter_parsing(self):
|
|
c = {"article": {"section": "News"}}
|
|
p = Parser("")
|
|
|
|
def fe_test(s, val):
|
|
self.assertEqual(FilterExpression(s, p).resolve(c), val)
|
|
|
|
fe_test("article.section", "News")
|
|
fe_test("article.section|upper", "NEWS")
|
|
fe_test('"News"', "News")
|
|
fe_test("'News'", "News")
|
|
fe_test(r'"Some \"Good\" News"', 'Some "Good" News')
|
|
fe_test(r'"Some \"Good\" News"', 'Some "Good" News')
|
|
fe_test(r"'Some \'Bad\' News'", "Some 'Bad' News")
|
|
|
|
fe = FilterExpression(r'"Some \"Good\" News"', p)
|
|
self.assertEqual(fe.filters, [])
|
|
self.assertEqual(fe.var, 'Some "Good" News')
|
|
|
|
# Filtered variables should reject access of attributes beginning with
|
|
# underscores.
|
|
self.assertRaises(TemplateSyntaxError, FilterExpression, "article._hidden|upper", p)
|
|
|
|
def test_variable_parsing(self):
|
|
c = {"article": {"section": "News"}}
|
|
self.assertEqual(Variable("article.section").resolve(c), "News")
|
|
self.assertEqual(Variable('"News"').resolve(c), "News")
|
|
self.assertEqual(Variable("'News'").resolve(c), "News")
|
|
|
|
# Translated strings are handled correctly.
|
|
self.assertEqual(Variable("_(article.section)").resolve(c), "News")
|
|
self.assertEqual(Variable('_("Good News")').resolve(c), "Good News")
|
|
self.assertEqual(Variable("_('Better News')").resolve(c), "Better News")
|
|
|
|
# Escaped quotes work correctly as well.
|
|
self.assertEqual(
|
|
Variable(r'"Some \"Good\" News"').resolve(c), 'Some "Good" News'
|
|
)
|
|
self.assertEqual(
|
|
Variable(r"'Some \'Better\' News'").resolve(c), "Some 'Better' News"
|
|
)
|
|
|
|
# Variables should reject access of attributes beginning with
|
|
# underscores.
|
|
self.assertRaises(TemplateSyntaxError, Variable, "article._hidden")
|
|
|
|
# Variables should raise on non string type
|
|
with six.assertRaisesRegex(self, TypeError, "Variable must be a string or number, got <(class|type) 'dict'>"):
|
|
Variable({})
|
|
|
|
def test_filter_args_count(self):
|
|
p = Parser("")
|
|
l = Library()
|
|
|
|
@l.filter
|
|
def no_arguments(value):
|
|
pass
|
|
|
|
@l.filter
|
|
def one_argument(value, arg):
|
|
pass
|
|
|
|
@l.filter
|
|
def one_opt_argument(value, arg=False):
|
|
pass
|
|
|
|
@l.filter
|
|
def two_arguments(value, arg, arg2):
|
|
pass
|
|
|
|
@l.filter
|
|
def two_one_opt_arg(value, arg, arg2=False):
|
|
pass
|
|
p.add_library(l)
|
|
for expr in (
|
|
'1|no_arguments:"1"',
|
|
'1|two_arguments',
|
|
'1|two_arguments:"1"',
|
|
'1|two_one_opt_arg',
|
|
):
|
|
with self.assertRaises(TemplateSyntaxError):
|
|
FilterExpression(expr, p)
|
|
for expr in (
|
|
# Correct number of arguments
|
|
'1|no_arguments',
|
|
'1|one_argument:"1"',
|
|
# One optional
|
|
'1|one_opt_argument',
|
|
'1|one_opt_argument:"1"',
|
|
# Not supplying all
|
|
'1|two_one_opt_arg:"1"',
|
|
):
|
|
FilterExpression(expr, p)
|