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(u'Message of ' + revision_id.decode('utf8'),
119
105
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)
109
class TestPreChangeBranchTip(ChangeBranchTipTestCase):
110
"""Tests for pre_change_branch_tip hook.
112
Most of these tests are very similar to the tests in
113
TestPostChangeBranchTip.
116
def test_hook_runs_before_change(self):
117
"""The hook runs *before* the branch's last_revision_info has changed.
119
branch = self.make_branch_with_revision_ids('revid-one')
120
def assertBranchAtRevision1(params):
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)
127
def test_reject_by_hook(self):
128
"""If a hook raises an exception, the change does not take effect.
130
Also, the exception will be propogated.
132
branch = self.make_branch_with_revision_ids(
133
'one-\xc2\xb5', 'two-\xc2\xb5')
134
class PearShapedError(Exception):
136
def hook_that_raises(params):
137
raise PearShapedError()
138
Branch.hooks.install_named_hook(
139
'pre_change_branch_tip', hook_that_raises, None)
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())
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)
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
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)
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)
173
def test_calls_all_hooks_no_errors(self):
174
"""If multiple hooks are registered, all are called (if none raise
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)
187
class TestPostChangeBranchTip(ChangeBranchTipTestCase):
188
"""Tests for post_change_branch_tip hook.
190
Most of these tests are very similar to the tests in
191
TestPostChangeBranchTip.
194
def test_hook_runs_after_change(self):
195
"""The hook runs *after* the branch's last_revision_info has changed.
197
branch = self.make_branch_with_revision_ids('revid-one')
198
def assertBranchAtRevision1(params):
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)
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)
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
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)
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)
234
def test_calls_all_hooks_no_errors(self):
235
"""If multiple hooks are registered, all are called (if none raise
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)