utils.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import functools
  2. import os
  3. from django.template.engine import Engine
  4. from django.test.utils import override_settings
  5. from django.utils.safestring import mark_safe
  6. ROOT = os.path.dirname(os.path.abspath(__file__))
  7. TEMPLATE_DIR = os.path.join(ROOT, 'templates')
  8. def setup(templates, *args, **kwargs):
  9. """
  10. Runs test method multiple times in the following order:
  11. debug cached string_if_invalid
  12. ----- ------ -----------------
  13. False False
  14. False True
  15. False False INVALID
  16. False True INVALID
  17. True False
  18. True True
  19. """
  20. # when testing deprecation warnings, it's useful to run just one test since
  21. # the message won't be displayed multiple times
  22. test_once = kwargs.get('test_once', False)
  23. for arg in args:
  24. templates.update(arg)
  25. # numerous tests make use of an inclusion tag
  26. # add this in here for simplicity
  27. templates["inclusion.html"] = "{{ result }}"
  28. loaders = [
  29. ('django.template.loaders.cached.Loader', [
  30. ('django.template.loaders.locmem.Loader', templates),
  31. ]),
  32. ]
  33. def decorator(func):
  34. # Make Engine.get_default() raise an exception to ensure that tests
  35. # are properly isolated from Django's global settings.
  36. @override_settings(TEMPLATES=None)
  37. @functools.wraps(func)
  38. def inner(self):
  39. # Set up custom template tag libraries if specified
  40. libraries = getattr(self, 'libraries', {})
  41. self.engine = Engine(
  42. libraries=libraries,
  43. loaders=loaders,
  44. )
  45. func(self)
  46. if test_once:
  47. return
  48. func(self)
  49. self.engine = Engine(
  50. libraries=libraries,
  51. loaders=loaders,
  52. string_if_invalid='INVALID',
  53. )
  54. func(self)
  55. func(self)
  56. self.engine = Engine(
  57. debug=True,
  58. libraries=libraries,
  59. loaders=loaders,
  60. )
  61. func(self)
  62. func(self)
  63. return inner
  64. return decorator
  65. # Helper objects
  66. class SomeException(Exception):
  67. silent_variable_failure = True
  68. class SomeOtherException(Exception):
  69. pass
  70. class ShouldNotExecuteException(Exception):
  71. pass
  72. class SomeClass:
  73. def __init__(self):
  74. self.otherclass = OtherClass()
  75. def method(self):
  76. return 'SomeClass.method'
  77. def method2(self, o):
  78. return o
  79. def method3(self):
  80. raise SomeException
  81. def method4(self):
  82. raise SomeOtherException
  83. def method5(self):
  84. raise TypeError
  85. def __getitem__(self, key):
  86. if key == 'silent_fail_key':
  87. raise SomeException
  88. elif key == 'noisy_fail_key':
  89. raise SomeOtherException
  90. raise KeyError
  91. @property
  92. def silent_fail_attribute(self):
  93. raise SomeException
  94. @property
  95. def noisy_fail_attribute(self):
  96. raise SomeOtherException
  97. @property
  98. def attribute_error_attribute(self):
  99. raise AttributeError
  100. @property
  101. def type_error_attribute(self):
  102. raise TypeError
  103. class OtherClass:
  104. def method(self):
  105. return 'OtherClass.method'
  106. class TestObj:
  107. def is_true(self):
  108. return True
  109. def is_false(self):
  110. return False
  111. def is_bad(self):
  112. raise ShouldNotExecuteException()
  113. class SilentGetItemClass:
  114. def __getitem__(self, key):
  115. raise SomeException
  116. class SilentAttrClass:
  117. def b(self):
  118. raise SomeException
  119. b = property(b)
  120. class UTF8Class:
  121. "Class whose __str__ returns non-ASCII data"
  122. def __str__(self):
  123. return 'ŠĐĆŽćžšđ'
  124. # These two classes are used to test auto-escaping of unicode output.
  125. class UnsafeClass:
  126. def __str__(self):
  127. return 'you & me'
  128. class SafeClass:
  129. def __str__(self):
  130. return mark_safe('you > me')