tests.py 6.71 KB
Newer Older
1
from __future__ import unicode_literals
2

3 4
import warnings

5
from django.test import SimpleTestCase
6
from django.test.utils import reset_warning_registry
7
from django.utils import six
8 9 10
from django.utils.deprecation import (
    DeprecationInstanceCheck, RemovedInNextVersionWarning, RenameMethodsBase,
)
11 12 13 14


class RenameManagerMethods(RenameMethodsBase):
    renamed_methods = (
15
        ('old', 'new', DeprecationWarning),
16 17 18 19 20 21 22 23 24 25 26 27 28 29
    )


class RenameMethodsTests(SimpleTestCase):
    """
    Tests the `RenameMethodsBase` type introduced to rename `get_query_set`
    to `get_queryset` across the code base following #15363.
    """

    def test_class_definition_warnings(self):
        """
        Ensure a warning is raised upon class definition to suggest renaming
        the faulty method.
        """
30
        reset_warning_registry()
31 32
        with warnings.catch_warnings(record=True) as recorded:
            warnings.simplefilter('always')
33

34 35 36 37 38 39 40 41 42 43 44 45 46 47
            class Manager(six.with_metaclass(RenameManagerMethods)):
                def old(self):
                    pass
            self.assertEqual(len(recorded), 1)
            msg = str(recorded[0].message)
            self.assertEqual(msg,
                '`Manager.old` method should be renamed `new`.')

    def test_get_new_defined(self):
        """
        Ensure `old` complains and not `new` when only `new` is defined.
        """
        with warnings.catch_warnings(record=True) as recorded:
            warnings.simplefilter('ignore')
48

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
            class Manager(six.with_metaclass(RenameManagerMethods)):
                def new(self):
                    pass
            warnings.simplefilter('always')
            manager = Manager()
            manager.new()
            self.assertEqual(len(recorded), 0)
            manager.old()
            self.assertEqual(len(recorded), 1)
            msg = str(recorded.pop().message)
            self.assertEqual(msg,
                '`Manager.old` is deprecated, use `new` instead.')

    def test_get_old_defined(self):
        """
        Ensure `old` complains when only `old` is defined.
        """
        with warnings.catch_warnings(record=True) as recorded:
            warnings.simplefilter('ignore')
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
            class Manager(six.with_metaclass(RenameManagerMethods)):
                def old(self):
                    pass
            warnings.simplefilter('always')
            manager = Manager()
            manager.new()
            self.assertEqual(len(recorded), 0)
            manager.old()
            self.assertEqual(len(recorded), 1)
            msg = str(recorded.pop().message)
            self.assertEqual(msg,
                '`Manager.old` is deprecated, use `new` instead.')

    def test_deprecated_subclass_renamed(self):
        """
        Ensure the correct warnings are raised when a class that didn't rename
        `old` subclass one that did.
        """
        with warnings.catch_warnings(record=True) as recorded:
            warnings.simplefilter('ignore')
89

90 91 92
            class Renamed(six.with_metaclass(RenameManagerMethods)):
                def new(self):
                    pass
93

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
            class Deprecated(Renamed):
                def old(self):
                    super(Deprecated, self).old()
            warnings.simplefilter('always')
            deprecated = Deprecated()
            deprecated.new()
            self.assertEqual(len(recorded), 1)
            msg = str(recorded.pop().message)
            self.assertEqual(msg,
                '`Renamed.old` is deprecated, use `new` instead.')
            recorded[:] = []
            deprecated.old()
            self.assertEqual(len(recorded), 2)
            msgs = [str(warning.message) for warning in recorded]
            self.assertEqual(msgs, [
                '`Deprecated.old` is deprecated, use `new` instead.',
                '`Renamed.old` is deprecated, use `new` instead.',
            ])

    def test_renamed_subclass_deprecated(self):
        """
        Ensure the correct warnings are raised when a class that renamed
        `old` subclass one that didn't.
        """
        with warnings.catch_warnings(record=True) as recorded:
            warnings.simplefilter('ignore')
120

121 122 123
            class Deprecated(six.with_metaclass(RenameManagerMethods)):
                def old(self):
                    pass
124

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
            class Renamed(Deprecated):
                def new(self):
                    super(Renamed, self).new()
            warnings.simplefilter('always')
            renamed = Renamed()
            renamed.new()
            self.assertEqual(len(recorded), 0)
            renamed.old()
            self.assertEqual(len(recorded), 1)
            msg = str(recorded.pop().message)
            self.assertEqual(msg,
                '`Renamed.old` is deprecated, use `new` instead.')

    def test_deprecated_subclass_renamed_and_mixins(self):
        """
        Ensure the correct warnings are raised when a subclass inherit from a
        class that renamed `old` and mixins that may or may not have renamed
        `new`.
        """
        with warnings.catch_warnings(record=True) as recorded:
            warnings.simplefilter('ignore')
146

147 148 149
            class Renamed(six.with_metaclass(RenameManagerMethods)):
                def new(self):
                    pass
150

151 152 153
            class RenamedMixin(object):
                def new(self):
                    super(RenamedMixin, self).new()
154

155 156 157
            class DeprecatedMixin(object):
                def old(self):
                    super(DeprecatedMixin, self).old()
158

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
            class Deprecated(DeprecatedMixin, RenamedMixin, Renamed):
                pass
            warnings.simplefilter('always')
            deprecated = Deprecated()
            deprecated.new()
            self.assertEqual(len(recorded), 1)
            msg = str(recorded.pop().message)
            self.assertEqual(msg,
                '`RenamedMixin.old` is deprecated, use `new` instead.')
            deprecated.old()
            self.assertEqual(len(recorded), 2)
            msgs = [str(warning.message) for warning in recorded]
            self.assertEqual(msgs, [
                '`DeprecatedMixin.old` is deprecated, use `new` instead.',
                '`RenamedMixin.old` is deprecated, use `new` instead.',
            ])
175 176 177 178 179 180 181 182 183 184 185 186 187


class DeprecationInstanceCheckTest(SimpleTestCase):
    def test_warning(self):
        class Manager(six.with_metaclass(DeprecationInstanceCheck)):
            alternative = 'fake.path.Foo'
            deprecation_warning = RemovedInNextVersionWarning

        msg = '`Manager` is deprecated, use `fake.path.Foo` instead.'
        with warnings.catch_warnings():
            warnings.simplefilter('error', category=RemovedInNextVersionWarning)
            with self.assertRaisesMessage(RemovedInNextVersionWarning, msg):
                isinstance(object, Manager)