~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_hooks.py

  • Committer: John Arbash Meinel
  • Date: 2009-03-04 18:31:31 UTC
  • mto: (0.17.34 trunk)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090304183131-p433dz5coqrmv8pw
Now using a zlib compressed format.
We encode the length of the compressed and uncompressed content,
and then compress the actual content.
Need to do some testing with real data to see if this is efficient
or if another structure would be better.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
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
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
"""Tests for the core Hooks logic."""
18
 
 
19
 
from bzrlib import (
20
 
    branch,
21
 
    errors,
22
 
    hooks as _mod_hooks,
23
 
    pyutils,
24
 
    tests,
25
 
    )
26
 
from bzrlib.hooks import (
27
 
    HookPoint,
28
 
    Hooks,
29
 
    install_lazy_named_hook,
30
 
    known_hooks,
31
 
    known_hooks_key_to_object,
32
 
    known_hooks_key_to_parent_and_attribute,
33
 
    )
34
 
from bzrlib.symbol_versioning import (
35
 
    deprecated_in,
36
 
    )
37
 
 
38
 
 
39
 
class TestHooks(tests.TestCase):
40
 
 
41
 
    def test_create_hook_first(self):
42
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
43
 
        doc = ("Invoked after changing the tip of a branch object. Called with"
44
 
            "a bzrlib.branch.PostChangeBranchTipParams object")
45
 
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
46
 
        self.applyDeprecated(deprecated_in((2, 4)), hooks.create_hook, hook)
47
 
        self.assertEqual(hook, hooks['post_tip_change'])
48
 
 
49
 
    def test_create_hook_name_collision_errors(self):
50
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
51
 
        doc = ("Invoked after changing the tip of a branch object. Called with"
52
 
            "a bzrlib.branch.PostChangeBranchTipParams object")
53
 
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
54
 
        hook2 = HookPoint("post_tip_change", None, None, None)
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)
58
 
        self.assertEqual(hook, hooks['post_tip_change'])
59
 
 
60
 
    def test_docs(self):
61
 
        """docs() should return something reasonable about the Hooks."""
62
 
        class MyHooks(Hooks):
63
 
            pass
64
 
        hooks = MyHooks("bzrlib.tests.test_hooks", "some_hooks")
65
 
        hooks['legacy'] = []
66
 
        hooks.add_hook('post_tip_change',
67
 
            "Invoked after the tip of a branch changes. Called with "
68
 
            "a ChangeBranchTipParams object.", (1, 4))
69
 
        hooks.add_hook('pre_tip_change',
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)
74
 
        self.assertEqualDiff(
75
 
            "MyHooks\n"
76
 
            "-------\n"
77
 
            "\n"
78
 
            "legacy\n"
79
 
            "~~~~~~\n"
80
 
            "\n"
81
 
            "An old-style hook. For documentation see the __init__ method of 'MyHooks'\n"
82
 
            "\n"
83
 
            "post_tip_change\n"
84
 
            "~~~~~~~~~~~~~~~\n"
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"
92
 
            "~~~~~~~~~~~~~~\n"
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
 
 
100
 
    def test_install_named_hook_raises_unknown_hook(self):
101
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
102
 
        self.assertRaises(errors.UnknownHook, hooks.install_named_hook, 'silly',
103
 
                          None, "")
104
 
 
105
 
    def test_install_named_hook_appends_known_hook(self):
106
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
107
 
        hooks['set_rh'] = []
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):
112
 
        hooks = Hooks("bzrlib.tests.test_hooks", "somehooks")
113
 
        hooks['set_rh'] = []
114
 
        hooks.install_named_hook('set_rh', None, "demo")
115
 
        self.assertEqual("demo", hooks.get_hook_name(None))
116
 
 
117
 
    def test_uninstall_named_hook(self):
118
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
119
 
        hooks.add_hook('set_rh', "Set revision history", (2, 0))
120
 
        hooks.install_named_hook('set_rh', None, "demo")
121
 
        self.assertEqual(1, len(hooks["set_rh"]))
122
 
        hooks.uninstall_named_hook("set_rh", "demo")
123
 
        self.assertEqual(0, len(hooks["set_rh"]))
124
 
 
125
 
    def test_uninstall_multiple_named_hooks(self):
126
 
        # Multiple callbacks with the same label all get removed
127
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
128
 
        hooks.add_hook('set_rh', "Set revision history", (2, 0))
129
 
        hooks.install_named_hook('set_rh', 1, "demo")
130
 
        hooks.install_named_hook('set_rh', 2, "demo")
131
 
        hooks.install_named_hook('set_rh', 3, "othername")
132
 
        self.assertEqual(3, len(hooks["set_rh"]))
133
 
        hooks.uninstall_named_hook("set_rh", "demo")
134
 
        self.assertEqual(1, len(hooks["set_rh"]))
135
 
 
136
 
    def test_uninstall_named_hook_unknown_callable(self):
137
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
138
 
        hooks.add_hook('set_rh', "Set revision hsitory", (2, 0))
139
 
        self.assertRaises(KeyError, hooks.uninstall_named_hook, "set_rh",
140
 
            "demo")
141
 
 
142
 
    def test_uninstall_named_hook_raises_unknown_hook(self):
143
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
144
 
        self.assertRaises(errors.UnknownHook, hooks.uninstall_named_hook,
145
 
            'silly', "")
146
 
 
147
 
    def test_uninstall_named_hook_old_style(self):
148
 
        hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
149
 
        hooks["set_rh"] = []
150
 
        hooks.install_named_hook('set_rh', None, "demo")
151
 
        self.assertRaises(errors.UnsupportedOperation,
152
 
            hooks.uninstall_named_hook, "set_rh", "demo")
153
 
 
154
 
    hooks = Hooks("bzrlib.tests.test_hooks", "TestHooks.hooks")
155
 
 
156
 
    def test_install_lazy_named_hook(self):
157
 
        # When the hook points are not yet registered the hook is
158
 
        # added to the _lazy_hooks dictionary in bzrlib.hooks.
159
 
        self.hooks.add_hook('set_rh', "doc", (0, 15))
160
 
        set_rh = lambda: None
161
 
        install_lazy_named_hook('bzrlib.tests.test_hooks',
162
 
            'TestHooks.hooks', 'set_rh', set_rh, "demo")
163
 
        set_rh_lazy_hooks = _mod_hooks._lazy_hooks[
164
 
            ('bzrlib.tests.test_hooks', 'TestHooks.hooks', 'set_rh')]
165
 
        self.assertEquals(1, len(set_rh_lazy_hooks))
166
 
        self.assertEquals(set_rh, set_rh_lazy_hooks[0][0].get_obj())
167
 
        self.assertEquals("demo", set_rh_lazy_hooks[0][1])
168
 
        self.assertEqual(list(TestHooks.hooks['set_rh']), [set_rh])
169
 
 
170
 
    set_rh = lambda: None
171
 
 
172
 
    def test_install_named_hook_lazy(self):
173
 
        hooks = Hooks("bzrlib.tests.hooks", "some_hooks")
174
 
        hooks['set_rh'] = HookPoint("set_rh", "doc", (0, 15), None)
175
 
        hooks.install_named_hook_lazy('set_rh', 'bzrlib.tests.test_hooks',
176
 
            'TestHooks.set_rh', "demo")
177
 
        self.assertEqual(list(hooks['set_rh']), [TestHooks.set_rh])
178
 
 
179
 
    def test_install_named_hook_lazy_old(self):
180
 
        # An exception is raised if a lazy hook is raised for
181
 
        # an old style hook point.
182
 
        hooks = Hooks("bzrlib.tests.hooks", "some_hooks")
183
 
        hooks['set_rh'] = []
184
 
        self.assertRaises(errors.UnsupportedOperation,
185
 
            hooks.install_named_hook_lazy,
186
 
            'set_rh', 'bzrlib.tests.test_hooks', 'TestHooks.set_rh',
187
 
            "demo")
188
 
 
189
 
    def test_valid_lazy_hooks(self):
190
 
        # Make sure that all the registered lazy hooks are referring to existing
191
 
        # hook points which allow lazy registration.
192
 
        for key, callbacks in _mod_hooks._lazy_hooks.iteritems():
193
 
            (module_name, member_name, hook_name) = key
194
 
            obj = pyutils.get_named_object(module_name, member_name)
195
 
            self.assertEquals(obj._module, module_name)
196
 
            self.assertEquals(obj._member_name, member_name)
197
 
            self.assertTrue(hook_name in obj)
198
 
            self.assertIs(callbacks, obj[hook_name]._callbacks)
199
 
 
200
 
 
201
 
class TestHook(tests.TestCase):
202
 
 
203
 
    def test___init__(self):
204
 
        doc = ("Invoked after changing the tip of a branch object. Called with"
205
 
            "a bzrlib.branch.PostChangeBranchTipParams object")
206
 
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
207
 
        self.assertEqual(doc, hook.__doc__)
208
 
        self.assertEqual("post_tip_change", hook.name)
209
 
        self.assertEqual((0, 15), hook.introduced)
210
 
        self.assertEqual(None, hook.deprecated)
211
 
        self.assertEqual([], list(hook))
212
 
 
213
 
    def test_docs(self):
214
 
        doc = ("Invoked after changing the tip of a branch object. Called with"
215
 
            " a bzrlib.branch.PostChangeBranchTipParams object")
216
 
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
217
 
        self.assertEqual("post_tip_change\n"
218
 
            "~~~~~~~~~~~~~~~\n"
219
 
            "\n"
220
 
            "Introduced in: 0.15\n"
221
 
            "\n"
222
 
            "Invoked after changing the tip of a branch object. Called with a\n"
223
 
            "bzrlib.branch.PostChangeBranchTipParams object\n", hook.docs())
224
 
 
225
 
    def test_hook(self):
226
 
        hook = HookPoint("foo", "no docs", None, None)
227
 
        def callback():
228
 
            pass
229
 
        hook.hook(callback, "my callback")
230
 
        self.assertEqual([callback], list(hook))
231
 
 
232
 
    def lazy_callback():
233
 
        pass
234
 
 
235
 
    def test_lazy_hook(self):
236
 
        hook = HookPoint("foo", "no docs", None, None)
237
 
        hook.hook_lazy(
238
 
            "bzrlib.tests.test_hooks", "TestHook.lazy_callback",
239
 
            "my callback")
240
 
        self.assertEqual([TestHook.lazy_callback], list(hook))
241
 
 
242
 
    def test_uninstall(self):
243
 
        hook = HookPoint("foo", "no docs", None, None)
244
 
        hook.hook_lazy(
245
 
            "bzrlib.tests.test_hooks", "TestHook.lazy_callback",
246
 
            "my callback")
247
 
        self.assertEqual([TestHook.lazy_callback], list(hook))
248
 
        hook.uninstall("my callback")
249
 
        self.assertEqual([], list(hook))
250
 
 
251
 
    def test_uninstall_unknown(self):
252
 
        hook = HookPoint("foo", "no docs", None, None)
253
 
        self.assertRaises(KeyError, hook.uninstall, "my callback")
254
 
 
255
 
    def test___repr(self):
256
 
        # The repr should list all the callbacks, with names.
257
 
        hook = HookPoint("foo", "no docs", None, None)
258
 
        def callback():
259
 
            pass
260
 
        hook.hook(callback, "my callback")
261
 
        callback_repr = repr(callback)
262
 
        self.assertEqual(
263
 
            '<HookPoint(foo), callbacks=[%s(my callback)]>' %
264
 
            callback_repr, repr(hook))
265
 
 
266
 
 
267
 
class TestHookRegistry(tests.TestCase):
268
 
 
269
 
    def test_items_are_reasonable_keys(self):
270
 
        # All the items in the known_hooks registry need to map from
271
 
        # (module_name, member_name) tuples to the callable used to get an
272
 
        # empty Hooks for that attribute. This is used to support the test
273
 
        # suite which needs to generate empty hooks (and HookPoints) to ensure
274
 
        # isolation and prevent tests failing spuriously.
275
 
        for key, factory in known_hooks.items():
276
 
            self.assertTrue(callable(factory),
277
 
                "The factory(%r) for %r is not callable" % (factory, key))
278
 
            obj = known_hooks_key_to_object(key)
279
 
            self.assertIsInstance(obj, Hooks)
280
 
            new_hooks = factory()
281
 
            self.assertIsInstance(obj, Hooks)
282
 
            self.assertEqual(type(obj), type(new_hooks))
283
 
            self.assertEqual("No hook name", new_hooks.get_hook_name(None))
284
 
 
285
 
    def test_known_hooks_key_to_object(self):
286
 
        self.assertIs(branch.Branch.hooks,
287
 
            known_hooks_key_to_object(('bzrlib.branch', 'Branch.hooks')))
288
 
 
289
 
    def test_known_hooks_key_to_parent_and_attribute_deprecated(self):
290
 
        self.assertEqual((branch.Branch, 'hooks'),
291
 
            self.applyDeprecated(deprecated_in((2,3)),
292
 
                known_hooks_key_to_parent_and_attribute,
293
 
                ('bzrlib.branch', 'Branch.hooks')))
294
 
        self.assertEqual((branch, 'Branch'),
295
 
            self.applyDeprecated(deprecated_in((2,3)),
296
 
                known_hooks_key_to_parent_and_attribute,
297
 
                ('bzrlib.branch', 'Branch')))
298
 
 
299
 
    def test_known_hooks_key_to_parent_and_attribute(self):
300
 
        self.assertEqual((branch.Branch, 'hooks'),
301
 
            known_hooks.key_to_parent_and_attribute(
302
 
            ('bzrlib.branch', 'Branch.hooks')))
303
 
        self.assertEqual((branch, 'Branch'),
304
 
            known_hooks.key_to_parent_and_attribute(
305
 
            ('bzrlib.branch', 'Branch')))