/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,
22
    tests,
23
    )
2553.1.1 by Robert Collins
Give Hooks names.
24
from bzrlib.hooks import (
4098.2.2 by Robert Collins
Review feedback.
25
    HookPoint,
2553.1.1 by Robert Collins
Give Hooks names.
26
    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.
27
    known_hooks,
28
    known_hooks_key_to_object,
29
    known_hooks_key_to_parent_and_attribute,
2553.1.1 by Robert Collins
Give Hooks names.
30
    )
5436.2.1 by Andrew Bennetts
Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.
31
from bzrlib.symbol_versioning import (
32
    deprecated_in,
33
    )
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
34
35
36
class TestHooks(tests.TestCase):
2553.1.1 by Robert Collins
Give Hooks names.
37
4098.2.1 by Robert Collins
Allow self documenting hooks.
38
    def test_create_hook_first(self):
39
        hooks = Hooks()
40
        doc = ("Invoked after changing the tip of a branch object. Called with"
41
            "a bzrlib.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
42
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
43
        hooks.create_hook(hook)
44
        self.assertEqual(hook, hooks['post_tip_change'])
45
46
    def test_create_hook_name_collision_errors(self):
47
        hooks = Hooks()
48
        doc = ("Invoked after changing the tip of a branch object. Called with"
49
            "a bzrlib.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
50
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
51
        hook2 = HookPoint("post_tip_change", None, None, None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
52
        hooks.create_hook(hook)
53
        self.assertRaises(errors.DuplicateKey, hooks.create_hook, hook2)
54
        self.assertEqual(hook, hooks['post_tip_change'])
55
56
    def test_docs(self):
57
        """docs() should return something reasonable about the Hooks."""
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
58
        class MyHooks(Hooks):
59
            pass
60
        hooks = MyHooks()
4098.2.1 by Robert Collins
Allow self documenting hooks.
61
        hooks['legacy'] = []
4098.2.2 by Robert Collins
Review feedback.
62
        hook1 = HookPoint('post_tip_change',
4098.2.1 by Robert Collins
Allow self documenting hooks.
63
            "Invoked after the tip of a branch changes. Called with "
64
            "a ChangeBranchTipParams object.", (1, 4), None)
4098.2.2 by Robert Collins
Review feedback.
65
        hook2 = HookPoint('pre_tip_change',
4098.2.1 by Robert Collins
Allow self documenting hooks.
66
            "Invoked before the tip of a branch changes. Called with "
67
            "a ChangeBranchTipParams object. Hooks should raise "
68
            "TipChangeRejected to signal that a tip change is not permitted.",
69
            (1, 6), None)
70
        hooks.create_hook(hook1)
71
        hooks.create_hook(hook2)
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
72
        self.assertEqualDiff(
73
            "MyHooks\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
74
            "-------\n"
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
75
            "\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
76
            "legacy\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
77
            "~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
78
            "\n"
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
79
            "An old-style hook. For documentation see the __init__ method of 'MyHooks'\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
80
            "\n"
81
            "post_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
82
            "~~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
83
            "\n"
84
            "Introduced in: 1.4\n"
85
            "\n"
86
            "Invoked after the tip of a branch changes. Called with a\n"
87
            "ChangeBranchTipParams object.\n"
88
            "\n"
89
            "pre_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
90
            "~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
91
            "\n"
92
            "Introduced in: 1.6\n"
93
            "\n"
94
            "Invoked before the tip of a branch changes. Called with a\n"
95
            "ChangeBranchTipParams object. Hooks should raise TipChangeRejected to\n"
96
            "signal that a tip change is not permitted.\n", hooks.docs())
97
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
98
    def test_install_named_hook_raises_unknown_hook(self):
99
        hooks = Hooks()
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
100
        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.
101
                          None, "")
102
103
    def test_install_named_hook_appends_known_hook(self):
104
        hooks = Hooks()
3256.2.32 by Ian Clatworthy
tweak hook tests to init the set_rh test when needed
105
        hooks['set_rh'] = []
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
106
        hooks.install_named_hook('set_rh', None, "demo")
107
        self.assertEqual(hooks['set_rh'], [None])
108
109
    def test_install_named_hook_and_retrieve_name(self):
110
        hooks = Hooks()
3256.2.32 by Ian Clatworthy
tweak hook tests to init the set_rh test when needed
111
        hooks['set_rh'] = []
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
112
        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.
113
        self.assertEqual("demo", hooks.get_hook_name(None))
114
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
115
    set_rh = lambda: None
116
117
    def test_install_named_hook_lazy(self):
118
        hooks = Hooks()
119
        hooks['set_rh'] = HookPoint("set_rh", "doc", (0, 15), None)
120
        hooks.install_named_hook_lazy('set_rh', 'bzrlib.tests.test_hooks',
121
            'TestHooks.set_rh', "demo")
122
        self.assertEqual(list(hooks['set_rh']), [TestHooks.set_rh])
123
124
    def test_install_named_hook_lazy_old(self):
125
        # An exception is raised if a lazy hook is raised for
126
        # an old style hook point.
127
        hooks = Hooks()
128
        hooks['set_rh'] = []
129
        self.assertRaises(errors.UnsupportedOperation,
130
            hooks.install_named_hook_lazy,
131
            'set_rh', 'bzrlib.tests.test_hooks', 'TestHooks.set_rh',
132
            "demo")
133
4098.2.1 by Robert Collins
Allow self documenting hooks.
134
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
135
class TestHook(tests.TestCase):
4098.2.1 by Robert Collins
Allow self documenting hooks.
136
137
    def test___init__(self):
138
        doc = ("Invoked after changing the tip of a branch object. Called with"
139
            "a bzrlib.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
140
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
141
        self.assertEqual(doc, hook.__doc__)
142
        self.assertEqual("post_tip_change", hook.name)
143
        self.assertEqual((0, 15), hook.introduced)
144
        self.assertEqual(None, hook.deprecated)
145
        self.assertEqual([], list(hook))
146
147
    def test_docs(self):
148
        doc = ("Invoked after changing the tip of a branch object. Called with"
149
            " a bzrlib.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
150
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
151
        self.assertEqual("post_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
152
            "~~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
153
            "\n"
154
            "Introduced in: 0.15\n"
155
            "\n"
156
            "Invoked after changing the tip of a branch object. Called with a\n"
157
            "bzrlib.branch.PostChangeBranchTipParams object\n", hook.docs())
158
159
    def test_hook(self):
4098.2.2 by Robert Collins
Review feedback.
160
        hook = HookPoint("foo", "no docs", None, None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
161
        def callback():
162
            pass
163
        hook.hook(callback, "my callback")
164
        self.assertEqual([callback], list(hook))
165
5622.1.1 by Jelmer Vernooij
Allow lazily loading hook callbacks.
166
    def lazy_callback():
167
        pass
168
169
    def test_lazy_hook(self):
170
        hook = HookPoint("foo", "no docs", None, None)
171
        hook.hook_lazy(
172
            "bzrlib.tests.test_hooks", "TestHook.lazy_callback",
173
            "my callback")
174
        self.assertEqual([TestHook.lazy_callback], list(hook))
175
4098.2.1 by Robert Collins
Allow self documenting hooks.
176
    def test___repr(self):
177
        # The repr should list all the callbacks, with names.
4098.2.2 by Robert Collins
Review feedback.
178
        hook = HookPoint("foo", "no docs", None, None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
179
        def callback():
180
            pass
181
        hook.hook(callback, "my callback")
182
        callback_repr = repr(callback)
183
        self.assertEqual(
4098.2.2 by Robert Collins
Review feedback.
184
            '<HookPoint(foo), callbacks=[%s(my callback)]>' %
4098.2.1 by Robert Collins
Allow self documenting hooks.
185
            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.
186
187
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
188
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.
189
190
    def test_items_are_reasonable_keys(self):
191
        # All the items in the known_hooks registry need to map from
192
        # (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.
193
        # 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.
194
        # suite which needs to generate empty hooks (and HookPoints) to ensure
195
        # isolation and prevent tests failing spuriously.
196
        for key, factory in known_hooks.items():
197
            self.assertTrue(callable(factory),
198
                "The factory(%r) for %r is not callable" % (factory, key))
199
            obj = known_hooks_key_to_object(key)
200
            self.assertIsInstance(obj, Hooks)
201
            new_hooks = factory()
202
            self.assertIsInstance(obj, Hooks)
203
            self.assertEqual(type(obj), type(new_hooks))
4781.1.1 by Vincent Ladeuil
Hooks daughter classes should always call the base constructor
204
            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.
205
206
    def test_known_hooks_key_to_object(self):
207
        self.assertIs(branch.Branch.hooks,
208
            known_hooks_key_to_object(('bzrlib.branch', 'Branch.hooks')))
209
5436.2.1 by Andrew Bennetts
Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.
210
    def test_known_hooks_key_to_parent_and_attribute_deprecated(self):
211
        self.assertEqual((branch.Branch, 'hooks'),
212
            self.applyDeprecated(deprecated_in((2,3)),
213
                known_hooks_key_to_parent_and_attribute,
214
                ('bzrlib.branch', 'Branch.hooks')))
215
        self.assertEqual((branch, 'Branch'),
216
            self.applyDeprecated(deprecated_in((2,3)),
217
                known_hooks_key_to_parent_and_attribute,
218
                ('bzrlib.branch', 'Branch')))
219
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.
220
    def test_known_hooks_key_to_parent_and_attribute(self):
221
        self.assertEqual((branch.Branch, 'hooks'),
5436.2.1 by Andrew Bennetts
Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.
222
            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.
223
            ('bzrlib.branch', 'Branch.hooks')))
224
        self.assertEqual((branch, 'Branch'),
5436.2.1 by Andrew Bennetts
Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.
225
            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.
226
            ('bzrlib.branch', 'Branch')))