tests.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. from __future__ import unicode_literals
  2. import warnings
  3. from django.test import SimpleTestCase
  4. from django.test.utils import reset_warning_registry
  5. from django.utils import six
  6. from django.utils.deprecation import (
  7. DeprecationInstanceCheck, RemovedInNextVersionWarning, RenameMethodsBase,
  8. )
  9. class RenameManagerMethods(RenameMethodsBase):
  10. renamed_methods = (
  11. ('old', 'new', DeprecationWarning),
  12. )
  13. class RenameMethodsTests(SimpleTestCase):
  14. """
  15. Tests the `RenameMethodsBase` type introduced to rename `get_query_set`
  16. to `get_queryset` across the code base following #15363.
  17. """
  18. def test_class_definition_warnings(self):
  19. """
  20. Ensure a warning is raised upon class definition to suggest renaming
  21. the faulty method.
  22. """
  23. reset_warning_registry()
  24. with warnings.catch_warnings(record=True) as recorded:
  25. warnings.simplefilter('always')
  26. class Manager(six.with_metaclass(RenameManagerMethods)):
  27. def old(self):
  28. pass
  29. self.assertEqual(len(recorded), 1)
  30. msg = str(recorded[0].message)
  31. self.assertEqual(msg,
  32. '`Manager.old` method should be renamed `new`.')
  33. def test_get_new_defined(self):
  34. """
  35. Ensure `old` complains and not `new` when only `new` is defined.
  36. """
  37. with warnings.catch_warnings(record=True) as recorded:
  38. warnings.simplefilter('ignore')
  39. class Manager(six.with_metaclass(RenameManagerMethods)):
  40. def new(self):
  41. pass
  42. warnings.simplefilter('always')
  43. manager = Manager()
  44. manager.new()
  45. self.assertEqual(len(recorded), 0)
  46. manager.old()
  47. self.assertEqual(len(recorded), 1)
  48. msg = str(recorded.pop().message)
  49. self.assertEqual(msg,
  50. '`Manager.old` is deprecated, use `new` instead.')
  51. def test_get_old_defined(self):
  52. """
  53. Ensure `old` complains when only `old` is defined.
  54. """
  55. with warnings.catch_warnings(record=True) as recorded:
  56. warnings.simplefilter('ignore')
  57. class Manager(six.with_metaclass(RenameManagerMethods)):
  58. def old(self):
  59. pass
  60. warnings.simplefilter('always')
  61. manager = Manager()
  62. manager.new()
  63. self.assertEqual(len(recorded), 0)
  64. manager.old()
  65. self.assertEqual(len(recorded), 1)
  66. msg = str(recorded.pop().message)
  67. self.assertEqual(msg,
  68. '`Manager.old` is deprecated, use `new` instead.')
  69. def test_deprecated_subclass_renamed(self):
  70. """
  71. Ensure the correct warnings are raised when a class that didn't rename
  72. `old` subclass one that did.
  73. """
  74. with warnings.catch_warnings(record=True) as recorded:
  75. warnings.simplefilter('ignore')
  76. class Renamed(six.with_metaclass(RenameManagerMethods)):
  77. def new(self):
  78. pass
  79. class Deprecated(Renamed):
  80. def old(self):
  81. super(Deprecated, self).old()
  82. warnings.simplefilter('always')
  83. deprecated = Deprecated()
  84. deprecated.new()
  85. self.assertEqual(len(recorded), 1)
  86. msg = str(recorded.pop().message)
  87. self.assertEqual(msg,
  88. '`Renamed.old` is deprecated, use `new` instead.')
  89. recorded[:] = []
  90. deprecated.old()
  91. self.assertEqual(len(recorded), 2)
  92. msgs = [str(warning.message) for warning in recorded]
  93. self.assertEqual(msgs, [
  94. '`Deprecated.old` is deprecated, use `new` instead.',
  95. '`Renamed.old` is deprecated, use `new` instead.',
  96. ])
  97. def test_renamed_subclass_deprecated(self):
  98. """
  99. Ensure the correct warnings are raised when a class that renamed
  100. `old` subclass one that didn't.
  101. """
  102. with warnings.catch_warnings(record=True) as recorded:
  103. warnings.simplefilter('ignore')
  104. class Deprecated(six.with_metaclass(RenameManagerMethods)):
  105. def old(self):
  106. pass
  107. class Renamed(Deprecated):
  108. def new(self):
  109. super(Renamed, self).new()
  110. warnings.simplefilter('always')
  111. renamed = Renamed()
  112. renamed.new()
  113. self.assertEqual(len(recorded), 0)
  114. renamed.old()
  115. self.assertEqual(len(recorded), 1)
  116. msg = str(recorded.pop().message)
  117. self.assertEqual(msg,
  118. '`Renamed.old` is deprecated, use `new` instead.')
  119. def test_deprecated_subclass_renamed_and_mixins(self):
  120. """
  121. Ensure the correct warnings are raised when a subclass inherit from a
  122. class that renamed `old` and mixins that may or may not have renamed
  123. `new`.
  124. """
  125. with warnings.catch_warnings(record=True) as recorded:
  126. warnings.simplefilter('ignore')
  127. class Renamed(six.with_metaclass(RenameManagerMethods)):
  128. def new(self):
  129. pass
  130. class RenamedMixin(object):
  131. def new(self):
  132. super(RenamedMixin, self).new()
  133. class DeprecatedMixin(object):
  134. def old(self):
  135. super(DeprecatedMixin, self).old()
  136. class Deprecated(DeprecatedMixin, RenamedMixin, Renamed):
  137. pass
  138. warnings.simplefilter('always')
  139. deprecated = Deprecated()
  140. deprecated.new()
  141. self.assertEqual(len(recorded), 1)
  142. msg = str(recorded.pop().message)
  143. self.assertEqual(msg,
  144. '`RenamedMixin.old` is deprecated, use `new` instead.')
  145. deprecated.old()
  146. self.assertEqual(len(recorded), 2)
  147. msgs = [str(warning.message) for warning in recorded]
  148. self.assertEqual(msgs, [
  149. '`DeprecatedMixin.old` is deprecated, use `new` instead.',
  150. '`RenamedMixin.old` is deprecated, use `new` instead.',
  151. ])
  152. class DeprecationInstanceCheckTest(SimpleTestCase):
  153. def test_warning(self):
  154. class Manager(six.with_metaclass(DeprecationInstanceCheck)):
  155. alternative = 'fake.path.Foo'
  156. deprecation_warning = RemovedInNextVersionWarning
  157. msg = '`Manager` is deprecated, use `fake.path.Foo` instead.'
  158. with warnings.catch_warnings():
  159. warnings.simplefilter('error', category=RemovedInNextVersionWarning)
  160. with self.assertRaisesMessage(RemovedInNextVersionWarning, msg):
  161. isinstance(object, Manager)