test_parser.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. self.assertRaises(TemplateSyntaxError, FilterExpression, "article._hidden|upper", p)
  38. def test_variable_parsing(self):
  39. c = {"article": {"section": "News"}}
  40. self.assertEqual(Variable("article.section").resolve(c), "News")
  41. self.assertEqual(Variable('"News"').resolve(c), "News")
  42. self.assertEqual(Variable("'News'").resolve(c), "News")
  43. # Translated strings are handled correctly.
  44. self.assertEqual(Variable("_(article.section)").resolve(c), "News")
  45. self.assertEqual(Variable('_("Good News")').resolve(c), "Good News")
  46. self.assertEqual(Variable("_('Better News')").resolve(c), "Better News")
  47. # Escaped quotes work correctly as well.
  48. self.assertEqual(
  49. Variable(r'"Some \"Good\" News"').resolve(c), 'Some "Good" News'
  50. )
  51. self.assertEqual(
  52. Variable(r"'Some \'Better\' News'").resolve(c), "Some 'Better' News"
  53. )
  54. # Variables should reject access of attributes beginning with
  55. # underscores.
  56. self.assertRaises(TemplateSyntaxError, Variable, "article._hidden")
  57. # Variables should raise on non string type
  58. with six.assertRaisesRegex(self, TypeError, "Variable must be a string or number, got <(class|type) 'dict'>"):
  59. Variable({})
  60. def test_filter_args_count(self):
  61. p = Parser("")
  62. l = Library()
  63. @l.filter
  64. def no_arguments(value):
  65. pass
  66. @l.filter
  67. def one_argument(value, arg):
  68. pass
  69. @l.filter
  70. def one_opt_argument(value, arg=False):
  71. pass
  72. @l.filter
  73. def two_arguments(value, arg, arg2):
  74. pass
  75. @l.filter
  76. def two_one_opt_arg(value, arg, arg2=False):
  77. pass
  78. p.add_library(l)
  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, p)
  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, p)