utils.py 4.1 KB

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