~bzr-pqm/bzr/bzr.dev

3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
1
# Copyright (C) 2006, 2007, 2009 Canonical Ltd
1534.2.1 by Robert Collins
Implement deprecated_method
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1534.2.1 by Robert Collins
Implement deprecated_method
16
17
"""Symbol versioning tests."""
18
3427.5.3 by John Arbash Meinel
Update the activate_deprecation_warnings so it can be skipped if there is already an error set.
19
import warnings
20
21
from bzrlib import symbol_versioning
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
22
from bzrlib.symbol_versioning import (
23
    deprecated_function,
24
    deprecated_in,
25
    deprecated_list,
26
    deprecated_method,
27
    )
1534.2.1 by Robert Collins
Implement deprecated_method
28
from bzrlib.tests import TestCase
29
30
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
31
@deprecated_function(deprecated_in((0, 7, 0)))
32
def sample_deprecated_function():
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
33
    """Deprecated function docstring."""
1534.2.2 by Robert Collins
Implement deprecated_function.
34
    return 1
35
1534.2.1 by Robert Collins
Implement deprecated_method
36
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
37
a_deprecated_list = symbol_versioning.deprecated_list(deprecated_in((0, 9, 0)),
1836.1.12 by John Arbash Meinel
Move ignores into a file of their own, make DEFAULT_IGNORE a deprecated list. Create deprecated_list in symbol versioning.
38
    'a_deprecated_list', ['one'], extra="Don't use me")
39
40
2227.1.2 by mbp at sourcefrog
Add a simple DeprecatedDict class
41
a_deprecated_dict = symbol_versioning.DeprecatedDict(
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
42
    deprecated_in((0, 14, 0)),
2227.1.2 by mbp at sourcefrog
Add a simple DeprecatedDict class
43
    'a_deprecated_dict',
44
    dict(a=42),
45
    advice='Pull the other one!',
46
    )
47
48
1534.2.1 by Robert Collins
Implement deprecated_method
49
class TestDeprecationWarnings(TestCase):
50
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
51
    def capture_warning(self, message, category, stacklevel=None):
52
        self._warnings.append((message, category, stacklevel))
1534.2.1 by Robert Collins
Implement deprecated_method
53
54
    def setUp(self):
55
        super(TestDeprecationWarnings, self).setUp()
56
        self._warnings = []
57
    
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
58
    @deprecated_method(deprecated_in((0, 7, 0)))
1534.2.1 by Robert Collins
Implement deprecated_method
59
    def deprecated_method(self):
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
60
        """Deprecated method docstring.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
61
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
62
        This might explain stuff.
63
        """
1534.2.2 by Robert Collins
Implement deprecated_function.
64
        return 1
1534.2.1 by Robert Collins
Implement deprecated_method
65
2825.3.3 by Martin Pool
Add basic test for calling deprecated static methods
66
    @staticmethod
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
67
    @deprecated_function(deprecated_in((0, 7, 0)))
2825.3.3 by Martin Pool
Add basic test for calling deprecated static methods
68
    def deprecated_static():
69
        """Deprecated static."""
70
        return 1
71
72
    def test_deprecated_static(self):
2825.3.4 by Martin Pool
Better explanation of deprecation
73
        # XXX: The results are not quite right because the class name is not
74
        # shown - however it is enough to give people a good indication of
75
        # where the problem is.
2825.3.3 by Martin Pool
Add basic test for calling deprecated static methods
76
        expected_warning = (
77
            "bzrlib.tests.test_symbol_versioning."
78
            "deprecated_static "
79
            "was deprecated in version 0.7.", DeprecationWarning, 2)
80
        expected_docstring = (
81
            'Deprecated static.\n'
82
            '\n'
83
            'This function was deprecated in version 0.7.\n'
84
            )
85
        self.check_deprecated_callable(
86
            expected_warning, expected_docstring,
87
            "deprecated_static",
88
            "bzrlib.tests.test_symbol_versioning",
89
            self.deprecated_static)
90
1534.2.1 by Robert Collins
Implement deprecated_method
91
    def test_deprecated_method(self):
1534.2.2 by Robert Collins
Implement deprecated_function.
92
        expected_warning = (
93
            "bzrlib.tests.test_symbol_versioning."
94
            "TestDeprecationWarnings.deprecated_method "
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
95
            "was deprecated in version 0.7.", DeprecationWarning, 2)
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
96
        expected_docstring = ('Deprecated method docstring.\n'
3943.8.2 by Marius Kruger
fix tests relying on trailing whitespace by replacing it with \x20.
97
                              '\n'
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
98
                              '        This might explain stuff.\n'
99
                              '        \n'
100
                              '        This method was deprecated in version 0.7.\n'
101
                              '        ')
102
        self.check_deprecated_callable(expected_warning, expected_docstring,
1534.2.5 by Robert Collins
Set the __name__ attribute on decorated methods and functions.
103
                                       "deprecated_method",
1534.1.3 by Robert Collins
Bugfix the symbol_versioning deprecation decorators to update the
104
                                       "bzrlib.tests.test_symbol_versioning",
1534.2.2 by Robert Collins
Implement deprecated_function.
105
                                       self.deprecated_method)
106
107
    def test_deprecated_function(self):
108
        expected_warning = (
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
109
            "bzrlib.tests.test_symbol_versioning.sample_deprecated_function "
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
110
            "was deprecated in version 0.7.", DeprecationWarning, 2)
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
111
        expected_docstring = ('Deprecated function docstring.\n'
112
                              '\n'
113
                              'This function was deprecated in version 0.7.\n'
114
                              )
115
        self.check_deprecated_callable(expected_warning, expected_docstring,
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
116
                                       "sample_deprecated_function",
1534.1.3 by Robert Collins
Bugfix the symbol_versioning deprecation decorators to update the
117
                                       "bzrlib.tests.test_symbol_versioning",
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
118
                                       sample_deprecated_function)
1534.2.2 by Robert Collins
Implement deprecated_function.
119
1836.1.12 by John Arbash Meinel
Move ignores into a file of their own, make DEFAULT_IGNORE a deprecated list. Create deprecated_list in symbol versioning.
120
    def test_deprecated_list(self):
121
        expected_warning = (
122
            "Modifying a_deprecated_list was deprecated in version 0.9."
123
            " Don't use me", DeprecationWarning, 3)
124
        old_warning_method = symbol_versioning.warn
125
        try:
126
            symbol_versioning.set_warning_method(self.capture_warning)
127
            self.assertEqual(['one'], a_deprecated_list)
128
            self.assertEqual([], self._warnings)
129
130
            a_deprecated_list.append('foo')
131
            self.assertEqual([expected_warning], self._warnings)
132
            self.assertEqual(['one', 'foo'], a_deprecated_list)
133
134
            a_deprecated_list.extend(['bar', 'baz'])
135
            self.assertEqual([expected_warning]*2, self._warnings)
136
            self.assertEqual(['one', 'foo', 'bar', 'baz'], a_deprecated_list)
137
138
            a_deprecated_list.insert(1, 'xxx')
139
            self.assertEqual([expected_warning]*3, self._warnings)
140
            self.assertEqual(['one', 'xxx', 'foo', 'bar', 'baz'], a_deprecated_list)
141
142
            a_deprecated_list.remove('foo')
143
            self.assertEqual([expected_warning]*4, self._warnings)
144
            self.assertEqual(['one', 'xxx', 'bar', 'baz'], a_deprecated_list)
145
146
            val = a_deprecated_list.pop()
147
            self.assertEqual([expected_warning]*5, self._warnings)
148
            self.assertEqual('baz', val)
149
            self.assertEqual(['one', 'xxx', 'bar'], a_deprecated_list)
150
151
            val = a_deprecated_list.pop(1)
152
            self.assertEqual([expected_warning]*6, self._warnings)
153
            self.assertEqual('xxx', val)
154
            self.assertEqual(['one', 'bar'], a_deprecated_list)
155
        finally:
156
            symbol_versioning.set_warning_method(old_warning_method)
157
2227.1.2 by mbp at sourcefrog
Add a simple DeprecatedDict class
158
    def test_deprecated_dict(self):
159
        expected_warning = (
160
            "access to a_deprecated_dict was deprecated in version 0.14."
161
            " Pull the other one!", DeprecationWarning, 2)
162
        old_warning_method = symbol_versioning.warn
163
        try:
164
            symbol_versioning.set_warning_method(self.capture_warning)
165
            self.assertEqual(len(a_deprecated_dict), 1)
166
            self.assertEqual([expected_warning], self._warnings)
167
168
            a_deprecated_dict['b'] = 42
169
            self.assertEqual(a_deprecated_dict['b'], 42)
170
            self.assertTrue('b' in a_deprecated_dict)
171
            del a_deprecated_dict['b']
172
            self.assertFalse('b' in a_deprecated_dict)
173
            self.assertEqual([expected_warning] * 6, self._warnings)
174
        finally:
175
            symbol_versioning.set_warning_method(old_warning_method)
176
177
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
178
    def check_deprecated_callable(self, expected_warning, expected_docstring,
1534.1.3 by Robert Collins
Bugfix the symbol_versioning deprecation decorators to update the
179
                                  expected_name, expected_module,
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
180
                                  deprecated_callable):
1534.2.1 by Robert Collins
Implement deprecated_method
181
        old_warning_method = symbol_versioning.warn
182
        try:
183
            symbol_versioning.set_warning_method(self.capture_warning)
1534.2.2 by Robert Collins
Implement deprecated_function.
184
            self.assertEqual(1, deprecated_callable())
1534.2.1 by Robert Collins
Implement deprecated_method
185
            self.assertEqual([expected_warning], self._warnings)
1534.2.2 by Robert Collins
Implement deprecated_function.
186
            deprecated_callable()
1534.2.1 by Robert Collins
Implement deprecated_method
187
            self.assertEqual([expected_warning, expected_warning],
188
                             self._warnings)
1534.2.3 by Robert Collins
decorate docstrings in deprecated functions.
189
            self.assertEqualDiff(expected_docstring, deprecated_callable.__doc__)
1534.2.5 by Robert Collins
Set the __name__ attribute on decorated methods and functions.
190
            self.assertEqualDiff(expected_name, deprecated_callable.__name__)
1534.1.3 by Robert Collins
Bugfix the symbol_versioning deprecation decorators to update the
191
            self.assertEqualDiff(expected_module, deprecated_callable.__module__)
1581.1.1 by Robert Collins
Bugfix aliases to be backwards compatible with plugins providing command.run_argv.
192
            self.assertTrue(deprecated_callable.is_deprecated)
1534.2.1 by Robert Collins
Implement deprecated_method
193
        finally:
194
            symbol_versioning.set_warning_method(old_warning_method)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
195
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
196
    def test_deprecated_passed(self):
197
        self.assertEqual(True, symbol_versioning.deprecated_passed(None))
198
        self.assertEqual(True, symbol_versioning.deprecated_passed(True))
199
        self.assertEqual(True, symbol_versioning.deprecated_passed(False))
200
        self.assertEqual(False,
201
                         symbol_versioning.deprecated_passed(
1534.4.32 by Robert Collins
Rename deprecated_nonce to DEPRECATED_PARAMETER
202
                            symbol_versioning.DEPRECATED_PARAMETER))
1982.3.1 by Robert Collins
New utility function symbol_versioning.deprecation_string. Returns the
203
204
    def test_deprecation_string(self):
205
        """We can get a deprecation string for a method or function."""
206
        self.assertEqual('bzrlib.tests.test_symbol_versioning.'
207
            'TestDeprecationWarnings.test_deprecation_string was deprecated in '
208
            'version 0.11.',
209
            symbol_versioning.deprecation_string(
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
210
            self.test_deprecation_string,
211
            deprecated_in((0, 11, 0))))
1982.3.1 by Robert Collins
New utility function symbol_versioning.deprecation_string. Returns the
212
        self.assertEqual('bzrlib.symbol_versioning.deprecated_function was '
213
            'deprecated in version 0.11.',
214
            symbol_versioning.deprecation_string(
215
                symbol_versioning.deprecated_function,
3948.3.1 by Martin Pool
Remove old static deprecation template strings, and update style of their tests
216
                deprecated_in((0, 11, 0))))
3427.5.3 by John Arbash Meinel
Update the activate_deprecation_warnings so it can be skipped if there is already an error set.
217
218
219
class TestSuppressAndActivate(TestCase):
220
221
    def setUp(self):
4153.1.2 by Andrew Bennetts
Add missing TestCase.setUp upcalls.
222
        TestCase.setUp(self)
3427.5.3 by John Arbash Meinel
Update the activate_deprecation_warnings so it can be skipped if there is already an error set.
223
        existing_filters = list(warnings.filters)
224
        def restore():
225
            warnings.filters[:] = existing_filters
226
        self.addCleanup(restore)
3427.5.5 by John Arbash Meinel
Disable suppression if there is already a filter present for Warnings
227
        # Clean out the filters so we have a clean slate.
228
        warnings.resetwarnings()
3427.5.3 by John Arbash Meinel
Update the activate_deprecation_warnings so it can be skipped if there is already an error set.
229
230
    def assertFirstWarning(self, action, category):
231
        """Test the first warning in the filters is correct"""
232
        first = warnings.filters[0]
233
        self.assertEqual((action, category), (first[0], first[2]))
234
235
    def test_suppress_deprecation_warnings(self):
236
        """suppress_deprecation_warnings sets DeprecationWarning to ignored."""
237
        symbol_versioning.suppress_deprecation_warnings()
238
        self.assertFirstWarning('ignore', DeprecationWarning)
239
3427.5.5 by John Arbash Meinel
Disable suppression if there is already a filter present for Warnings
240
    def test_suppress_deprecation_with_warning_filter(self):
241
        """don't suppress if we already have a filter"""
3427.5.7 by John Arbash Meinel
Bring back always in the form of 'override'.
242
        warnings.filterwarnings('error', category=Warning)
243
        self.assertFirstWarning('error', Warning)
3427.5.5 by John Arbash Meinel
Disable suppression if there is already a filter present for Warnings
244
        self.assertEqual(1, len(warnings.filters))
3427.5.7 by John Arbash Meinel
Bring back always in the form of 'override'.
245
        symbol_versioning.suppress_deprecation_warnings(override=False)
246
        self.assertFirstWarning('error', Warning)
3427.5.5 by John Arbash Meinel
Disable suppression if there is already a filter present for Warnings
247
        self.assertEqual(1, len(warnings.filters))
248
249
    def test_suppress_deprecation_with_filter(self):
250
        """don't suppress if we already have a filter"""
3427.5.7 by John Arbash Meinel
Bring back always in the form of 'override'.
251
        warnings.filterwarnings('error', category=DeprecationWarning)
252
        self.assertFirstWarning('error', DeprecationWarning)
253
        self.assertEqual(1, len(warnings.filters))
254
        symbol_versioning.suppress_deprecation_warnings(override=False)
255
        self.assertFirstWarning('error', DeprecationWarning)
256
        self.assertEqual(1, len(warnings.filters))
257
        symbol_versioning.suppress_deprecation_warnings(override=True)
258
        self.assertFirstWarning('ignore', DeprecationWarning)
259
        self.assertEqual(2, len(warnings.filters))
3427.5.5 by John Arbash Meinel
Disable suppression if there is already a filter present for Warnings
260
3427.5.3 by John Arbash Meinel
Update the activate_deprecation_warnings so it can be skipped if there is already an error set.
261
    def test_activate_deprecation_no_error(self):
262
        # First nuke the filters, so we know it is clean
3427.5.6 by John Arbash Meinel
remove the parameter from activate, and just have it always False
263
        symbol_versioning.activate_deprecation_warnings()
3427.5.3 by John Arbash Meinel
Update the activate_deprecation_warnings so it can be skipped if there is already an error set.
264
        self.assertFirstWarning('default', DeprecationWarning)
265
266
    def test_activate_deprecation_with_error(self):
267
        # First nuke the filters, so we know it is clean
268
        # Add a warning == error rule
269
        warnings.filterwarnings('error', category=Warning)
270
        self.assertFirstWarning('error', Warning)
271
        self.assertEqual(1, len(warnings.filters))
3427.5.7 by John Arbash Meinel
Bring back always in the form of 'override'.
272
        symbol_versioning.activate_deprecation_warnings(override=False)
3427.5.3 by John Arbash Meinel
Update the activate_deprecation_warnings so it can be skipped if there is already an error set.
273
        # There should not be a new warning
274
        self.assertFirstWarning('error', Warning)
275
        self.assertEqual(1, len(warnings.filters))
276
277
    def test_activate_deprecation_with_DW_error(self):
278
        # First nuke the filters, so we know it is clean
279
        # Add a warning == error rule
280
        warnings.filterwarnings('error', category=DeprecationWarning)
281
        self.assertFirstWarning('error', DeprecationWarning)
282
        self.assertEqual(1, len(warnings.filters))
3427.5.7 by John Arbash Meinel
Bring back always in the form of 'override'.
283
        symbol_versioning.activate_deprecation_warnings(override=False)
3427.5.3 by John Arbash Meinel
Update the activate_deprecation_warnings so it can be skipped if there is already an error set.
284
        # There should not be a new warning
285
        self.assertFirstWarning('error', DeprecationWarning)
286
        self.assertEqual(1, len(warnings.filters))
3427.5.7 by John Arbash Meinel
Bring back always in the form of 'override'.
287
        symbol_versioning.activate_deprecation_warnings(override=True)
288
        self.assertFirstWarning('default', DeprecationWarning)
289
        self.assertEqual(2, len(warnings.filters))