/brz/remove-bazaar

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