test_parser.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. """
  2. Testing some internals of the template processing. These are *not* examples to be copied in user code.
  3. """
  4. from __future__ import unicode_literals
  5. from unittest import TestCase
  6. from django.template import Library, TemplateSyntaxError
  7. from django.template.base import (
  8. TOKEN_BLOCK, FilterExpression, Parser, Token, Variable,
  9. )
  10. from django.template.defaultfilters import register as filter_library
  11. from django.utils import six
  12. class ParserTests(TestCase):
  13. def test_token_smart_split(self):
  14. """
  15. #7027 -- _() syntax should work with spaces
  16. """
  17. token = Token(TOKEN_BLOCK, 'sometag _("Page not found") value|yesno:_("yes,no")')
  18. split = token.split_contents()
  19. self.assertEqual(split, ["sometag", '_("Page not found")', 'value|yesno:_("yes,no")'])
  20. def test_filter_parsing(self):
  21. c = {"article": {"section": "News"}}
  22. p = Parser("", builtins=[filter_library])
  23. def fe_test(s, val):
  24. self.assertEqual(FilterExpression(s, p).resolve(c), val)
  25. fe_test("article.section", "News")
  26. fe_test("article.section|upper", "NEWS")
  27. fe_test('"News"', "News")
  28. fe_test("'News'", "News")
  29. fe_test(r'"Some \"Good\" News"', 'Some "Good" News')
  30. fe_test(r'"Some \"Good\" News"', 'Some "Good" News')
  31. fe_test(r"'Some \'Bad\' News'", "Some 'Bad' News")
  32. fe = FilterExpression(r'"Some \"Good\" News"', p)
  33. self.assertEqual(fe.filters, [])
  34. self.assertEqual(fe.var, 'Some "Good" News')
  35. # Filtered variables should reject access of attributes beginning with
  36. # underscores.
  37. with self.assertRaises(TemplateSyntaxError):
  38. FilterExpression("article._hidden|upper", p)
  39. def test_variable_parsing(self):
  40. c = {"article": {"section": "News"}}
  41. self.assertEqual(Variable("article.section").resolve(c), "News")
  42. self.assertEqual(Variable('"News"').resolve(c), "News")
  43. self.assertEqual(Variable("'News'").resolve(c), "News")
  44. # Translated strings are handled correctly.
  45. self.assertEqual(Variable("_(article.section)").resolve(c), "News")
  46. self.assertEqual(Variable('_("Good News")').resolve(c), "Good News")
  47. self.assertEqual(Variable("_('Better News')").resolve(c), "Better News")
  48. # Escaped quotes work correctly as well.
  49. self.assertEqual(
  50. Variable(r'"Some \"Good\" News"').resolve(c), 'Some "Good" News'
  51. )
  52. self.assertEqual(
  53. Variable(r"'Some \'Better\' News'").resolve(c), "Some 'Better' News"
  54. )
  55. # Variables should reject access of attributes beginning with
  56. # underscores.
  57. with self.assertRaises(TemplateSyntaxError):
  58. Variable("article._hidden")
  59. # Variables should raise on non string type
  60. with six.assertRaisesRegex(self, TypeError, "Variable must be a string or number, got <(class|type) 'dict'>"):
  61. Variable({})
  62. def test_filter_args_count(self):
  63. parser = Parser("")
  64. register = Library()
  65. @register.filter
  66. def no_arguments(value):
  67. pass
  68. @register.filter
  69. def one_argument(value, arg):
  70. pass
  71. @register.filter
  72. def one_opt_argument(value, arg=False):
  73. pass
  74. @register.filter
  75. def two_arguments(value, arg, arg2):
  76. pass
  77. @register.filter
  78. def two_one_opt_arg(value, arg, arg2=False):
  79. pass
  80. parser.add_library(register)
  81. for expr in (
  82. '1|no_arguments:"1"',
  83. '1|two_arguments',
  84. '1|two_arguments:"1"',
  85. '1|two_one_opt_arg',
  86. ):
  87. with self.assertRaises(TemplateSyntaxError):
  88. FilterExpression(expr, parser)
  89. for expr in (
  90. # Correct number of arguments
  91. '1|no_arguments',
  92. '1|one_argument:"1"',
  93. # One optional
  94. '1|one_opt_argument',
  95. '1|one_opt_argument:"1"',
  96. # Not supplying all
  97. '1|two_one_opt_arg:"1"',
  98. ):
  99. FilterExpression(expr, parser)