83
class TestPostChangeBranchTip(TestCaseWithMemoryTransport):
87
TestCaseWithMemoryTransport.setUp(self)
89
def capture_post_change_branch_tip_hook(self, params):
90
"""Capture post_change_branch_tip hook calls to self.hook_calls.
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."""
86
def install_logging_hook(self, prefix):
87
"""Add a hook that logs calls made to it.
89
:returns: the list that the calls will be appended to.
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))
98
def test_post_change_branch_tip_empty_history(self):
99
branch = self.make_branch('source')
100
92
Branch.hooks.install_named_hook(
101
'post_change_branch_tip',
102
self.capture_post_change_branch_tip_hook,
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)
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')
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('Message of ' + revision_id, rev_id=revision_id)
119
104
branch = tree.branch
120
Branch.hooks.install_named_hook(
121
'post_change_branch_tip',
122
self.capture_post_change_branch_tip_hook,
124
# some branches require that their history be set to a revision in the
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)
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,
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)
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,
151
Branch.hooks.install_named_hook(
152
'post_change_branch_tip',
153
self.capture_post_change_branch_tip_hook,
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)
108
class TestPreChangeBranchTip(ChangeBranchTipTestCase):
109
"""Tests for pre_change_branch_tip hook.
111
Most of these tests are very similar to the tests in
112
TestPostChangeBranchTip.
115
def test_hook_runs_before_change(self):
116
"""The hook runs *before* the branch's last_revision_info has changed.
118
branch = self.make_branch_with_revision_ids('revid-one')
119
def assertBranchAtRevision1(params):
121
(1, 'revid-one'), params.branch.last_revision_info())
122
Branch.hooks.install_named_hook(
123
'pre_change_branch_tip', assertBranchAtRevision1, None)
124
branch.set_last_revision_info(0, NULL_REVISION)
126
def test_reject_by_hook(self):
127
"""If a hook raises an exception, the change does not take effect.
129
Also, the exception will be propogated.
131
branch = self.make_branch_with_revision_ids(
132
'one-\xc2\xb5', 'two-\xc2\xb5')
133
class PearShapedError(Exception):
135
def hook_that_raises(params):
136
raise PearShapedError()
137
Branch.hooks.install_named_hook(
138
'pre_change_branch_tip', hook_that_raises, None)
140
PearShapedError, branch.set_last_revision_info, 0, NULL_REVISION)
141
# The revision info is unchanged.
142
self.assertEqual((2, 'two-\xc2\xb5'), branch.last_revision_info())
144
def test_empty_history(self):
145
branch = self.make_branch('source')
146
hook_calls = self.install_logging_hook('pre')
147
branch.set_last_revision_info(0, NULL_REVISION)
148
expected_params = ChangeBranchTipParams(
149
branch, 0, 0, NULL_REVISION, NULL_REVISION)
150
self.assertEqual([expected_params], hook_calls)
152
def test_nonempty_history(self):
153
# some branches require that their history be set to a revision in the
154
# repository, so we need to make a branch with non-empty history for
156
branch = self.make_branch_with_revision_ids(
157
'one-\xc2\xb5', 'two-\xc2\xb5')
158
hook_calls = self.install_logging_hook('pre')
159
branch.set_last_revision_info(1, 'one-\xc2\xb5')
160
expected_params = ChangeBranchTipParams(
161
branch, 2, 1, 'two-\xc2\xb5', 'one-\xc2\xb5')
162
self.assertEqual([expected_params], hook_calls)
164
def test_branch_is_locked(self):
165
branch = self.make_branch('source')
166
def assertBranchIsLocked(params):
167
self.assertTrue(params.branch.is_locked())
168
Branch.hooks.install_named_hook(
169
'pre_change_branch_tip', assertBranchIsLocked, None)
170
branch.set_last_revision_info(0, NULL_REVISION)
172
def test_calls_all_hooks_no_errors(self):
173
"""If multiple hooks are registered, all are called (if none raise
176
branch = self.make_branch('source')
177
hook_calls_1 = self.install_logging_hook('pre')
178
hook_calls_2 = self.install_logging_hook('pre')
179
self.assertIsNot(hook_calls_1, hook_calls_2)
180
branch.set_last_revision_info(0, NULL_REVISION)
181
# Both hooks are called.
182
self.assertEqual(len(hook_calls_1), 1)
183
self.assertEqual(len(hook_calls_2), 1)
186
class TestPostChangeBranchTip(ChangeBranchTipTestCase):
187
"""Tests for post_change_branch_tip hook.
189
Most of these tests are very similar to the tests in
190
TestPostChangeBranchTip.
193
def test_hook_runs_after_change(self):
194
"""The hook runs *after* the branch's last_revision_info has changed.
196
branch = self.make_branch_with_revision_ids('revid-one')
197
def assertBranchAtRevision1(params):
199
(0, NULL_REVISION), params.branch.last_revision_info())
200
Branch.hooks.install_named_hook(
201
'post_change_branch_tip', assertBranchAtRevision1, None)
202
branch.set_last_revision_info(0, NULL_REVISION)
204
def test_empty_history(self):
205
branch = self.make_branch('source')
206
hook_calls = self.install_logging_hook('post')
207
branch.set_last_revision_info(0, NULL_REVISION)
208
expected_params = ChangeBranchTipParams(
209
branch, 0, 0, NULL_REVISION, NULL_REVISION)
210
self.assertEqual([expected_params], hook_calls)
212
def test_nonempty_history(self):
213
# some branches require that their history be set to a revision in the
214
# repository, so we need to make a branch with non-empty history for
216
branch = self.make_branch_with_revision_ids(
217
'one-\xc2\xb5', 'two-\xc2\xb5')
218
hook_calls = self.install_logging_hook('post')
219
branch.set_last_revision_info(1, 'one-\xc2\xb5')
220
expected_params = ChangeBranchTipParams(
221
branch, 2, 1, 'two-\xc2\xb5', 'one-\xc2\xb5')
222
self.assertEqual([expected_params], hook_calls)
224
def test_branch_is_locked(self):
225
"""The branch passed to the hook is locked."""
226
branch = self.make_branch('source')
227
def assertBranchIsLocked(params):
228
self.assertTrue(params.branch.is_locked())
229
Branch.hooks.install_named_hook(
230
'post_change_branch_tip', assertBranchIsLocked, None)
231
branch.set_last_revision_info(0, NULL_REVISION)
233
def test_calls_all_hooks_no_errors(self):
234
"""If multiple hooks are registered, all are called (if none raise
237
branch = self.make_branch('source')
238
hook_calls_1 = self.install_logging_hook('post')
239
hook_calls_2 = self.install_logging_hook('post')
240
self.assertIsNot(hook_calls_1, hook_calls_2)
241
branch.set_last_revision_info(0, NULL_REVISION)
242
# Both hooks are called.
243
self.assertEqual(len(hook_calls_1), 1)
244
self.assertEqual(len(hook_calls_2), 1)