/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3948.3.3 by Martin Pool
merge trunk
1
# Copyright (C) 2007, 2009 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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tests for the core Hooks logic."""
18
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.
19
from bzrlib import branch, errors
2553.1.1 by Robert Collins
Give Hooks names.
20
from bzrlib.hooks import (
4098.2.2 by Robert Collins
Review feedback.
21
    HookPoint,
2553.1.1 by Robert Collins
Give Hooks names.
22
    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.
23
    known_hooks,
24
    known_hooks_key_to_object,
25
    known_hooks_key_to_parent_and_attribute,
2553.1.1 by Robert Collins
Give Hooks names.
26
    )
27
from bzrlib.errors import (
28
    UnknownHook,
29
    )
30
31
from bzrlib.tests import TestCase
32
33
34
class TestHooks(TestCase):
35
4098.2.1 by Robert Collins
Allow self documenting hooks.
36
    def test_create_hook_first(self):
37
        hooks = Hooks()
38
        doc = ("Invoked after changing the tip of a branch object. Called with"
39
            "a bzrlib.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
40
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
41
        hooks.create_hook(hook)
42
        self.assertEqual(hook, hooks['post_tip_change'])
43
44
    def test_create_hook_name_collision_errors(self):
45
        hooks = Hooks()
46
        doc = ("Invoked after changing the tip of a branch object. Called with"
47
            "a bzrlib.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
48
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
49
        hook2 = HookPoint("post_tip_change", None, None, None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
50
        hooks.create_hook(hook)
51
        self.assertRaises(errors.DuplicateKey, hooks.create_hook, hook2)
52
        self.assertEqual(hook, hooks['post_tip_change'])
53
54
    def test_docs(self):
55
        """docs() should return something reasonable about the Hooks."""
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
56
        class MyHooks(Hooks):
57
            pass
58
        hooks = MyHooks()
4098.2.1 by Robert Collins
Allow self documenting hooks.
59
        hooks['legacy'] = []
4098.2.2 by Robert Collins
Review feedback.
60
        hook1 = HookPoint('post_tip_change',
4098.2.1 by Robert Collins
Allow self documenting hooks.
61
            "Invoked after the tip of a branch changes. Called with "
62
            "a ChangeBranchTipParams object.", (1, 4), None)
4098.2.2 by Robert Collins
Review feedback.
63
        hook2 = HookPoint('pre_tip_change',
4098.2.1 by Robert Collins
Allow self documenting hooks.
64
            "Invoked before the tip of a branch changes. Called with "
65
            "a ChangeBranchTipParams object. Hooks should raise "
66
            "TipChangeRejected to signal that a tip change is not permitted.",
67
            (1, 6), None)
68
        hooks.create_hook(hook1)
69
        hooks.create_hook(hook2)
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
70
        self.assertEqualDiff(
71
            "MyHooks\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
72
            "-------\n"
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
73
            "\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
74
            "legacy\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"
4108.3.1 by Robert Collins
Include the Hooks class in the Hooks docs.
77
            "An old-style hook. For documentation see the __init__ method of 'MyHooks'\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
78
            "\n"
79
            "post_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
80
            "~~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
81
            "\n"
82
            "Introduced in: 1.4\n"
83
            "Deprecated in: Not deprecated\n"
84
            "\n"
85
            "Invoked after the tip of a branch changes. Called with a\n"
86
            "ChangeBranchTipParams object.\n"
87
            "\n"
88
            "pre_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
89
            "~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
90
            "\n"
91
            "Introduced in: 1.6\n"
92
            "Deprecated in: Not deprecated\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
2553.1.1 by Robert Collins
Give Hooks names.
98
    def test_install_hook_raises_unknown_hook(self):
99
        """install_hook should raise UnknownHook if a hook is unknown."""
100
        hooks = Hooks()
3256.2.30 by Daniel Watkins
Updated deprecation warnings and tests.
101
        self.assertRaises(UnknownHook, self.applyDeprecated, one_five,
3256.2.20 by Daniel Watkins
Modified Hooks.install_hook tests to use applyDeprecated.
102
                          hooks.install_hook, 'silly', None)
2553.1.1 by Robert Collins
Give Hooks names.
103
104
    def test_install_hook_appends_known_hook(self):
105
        """install_hook should append the callable for known hooks."""
106
        hooks = Hooks()
3256.2.32 by Ian Clatworthy
tweak hook tests to init the set_rh test when needed
107
        hooks['set_rh'] = []
3256.2.30 by Daniel Watkins
Updated deprecation warnings and tests.
108
        self.applyDeprecated(one_five, hooks.install_hook, 'set_rh', None)
2553.1.1 by Robert Collins
Give Hooks names.
109
        self.assertEqual(hooks['set_rh'], [None])
110
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
111
    def test_install_named_hook_raises_unknown_hook(self):
112
        hooks = Hooks()
113
        self.assertRaises(UnknownHook, hooks.install_named_hook, 'silly',
114
                          None, "")
115
116
    def test_install_named_hook_appends_known_hook(self):
117
        hooks = Hooks()
3256.2.32 by Ian Clatworthy
tweak hook tests to init the set_rh test when needed
118
        hooks['set_rh'] = []
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
119
        hooks.install_named_hook('set_rh', None, "demo")
120
        self.assertEqual(hooks['set_rh'], [None])
121
122
    def test_install_named_hook_and_retrieve_name(self):
123
        hooks = Hooks()
3256.2.32 by Ian Clatworthy
tweak hook tests to init the set_rh test when needed
124
        hooks['set_rh'] = []
3256.2.4 by Daniel Watkins
Modified tests to reflect install_named_hook becoming a separate method.
125
        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.
126
        self.assertEqual("demo", hooks.get_hook_name(None))
127
4098.2.1 by Robert Collins
Allow self documenting hooks.
128
129
class TestHook(TestCase):
130
131
    def test___init__(self):
132
        doc = ("Invoked after changing the tip of a branch object. Called with"
133
            "a bzrlib.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
134
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
135
        self.assertEqual(doc, hook.__doc__)
136
        self.assertEqual("post_tip_change", hook.name)
137
        self.assertEqual((0, 15), hook.introduced)
138
        self.assertEqual(None, hook.deprecated)
139
        self.assertEqual([], list(hook))
140
141
    def test_docs(self):
142
        doc = ("Invoked after changing the tip of a branch object. Called with"
143
            " a bzrlib.branch.PostChangeBranchTipParams object")
4098.2.2 by Robert Collins
Review feedback.
144
        hook = HookPoint("post_tip_change", doc, (0, 15), None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
145
        self.assertEqual("post_tip_change\n"
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
146
            "~~~~~~~~~~~~~~~\n"
4098.2.1 by Robert Collins
Allow self documenting hooks.
147
            "\n"
148
            "Introduced in: 0.15\n"
149
            "Deprecated in: Not deprecated\n"
150
            "\n"
151
            "Invoked after changing the tip of a branch object. Called with a\n"
152
            "bzrlib.branch.PostChangeBranchTipParams object\n", hook.docs())
153
154
    def test_hook(self):
4098.2.2 by Robert Collins
Review feedback.
155
        hook = HookPoint("foo", "no docs", None, None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
156
        def callback():
157
            pass
158
        hook.hook(callback, "my callback")
159
        self.assertEqual([callback], list(hook))
160
161
    def test___repr(self):
162
        # The repr should list all the callbacks, with names.
4098.2.2 by Robert Collins
Review feedback.
163
        hook = HookPoint("foo", "no docs", None, None)
4098.2.1 by Robert Collins
Allow self documenting hooks.
164
        def callback():
165
            pass
166
        hook.hook(callback, "my callback")
167
        callback_repr = repr(callback)
168
        self.assertEqual(
4098.2.2 by Robert Collins
Review feedback.
169
            '<HookPoint(foo), callbacks=[%s(my callback)]>' %
4098.2.1 by Robert Collins
Allow self documenting hooks.
170
            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.
171
172
173
class TestHookRegistry(TestCase):
174
175
    def test_items_are_reasonable_keys(self):
176
        # All the items in the known_hooks registry need to map from
177
        # (module_name, member_name) tuples to the callable used to get an
178
        # empty Hooks of for that attribute. This is used to support the test
179
        # suite which needs to generate empty hooks (and HookPoints) to ensure
180
        # isolation and prevent tests failing spuriously.
181
        for key, factory in known_hooks.items():
182
            self.assertTrue(callable(factory),
183
                "The factory(%r) for %r is not callable" % (factory, key))
184
            obj = known_hooks_key_to_object(key)
185
            self.assertIsInstance(obj, Hooks)
186
            new_hooks = factory()
187
            self.assertIsInstance(obj, Hooks)
188
            self.assertEqual(type(obj), type(new_hooks))
189
190
    def test_known_hooks_key_to_object(self):
191
        self.assertIs(branch.Branch.hooks,
192
            known_hooks_key_to_object(('bzrlib.branch', 'Branch.hooks')))
193
194
    def test_known_hooks_key_to_parent_and_attribute(self):
195
        self.assertEqual((branch.Branch, 'hooks'),
196
            known_hooks_key_to_parent_and_attribute(
197
            ('bzrlib.branch', 'Branch.hooks')))
198
        self.assertEqual((branch, 'Branch'),
199
            known_hooks_key_to_parent_and_attribute(
200
            ('bzrlib.branch', 'Branch')))