/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2007-2012, 2016 Canonical Ltd
2553.1.1 by Robert Collins
Give Hooks names.
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
2553.1.1 by Robert Collins
Give Hooks names.
16
17
"""Tests for the core Hooks logic."""
18
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
19
from .. import (
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
20
    branch,
21
    errors,
5691.2.3 by Jelmer Vernooij
Fix tests.
22
    hooks as _mod_hooks,
5622.2.5 by Jelmer Vernooij
Add more tests for lazy hooks.
23
    pyutils,
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
24
    tests,
25
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
26
from ..hooks import (
4098.2.2 by Robert Collins
Review feedback.
27
    HookPoint,
2553.1.1 by Robert Collins
Give Hooks names.
28
    Hooks,
6734.1.15 by Jelmer Vernooij
Move errors for breezy.directory_service.
29
    UnknownHook,
5622.2.1 by Jelmer Vernooij
Some work on lazy hooks.
30
    install_lazy_named_hook,
4119.3.1 by Robert Collins
Create a single registry of all Hooks classes, removing the test suite knowledge of such hooks and allowing plugins to sensibly and safely define new hooks.
31
    known_hooks,
32
    known_hooks_key_to_object,
2553.1.1 by Robert Collins
Give Hooks names.
33
    )
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
34
35
6734.1.15 by Jelmer Vernooij
Move errors for breezy.directory_service.
36
class TestErrors(tests.TestCase):
37
38
    def test_unknown_hook(self):
39
        error = UnknownHook("branch", "foo")
40
        self.assertEqualDiff("The branch hook 'foo' is unknown in this version"
41
            " of breezy.",
42
            str(error))
43
        error = UnknownHook("tree", "bar")
44
        self.assertEqualDiff("The tree hook 'bar' is unknown in this version"
45
            " of breezy.",
46
            str(error))
47
48
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
49
class TestHooks(tests.TestCase):
2553.1.1 by Robert Collins
Give Hooks names.
50
4098.2.1 by Robert Collins
Allow self documenting hooks.
51
    def test_docs(self):
52
        """docs() should return something reasonable about the Hooks."""
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
53
        class MyHooks(Hooks):
54
            pass
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
55
        hooks = MyHooks("breezy.tests.test_hooks", "some_hooks")
4098.2.1 by Robert Collins
Allow self documenting hooks.
56
        hooks['legacy'] = []
5622.3.13 by Jelmer Vernooij
Catch deprecation warnings.
57
        hooks.add_hook('post_tip_change',
4098.2.1 by Robert Collins
Allow self documenting hooks.
58
            "Invoked after the tip of a branch changes. Called with "
5622.3.13 by Jelmer Vernooij
Catch deprecation warnings.
59
            "a ChangeBranchTipParams object.", (1, 4))
60
        hooks.add_hook('pre_tip_change',
4098.2.1 by Robert Collins
Allow self documenting hooks.
61
            "Invoked before the tip of a branch changes. Called with "
62
            "a ChangeBranchTipParams object. Hooks should raise "
63
            "TipChangeRejected to signal that a tip change is not permitted.",
64
            (1, 6), None)
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
65
        self.assertEqualDiff(
66
            "MyHooks\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
67
            "-------\n"
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
68
            "\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
69
            "legacy\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
70
            "~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
71
            "\n"
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
72
            "An old-style hook. For documentation see the __init__ method of 'MyHooks'\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
73
            "\n"
74
            "post_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
75
            "~~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
76
            "\n"
77
            "Introduced in: 1.4\n"
78
            "\n"
79
            "Invoked after the tip of a branch changes. Called with a\n"
80
            "ChangeBranchTipParams object.\n"
81
            "\n"
82
            "pre_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
83
            "~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
84
            "\n"
85
            "Introduced in: 1.6\n"
86
            "\n"
87
            "Invoked before the tip of a branch changes. Called with a\n"
88
            "ChangeBranchTipParams object. Hooks should raise TipChangeRejected to\n"
89
            "signal that a tip change is not permitted.\n", hooks.docs())
90
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
91
    def test_install_named_hook_raises_unknown_hook(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
92
        hooks = Hooks("breezy.tests.test_hooks", "some_hooks")
6734.1.15 by Jelmer Vernooij
Move errors for breezy.directory_service.
93
        self.assertRaises(UnknownHook, hooks.install_named_hook, 'silly',
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
94
                          None, "")
95
96
    def test_install_named_hook_appends_known_hook(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
97
        hooks = Hooks("breezy.tests.test_hooks", "some_hooks")
3256.2.32 by Ian Clatworthy
tweak hook tests to init the set_rh test when needed
98
        hooks['set_rh'] = []
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
99
        hooks.install_named_hook('set_rh', None, "demo")
100
        self.assertEqual(hooks['set_rh'], [None])
101
102
    def test_install_named_hook_and_retrieve_name(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
103
        hooks = Hooks("breezy.tests.test_hooks", "somehooks")
3256.2.32 by Ian Clatworthy
tweak hook tests to init the set_rh test when needed
104
        hooks['set_rh'] = []
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
105
        hooks.install_named_hook('set_rh', None, "demo")
3256.2.1 by Daniel Watkins
Added tests from Hooks.install_hook with an optional name parameter.
106
        self.assertEqual("demo", hooks.get_hook_name(None))
107
5622.4.2 by Jelmer Vernooij
Allow uninstalling hooks.
108
    def test_uninstall_named_hook(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
109
        hooks = Hooks("breezy.tests.test_hooks", "some_hooks")
5622.4.3 by Jelmer Vernooij
Remove all callables with specified label, not just the first.
110
        hooks.add_hook('set_rh', "Set revision history", (2, 0))
5622.4.2 by Jelmer Vernooij
Allow uninstalling hooks.
111
        hooks.install_named_hook('set_rh', None, "demo")
112
        self.assertEqual(1, len(hooks["set_rh"]))
113
        hooks.uninstall_named_hook("set_rh", "demo")
114
        self.assertEqual(0, len(hooks["set_rh"]))
115
5622.4.3 by Jelmer Vernooij
Remove all callables with specified label, not just the first.
116
    def test_uninstall_multiple_named_hooks(self):
117
        # Multiple callbacks with the same label all get removed
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
118
        hooks = Hooks("breezy.tests.test_hooks", "some_hooks")
5622.4.3 by Jelmer Vernooij
Remove all callables with specified label, not just the first.
119
        hooks.add_hook('set_rh', "Set revision history", (2, 0))
120
        hooks.install_named_hook('set_rh', 1, "demo")
121
        hooks.install_named_hook('set_rh', 2, "demo")
122
        hooks.install_named_hook('set_rh', 3, "othername")
123
        self.assertEqual(3, len(hooks["set_rh"]))
124
        hooks.uninstall_named_hook("set_rh", "demo")
125
        self.assertEqual(1, len(hooks["set_rh"]))
126
5622.4.2 by Jelmer Vernooij
Allow uninstalling hooks.
127
    def test_uninstall_named_hook_unknown_callable(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
128
        hooks = Hooks("breezy.tests.test_hooks", "some_hooks")
5622.4.2 by Jelmer Vernooij
Allow uninstalling hooks.
129
        hooks.add_hook('set_rh', "Set revision hsitory", (2, 0))
130
        self.assertRaises(KeyError, hooks.uninstall_named_hook, "set_rh",
131
            "demo")
132
133
    def test_uninstall_named_hook_raises_unknown_hook(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
134
        hooks = Hooks("breezy.tests.test_hooks", "some_hooks")
6734.1.15 by Jelmer Vernooij
Move errors for breezy.directory_service.
135
        self.assertRaises(UnknownHook, hooks.uninstall_named_hook, 'silly', "")
5622.4.2 by Jelmer Vernooij
Allow uninstalling hooks.
136
137
    def test_uninstall_named_hook_old_style(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
138
        hooks = Hooks("breezy.tests.test_hooks", "some_hooks")
5622.4.2 by Jelmer Vernooij
Allow uninstalling hooks.
139
        hooks["set_rh"] = []
140
        hooks.install_named_hook('set_rh', None, "demo")
141
        self.assertRaises(errors.UnsupportedOperation,
142
            hooks.uninstall_named_hook, "set_rh", "demo")
143
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
144
    hooks = Hooks("breezy.tests.test_hooks", "TestHooks.hooks")
5622.2.1 by Jelmer Vernooij
Some work on lazy hooks.
145
146
    def test_install_lazy_named_hook(self):
147
        # When the hook points are not yet registered the hook is
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
148
        # added to the _lazy_hooks dictionary in breezy.hooks.
5622.2.6 by Jelmer Vernooij
Put module/member information on Hooks, not individual hook points.
149
        self.hooks.add_hook('set_rh', "doc", (0, 15))
5622.2.1 by Jelmer Vernooij
Some work on lazy hooks.
150
        set_rh = lambda: None
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
151
        install_lazy_named_hook('breezy.tests.test_hooks',
5622.2.1 by Jelmer Vernooij
Some work on lazy hooks.
152
            'TestHooks.hooks', 'set_rh', set_rh, "demo")
5691.2.3 by Jelmer Vernooij
Fix tests.
153
        set_rh_lazy_hooks = _mod_hooks._lazy_hooks[
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
154
            ('breezy.tests.test_hooks', 'TestHooks.hooks', 'set_rh')]
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
155
        self.assertEqual(1, len(set_rh_lazy_hooks))
156
        self.assertEqual(set_rh, set_rh_lazy_hooks[0][0].get_obj())
157
        self.assertEqual("demo", set_rh_lazy_hooks[0][1])
5622.2.5 by Jelmer Vernooij
Add more tests for lazy hooks.
158
        self.assertEqual(list(TestHooks.hooks['set_rh']), [set_rh])
5622.2.1 by Jelmer Vernooij
Some work on lazy hooks.
159
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
160
    set_rh = lambda: None
161
162
    def test_install_named_hook_lazy(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
163
        hooks = Hooks("breezy.tests.hooks", "some_hooks")
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
164
        hooks['set_rh'] = HookPoint("set_rh", "doc", (0, 15), None)
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
165
        hooks.install_named_hook_lazy('set_rh', 'breezy.tests.test_hooks',
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
166
            'TestHooks.set_rh', "demo")
167
        self.assertEqual(list(hooks['set_rh']), [TestHooks.set_rh])
168
169
    def test_install_named_hook_lazy_old(self):
170
        # An exception is raised if a lazy hook is raised for
171
        # an old style hook point.
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
172
        hooks = Hooks("breezy.tests.hooks", "some_hooks")
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
173
        hooks['set_rh'] = []
174
        self.assertRaises(errors.UnsupportedOperation,
175
            hooks.install_named_hook_lazy,
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
176
            'set_rh', 'breezy.tests.test_hooks', 'TestHooks.set_rh',
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
177
            "demo")
178
5622.2.5 by Jelmer Vernooij
Add more tests for lazy hooks.
179
    def test_valid_lazy_hooks(self):
180
        # Make sure that all the registered lazy hooks are referring to existing
181
        # hook points which allow lazy registration.
6759.2.1 by Martin
One last dict.iteritems() in hooks tests
182
        for key, callbacks in _mod_hooks._lazy_hooks.items():
5622.2.8 by Jelmer Vernooij
more tests.
183
            (module_name, member_name, hook_name) = key
5622.2.5 by Jelmer Vernooij
Add more tests for lazy hooks.
184
            obj = pyutils.get_named_object(module_name, member_name)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
185
            self.assertEqual(obj._module, module_name)
186
            self.assertEqual(obj._member_name, member_name)
5622.2.6 by Jelmer Vernooij
Put module/member information on Hooks, not individual hook points.
187
            self.assertTrue(hook_name in obj)
5622.2.8 by Jelmer Vernooij
more tests.
188
            self.assertIs(callbacks, obj[hook_name]._callbacks)
5622.2.5 by Jelmer Vernooij
Add more tests for lazy hooks.
189
4098.2.1 by Robert Collins
Allow self documenting hooks.
190
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
191
class TestHook(tests.TestCase):
4098.2.1 by Robert Collins
Allow self documenting hooks.
192
193
    def test___init__(self):
194
        doc = ("Invoked after changing the tip of a branch object. Called with"
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
195
            "a breezy.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
196
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
197
        self.assertEqual(doc, hook.__doc__)
198
        self.assertEqual("post_tip_change", hook.name)
199
        self.assertEqual((0, 15), hook.introduced)
200
        self.assertEqual(None, hook.deprecated)
201
        self.assertEqual([], list(hook))
202
203
    def test_docs(self):
204
        doc = ("Invoked after changing the tip of a branch object. Called with"
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
205
            " a breezy.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
206
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
207
        self.assertEqual("post_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
208
            "~~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
209
            "\n"
210
            "Introduced in: 0.15\n"
211
            "\n"
212
            "Invoked after changing the tip of a branch object. Called with a\n"
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
213
            "breezy.branch.PostChangeBranchTipParams object\n", hook.docs())
4098.2.1 by Robert Collins
Allow self documenting hooks.
214
215
    def test_hook(self):
4098.2.2 by Robert Collins
Review feedback.
216
        hook = HookPoint("foo", "no docs", None, None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
217
        def callback():
218
            pass
219
        hook.hook(callback, "my callback")
220
        self.assertEqual([callback], list(hook))
221
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
222
    def lazy_callback():
223
        pass
224
225
    def test_lazy_hook(self):
226
        hook = HookPoint("foo", "no docs", None, None)
227
        hook.hook_lazy(
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
228
            "breezy.tests.test_hooks", "TestHook.lazy_callback",
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
229
            "my callback")
230
        self.assertEqual([TestHook.lazy_callback], list(hook))
231
5622.4.2 by Jelmer Vernooij
Allow uninstalling hooks.
232
    def test_uninstall(self):
233
        hook = HookPoint("foo", "no docs", None, None)
234
        hook.hook_lazy(
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
235
            "breezy.tests.test_hooks", "TestHook.lazy_callback",
5622.4.2 by Jelmer Vernooij
Allow uninstalling hooks.
236
            "my callback")
237
        self.assertEqual([TestHook.lazy_callback], list(hook))
238
        hook.uninstall("my callback")
239
        self.assertEqual([], list(hook))
240
241
    def test_uninstall_unknown(self):
242
        hook = HookPoint("foo", "no docs", None, None)
243
        self.assertRaises(KeyError, hook.uninstall, "my callback")
244
4098.2.1 by Robert Collins
Allow self documenting hooks.
245
    def test___repr(self):
246
        # The repr should list all the callbacks, with names.
4098.2.2 by Robert Collins
Review feedback.
247
        hook = HookPoint("foo", "no docs", None, None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
248
        def callback():
249
            pass
250
        hook.hook(callback, "my callback")
251
        callback_repr = repr(callback)
252
        self.assertEqual(
4098.2.2 by Robert Collins
Review feedback.
253
            '<HookPoint(foo), callbacks=[%s(my callback)]>' %
4098.2.1 by Robert Collins
Allow self documenting hooks.
254
            callback_repr, repr(hook))
4119.3.1 by Robert Collins
Create a single registry of all Hooks classes, removing the test suite knowledge of such hooks and allowing plugins to sensibly and safely define new hooks.
255
256
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
257
class TestHookRegistry(tests.TestCase):
4119.3.1 by Robert Collins
Create a single registry of all Hooks classes, removing the test suite knowledge of such hooks and allowing plugins to sensibly and safely define new hooks.
258
259
    def test_items_are_reasonable_keys(self):
260
        # All the items in the known_hooks registry need to map from
261
        # (module_name, member_name) tuples to the callable used to get an
4230.1.2 by James Westby
Update the comments based on those in the test.
262
        # empty Hooks for that attribute. This is used to support the test
4119.3.1 by Robert Collins
Create a single registry of all Hooks classes, removing the test suite knowledge of such hooks and allowing plugins to sensibly and safely define new hooks.
263
        # suite which needs to generate empty hooks (and HookPoints) to ensure
264
        # isolation and prevent tests failing spuriously.
265
        for key, factory in known_hooks.items():
266
            self.assertTrue(callable(factory),
267
                "The factory(%r) for %r is not callable" % (factory, key))
268
            obj = known_hooks_key_to_object(key)
269
            self.assertIsInstance(obj, Hooks)
5622.3.11 by Jelmer Vernooij
Revert some unnecessary changes.
270
            new_hooks = factory()
4119.3.1 by Robert Collins
Create a single registry of all Hooks classes, removing the test suite knowledge of such hooks and allowing plugins to sensibly and safely define new hooks.
271
            self.assertIsInstance(obj, Hooks)
272
            self.assertEqual(type(obj), type(new_hooks))
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
273
            self.assertEqual("No hook name", new_hooks.get_hook_name(None))
4119.3.1 by Robert Collins
Create a single registry of all Hooks classes, removing the test suite knowledge of such hooks and allowing plugins to sensibly and safely define new hooks.
274
275
    def test_known_hooks_key_to_object(self):
276
        self.assertIs(branch.Branch.hooks,
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
277
            known_hooks_key_to_object(('breezy.branch', 'Branch.hooks')))
4119.3.1 by Robert Collins
Create a single registry of all Hooks classes, removing the test suite knowledge of such hooks and allowing plugins to sensibly and safely define new hooks.
278
279
    def test_known_hooks_key_to_parent_and_attribute(self):
280
        self.assertEqual((branch.Branch, 'hooks'),
5436.2.1 by Andrew Bennetts
Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.
281
            known_hooks.key_to_parent_and_attribute(
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
282
            ('breezy.branch', 'Branch.hooks')))
4119.3.1 by Robert Collins
Create a single registry of all Hooks classes, removing the test suite knowledge of such hooks and allowing plugins to sensibly and safely define new hooks.
283
        self.assertEqual((branch, 'Branch'),
5436.2.1 by Andrew Bennetts
Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.
284
            known_hooks.key_to_parent_and_attribute(
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
285
            ('breezy.branch', 'Branch')))