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