/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/branch_implementations/test_hooks.py

Merge in the BranchBuilder updates, which brings in a newer bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Tests that branch classes implement hook callouts correctly."""
18
18
 
19
 
from bzrlib.branch import Branch
 
19
from bzrlib.branch import Branch, ChangeBranchTipParams
20
20
from bzrlib.revision import NULL_REVISION
21
21
from bzrlib.tests import TestCaseWithMemoryTransport
22
22
 
80
80
            ])
81
81
 
82
82
 
83
 
class TestPostChangeBranchTip(TestCaseWithMemoryTransport):
84
 
 
85
 
    def setUp(self):
86
 
        self.hook_calls = []
87
 
        TestCaseWithMemoryTransport.setUp(self)
88
 
 
89
 
    def capture_post_change_branch_tip_hook(self, params):
90
 
        """Capture post_change_branch_tip hook calls to self.hook_calls.
91
 
 
92
 
        The call is logged, as is some state of the branch.
 
83
class ChangeBranchTipTestCase(TestCaseWithMemoryTransport):
 
84
    """Base TestCase for testing pre/post_change_branch_tip hooks."""
 
85
 
 
86
    def install_logging_hook(self, prefix):
 
87
        """Add a hook that logs calls made to it.
 
88
        
 
89
        :returns: the list that the calls will be appended to.
93
90
        """
94
 
        self.hook_calls.append((params, params.branch.is_locked()))
95
 
        self.assertEquals(params.branch.last_revision_info(),
96
 
                          (params.new_revno, params.new_revid))
97
 
 
98
 
    def test_post_change_branch_tip_empty_history(self):
99
 
        branch = self.make_branch('source')
 
91
        hook_calls = []
100
92
        Branch.hooks.install_named_hook(
101
 
            'post_change_branch_tip',
102
 
            self.capture_post_change_branch_tip_hook,
103
 
            None)
104
 
        branch.set_last_revision_info(0, NULL_REVISION)
105
 
        self.assertEqual(len(self.hook_calls), 1)
106
 
        self.assertEqual(self.hook_calls[0][0].branch, branch)
107
 
        self.assertEqual(self.hook_calls[0][0].old_revid, NULL_REVISION)
108
 
        self.assertEqual(self.hook_calls[0][0].old_revno, 0)
109
 
        self.assertEqual(self.hook_calls[0][0].new_revid, NULL_REVISION)
110
 
        self.assertEqual(self.hook_calls[0][0].new_revno, 0)
 
93
            'pre_change_branch_tip', hook_calls.append, None)
 
94
        return hook_calls
111
95
 
112
 
    def test_post_change_branch_tip_nonempty_history(self):
 
96
    def make_branch_with_revision_ids(self, *revision_ids):
 
97
        """Makes a branch with the given commits."""
113
98
        tree = self.make_branch_and_memory_tree('source')
114
99
        tree.lock_write()
115
100
        tree.add('')
116
 
        tree.commit('another commit', rev_id='f\xc2\xb5')
117
 
        tree.commit('empty commit', rev_id='foo')
 
101
        for revision_id in revision_ids:
 
102
            tree.commit(u'Message of ' + revision_id.decode('utf8'),
 
103
                        rev_id=revision_id)
118
104
        tree.unlock()
119
105
        branch = tree.branch
120
 
        Branch.hooks.install_named_hook(
121
 
            'post_change_branch_tip',
122
 
            self.capture_post_change_branch_tip_hook,
123
 
            None)
124
 
        # some branches require that their history be set to a revision in the
125
 
        # repository
126
 
        branch.set_last_revision_info(1, 'f\xc2\xb5')
127
 
        self.assertEqual(len(self.hook_calls), 1)
128
 
        self.assertEqual(self.hook_calls[0][0].branch, branch)
129
 
        self.assertEqual(self.hook_calls[0][0].old_revid, 'foo')
130
 
        self.assertEqual(self.hook_calls[0][0].old_revno, 2)
131
 
        self.assertEqual(self.hook_calls[0][0].new_revid, 'f\xc2\xb5')
132
 
        self.assertEqual(self.hook_calls[0][0].new_revno, 1)
133
 
 
134
 
    def test_post_change_branch_tip_branch_is_locked(self):
135
 
        branch = self.make_branch('source')
136
 
        Branch.hooks.install_named_hook(
137
 
            'post_change_branch_tip',
138
 
            self.capture_post_change_branch_tip_hook,
139
 
            None)
140
 
        branch.set_last_revision_info(0, NULL_REVISION)
141
 
        self.assertEqual(len(self.hook_calls), 1)
142
 
        self.assertEqual(self.hook_calls[0][0].branch, branch)
143
 
        self.assertEqual(self.hook_calls[0][1], True)
144
 
 
145
 
    def test_post_change_branch_tip_calls_all_hooks_no_errors(self):
146
 
        branch = self.make_branch('source')
147
 
        Branch.hooks.install_named_hook(
148
 
            'post_change_branch_tip',
149
 
            self.capture_post_change_branch_tip_hook,
150
 
            None)
151
 
        Branch.hooks.install_named_hook(
152
 
            'post_change_branch_tip',
153
 
            self.capture_post_change_branch_tip_hook,
154
 
            None)
155
 
        branch.set_last_revision_info(0, NULL_REVISION)
156
 
        self.assertEqual(len(self.hook_calls), 2)
157
 
        self.assertEqual(self.hook_calls[0][0].branch, branch)
158
 
        self.assertEqual(self.hook_calls[1][0].branch, branch)
 
106
        return branch
 
107
 
 
108
 
 
109
class TestPreChangeBranchTip(ChangeBranchTipTestCase):
 
110
    """Tests for pre_change_branch_tip hook.
 
111
    
 
112
    Most of these tests are very similar to the tests in
 
113
    TestPostChangeBranchTip.
 
114
    """
 
115
 
 
116
    def test_hook_runs_before_change(self):
 
117
        """The hook runs *before* the branch's last_revision_info has changed.
 
118
        """
 
119
        branch = self.make_branch_with_revision_ids('revid-one')
 
120
        def assertBranchAtRevision1(params):
 
121
            self.assertEquals(
 
122
                (1, 'revid-one'), params.branch.last_revision_info())
 
123
        Branch.hooks.install_named_hook(
 
124
            'pre_change_branch_tip', assertBranchAtRevision1, None)
 
125
        branch.set_last_revision_info(0, NULL_REVISION)
 
126
 
 
127
    def test_reject_by_hook(self):
 
128
        """If a hook raises an exception, the change does not take effect.
 
129
        
 
130
        Also, the exception will be propogated.
 
131
        """
 
132
        branch = self.make_branch_with_revision_ids(
 
133
            'one-\xc2\xb5', 'two-\xc2\xb5')
 
134
        class PearShapedError(Exception):
 
135
            pass
 
136
        def hook_that_raises(params):
 
137
            raise PearShapedError()
 
138
        Branch.hooks.install_named_hook(
 
139
            'pre_change_branch_tip', hook_that_raises, None)
 
140
        self.assertRaises(
 
141
            PearShapedError, branch.set_last_revision_info, 0, NULL_REVISION)
 
142
        # The revision info is unchanged.
 
143
        self.assertEqual((2, 'two-\xc2\xb5'), branch.last_revision_info())
 
144
        
 
145
    def test_empty_history(self):
 
146
        branch = self.make_branch('source')
 
147
        hook_calls = self.install_logging_hook('pre')
 
148
        branch.set_last_revision_info(0, NULL_REVISION)
 
149
        expected_params = ChangeBranchTipParams(
 
150
            branch, 0, 0, NULL_REVISION, NULL_REVISION)
 
151
        self.assertEqual([expected_params], hook_calls)
 
152
 
 
153
    def test_nonempty_history(self):
 
154
        # some branches require that their history be set to a revision in the
 
155
        # repository, so we need to make a branch with non-empty history for
 
156
        # this test.
 
157
        branch = self.make_branch_with_revision_ids(
 
158
            'one-\xc2\xb5', 'two-\xc2\xb5')
 
159
        hook_calls = self.install_logging_hook('pre')
 
160
        branch.set_last_revision_info(1, 'one-\xc2\xb5')
 
161
        expected_params = ChangeBranchTipParams(
 
162
            branch, 2, 1, 'two-\xc2\xb5', 'one-\xc2\xb5')
 
163
        self.assertEqual([expected_params], hook_calls)
 
164
 
 
165
    def test_branch_is_locked(self):
 
166
        branch = self.make_branch('source')
 
167
        def assertBranchIsLocked(params):
 
168
            self.assertTrue(params.branch.is_locked())
 
169
        Branch.hooks.install_named_hook(
 
170
            'pre_change_branch_tip', assertBranchIsLocked, None)
 
171
        branch.set_last_revision_info(0, NULL_REVISION)
 
172
 
 
173
    def test_calls_all_hooks_no_errors(self):
 
174
        """If multiple hooks are registered, all are called (if none raise
 
175
        errors).
 
176
        """
 
177
        branch = self.make_branch('source')
 
178
        hook_calls_1 = self.install_logging_hook('pre')
 
179
        hook_calls_2 = self.install_logging_hook('pre')
 
180
        self.assertIsNot(hook_calls_1, hook_calls_2)
 
181
        branch.set_last_revision_info(0, NULL_REVISION)
 
182
        # Both hooks are called.
 
183
        self.assertEqual(len(hook_calls_1), 1)
 
184
        self.assertEqual(len(hook_calls_2), 1)
 
185
 
 
186
 
 
187
class TestPostChangeBranchTip(ChangeBranchTipTestCase):
 
188
    """Tests for post_change_branch_tip hook.
 
189
 
 
190
    Most of these tests are very similar to the tests in
 
191
    TestPostChangeBranchTip.
 
192
    """
 
193
 
 
194
    def test_hook_runs_after_change(self):
 
195
        """The hook runs *after* the branch's last_revision_info has changed.
 
196
        """
 
197
        branch = self.make_branch_with_revision_ids('revid-one')
 
198
        def assertBranchAtRevision1(params):
 
199
            self.assertEquals(
 
200
                (0, NULL_REVISION), params.branch.last_revision_info())
 
201
        Branch.hooks.install_named_hook(
 
202
            'post_change_branch_tip', assertBranchAtRevision1, None)
 
203
        branch.set_last_revision_info(0, NULL_REVISION)
 
204
 
 
205
    def test_empty_history(self):
 
206
        branch = self.make_branch('source')
 
207
        hook_calls = self.install_logging_hook('post')
 
208
        branch.set_last_revision_info(0, NULL_REVISION)
 
209
        expected_params = ChangeBranchTipParams(
 
210
            branch, 0, 0, NULL_REVISION, NULL_REVISION)
 
211
        self.assertEqual([expected_params], hook_calls)
 
212
 
 
213
    def test_nonempty_history(self):
 
214
        # some branches require that their history be set to a revision in the
 
215
        # repository, so we need to make a branch with non-empty history for
 
216
        # this test.
 
217
        branch = self.make_branch_with_revision_ids(
 
218
            'one-\xc2\xb5', 'two-\xc2\xb5')
 
219
        hook_calls = self.install_logging_hook('post')
 
220
        branch.set_last_revision_info(1, 'one-\xc2\xb5')
 
221
        expected_params = ChangeBranchTipParams(
 
222
            branch, 2, 1, 'two-\xc2\xb5', 'one-\xc2\xb5')
 
223
        self.assertEqual([expected_params], hook_calls)
 
224
 
 
225
    def test_branch_is_locked(self):
 
226
        """The branch passed to the hook is locked."""
 
227
        branch = self.make_branch('source')
 
228
        def assertBranchIsLocked(params):
 
229
            self.assertTrue(params.branch.is_locked())
 
230
        Branch.hooks.install_named_hook(
 
231
            'post_change_branch_tip', assertBranchIsLocked, None)
 
232
        branch.set_last_revision_info(0, NULL_REVISION)
 
233
 
 
234
    def test_calls_all_hooks_no_errors(self):
 
235
        """If multiple hooks are registered, all are called (if none raise
 
236
        errors).
 
237
        """
 
238
        branch = self.make_branch('source')
 
239
        hook_calls_1 = self.install_logging_hook('post')
 
240
        hook_calls_2 = self.install_logging_hook('post')
 
241
        self.assertIsNot(hook_calls_1, hook_calls_2)
 
242
        branch.set_last_revision_info(0, NULL_REVISION)
 
243
        # Both hooks are called.
 
244
        self.assertEqual(len(hook_calls_1), 1)
 
245
        self.assertEqual(len(hook_calls_2), 1)