test_parser.py 4.0 KB

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