13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Tests for the Branch facility that are not interface tests.
19
For interface tests see `tests/per_branch/*.py`.
19
For interface tests see tests/branch_implementations/*.py.
21
21
For concrete class tests see this file, and for meta-branch tests
22
22
also see this file.
25
from cStringIO import StringIO
25
from StringIO import StringIO
27
27
from bzrlib import (
28
28
branch as _mod_branch,
39
class TestDefaultFormat(tests.TestCase):
41
def test_default_format(self):
42
# update this if you change the default branch format
43
self.assertIsInstance(_mod_branch.format_registry.get_default(),
44
_mod_branch.BzrBranchFormat7)
46
def test_default_format_is_same_as_bzrdir_default(self):
47
# XXX: it might be nice if there was only one place the default was
48
# set, but at the moment that's not true -- mbp 20070814 --
49
# https://bugs.launchpad.net/bzr/+bug/132376
51
_mod_branch.format_registry.get_default(),
52
bzrdir.BzrDirFormat.get_default_format().get_branch_format())
35
from bzrlib.branch import (
39
BranchReferenceFormat,
44
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1,
46
from bzrlib.errors import (NotBranchError,
49
UnsupportedFormatError,
52
from bzrlib.tests import TestCase, TestCaseWithTransport
53
from bzrlib.transport import get_transport
55
class TestDefaultFormat(TestCase):
54
57
def test_get_set_default_format(self):
55
# set the format and then set it back again
56
old_format = _mod_branch.format_registry.get_default()
57
_mod_branch.format_registry.set_default(SampleBranchFormat())
58
old_format = BranchFormat.get_default_format()
60
self.assertTrue(isinstance(old_format, BzrBranchFormat5))
61
BranchFormat.set_default_format(SampleBranchFormat())
59
63
# the default branch format is used by the meta dir format
60
64
# which is not the default bzrdir format at this point
61
dir = bzrdir.BzrDirMetaFormat1().initialize('memory:///')
65
dir = BzrDirMetaFormat1().initialize('memory:///')
62
66
result = dir.create_branch()
63
67
self.assertEqual(result, 'A branch')
65
_mod_branch.format_registry.set_default(old_format)
66
self.assertEqual(old_format,
67
_mod_branch.format_registry.get_default())
70
class TestBranchFormat5(tests.TestCaseWithTransport):
69
BranchFormat.set_default_format(old_format)
70
self.assertEqual(old_format, BranchFormat.get_default_format())
73
class TestBranchFormat5(TestCaseWithTransport):
71
74
"""Tests specific to branch format 5"""
73
76
def test_branch_format_5_uses_lockdir(self):
74
77
url = self.get_url()
75
bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
76
bdir.create_repository()
77
branch = _mod_branch.BzrBranchFormat5().initialize(bdir)
78
bzrdir = BzrDirMetaFormat1().initialize(url)
79
bzrdir.create_repository()
80
branch = bzrdir.create_branch()
78
81
t = self.get_transport()
79
82
self.log("branch instance is %r" % branch)
80
self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
83
self.assert_(isinstance(branch, BzrBranch5))
81
84
self.assertIsDirectory('.', t)
82
85
self.assertIsDirectory('.bzr/branch', t)
83
86
self.assertIsDirectory('.bzr/branch/lock', t)
84
87
branch.lock_write()
85
self.addCleanup(branch.unlock)
86
self.assertIsDirectory('.bzr/branch/lock/held', t)
89
self.assertIsDirectory('.bzr/branch/lock/held', t)
88
93
def test_set_push_location(self):
89
conf = config.LocationConfig.from_string('# comment\n', '.', save=True)
94
from bzrlib.config import (locations_config_filename,
95
ensure_config_dir_exists)
96
ensure_config_dir_exists()
97
fn = locations_config_filename()
91
98
branch = self.make_branch('.', format='knit')
92
99
branch.set_push_location('foo')
93
100
local_path = urlutils.local_path_from_url(branch.base[:-1])
94
self.assertFileEqual("# comment\n"
101
self.assertFileEqual("[%s]\n"
96
102
"push_location = foo\n"
97
"push_location:policy = norecurse\n" % local_path,
98
config.locations_config_filename())
103
"push_location:policy = norecurse" % local_path,
100
106
# TODO RBC 20051029 test getting a push location from a branch in a
101
107
# recursive section - that is, it appends the branch name.
104
class SampleBranchFormat(_mod_branch.BranchFormat):
110
class SampleBranchFormat(BranchFormat):
105
111
"""A sample format
107
this format is initializable, unsupported to aid in testing the
113
this format is initializable, unsupported to aid in testing the
108
114
open and open_downlevel routines.
112
118
"""See BzrBranchFormat.get_format_string()."""
113
119
return "Sample branch format."
115
def initialize(self, a_bzrdir, name=None, repository=None):
121
def initialize(self, a_bzrdir):
116
122
"""Format 4 branches cannot be created."""
117
t = a_bzrdir.get_branch_transport(self, name=name)
123
t = a_bzrdir.get_branch_transport(self)
118
124
t.put_bytes('format', self.get_format_string())
119
125
return 'A branch'
121
127
def is_supported(self):
124
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
130
def open(self, transport, _found=False):
125
131
return "opened branch."
128
# Demonstrating how lazy loading is often implemented:
129
# A constant string is created.
130
SampleSupportedBranchFormatString = "Sample supported branch format."
132
# And the format class can then reference the constant to avoid skew.
133
class SampleSupportedBranchFormat(_mod_branch.BranchFormat):
134
"""A sample supported format."""
136
def get_format_string(self):
137
"""See BzrBranchFormat.get_format_string()."""
138
return SampleSupportedBranchFormatString
140
def initialize(self, a_bzrdir, name=None):
141
t = a_bzrdir.get_branch_transport(self, name=name)
142
t.put_bytes('format', self.get_format_string())
145
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
146
return "opened supported branch."
149
class SampleExtraBranchFormat(_mod_branch.BranchFormat):
150
"""A sample format that is not usable in a metadir."""
152
def get_format_string(self):
153
# This format is not usable in a metadir.
156
def network_name(self):
157
# Network name always has to be provided.
160
def initialize(self, a_bzrdir, name=None):
161
raise NotImplementedError(self.initialize)
163
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
164
raise NotImplementedError(self.open)
167
class TestBzrBranchFormat(tests.TestCaseWithTransport):
134
class TestBzrBranchFormat(TestCaseWithTransport):
168
135
"""Tests for the BzrBranchFormat facility."""
170
137
def test_find_format(self):
171
138
# is the right format object found for a branch?
172
139
# create a branch with a few known format objects.
173
# this is not quite the same as
140
# this is not quite the same as
174
141
self.build_tree(["foo/", "bar/"])
175
142
def check_format(format, url):
176
143
dir = format._matchingbzrdir.initialize(url)
177
144
dir.create_repository()
178
145
format.initialize(dir)
179
found_format = _mod_branch.BranchFormat.find_format(dir)
180
self.assertIsInstance(found_format, format.__class__)
181
check_format(_mod_branch.BzrBranchFormat5(), "bar")
183
def test_find_format_factory(self):
184
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
185
SampleSupportedBranchFormat().initialize(dir)
186
factory = _mod_branch.MetaDirBranchFormatFactory(
187
SampleSupportedBranchFormatString,
188
"bzrlib.tests.test_branch", "SampleSupportedBranchFormat")
189
_mod_branch.format_registry.register(factory)
190
self.addCleanup(_mod_branch.format_registry.remove, factory)
191
b = _mod_branch.Branch.open(self.get_url())
192
self.assertEqual(b, "opened supported branch.")
146
found_format = BranchFormat.find_format(dir)
147
self.failUnless(isinstance(found_format, format.__class__))
148
check_format(BzrBranchFormat5(), "bar")
194
150
def test_find_format_not_branch(self):
195
151
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
196
self.assertRaises(errors.NotBranchError,
197
_mod_branch.BranchFormat.find_format,
152
self.assertRaises(NotBranchError,
153
BranchFormat.find_format,
200
156
def test_find_format_unknown_format(self):
201
157
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
202
158
SampleBranchFormat().initialize(dir)
203
self.assertRaises(errors.UnknownFormatError,
204
_mod_branch.BranchFormat.find_format,
159
self.assertRaises(UnknownFormatError,
160
BranchFormat.find_format,
207
163
def test_register_unregister_format(self):
208
# Test the deprecated format registration functions
209
164
format = SampleBranchFormat()
210
165
# make a control dir
211
166
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
213
168
format.initialize(dir)
214
169
# register a format for it.
215
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
216
_mod_branch.BranchFormat.register_format, format)
170
BranchFormat.register_format(format)
217
171
# which branch.Open will refuse (not supported)
218
self.assertRaises(errors.UnsupportedFormatError,
219
_mod_branch.Branch.open, self.get_url())
172
self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
220
173
self.make_branch_and_tree('foo')
221
174
# but open_downlevel will work
224
bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
175
self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
225
176
# unregister the format
226
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
227
_mod_branch.BranchFormat.unregister_format, format)
177
BranchFormat.unregister_format(format)
228
178
self.make_branch_and_tree('bar')
231
class TestBranchFormatRegistry(tests.TestCase):
234
super(TestBranchFormatRegistry, self).setUp()
235
self.registry = _mod_branch.BranchFormatRegistry()
237
def test_default(self):
238
self.assertIs(None, self.registry.get_default())
239
format = SampleBranchFormat()
240
self.registry.set_default(format)
241
self.assertEquals(format, self.registry.get_default())
243
def test_register_unregister_format(self):
244
format = SampleBranchFormat()
245
self.registry.register(format)
246
self.assertEquals(format,
247
self.registry.get("Sample branch format."))
248
self.registry.remove(format)
249
self.assertRaises(KeyError, self.registry.get,
250
"Sample branch format.")
252
def test_get_all(self):
253
format = SampleBranchFormat()
254
self.assertEquals([], self.registry._get_all())
255
self.registry.register(format)
256
self.assertEquals([format], self.registry._get_all())
258
def test_register_extra(self):
259
format = SampleExtraBranchFormat()
260
self.assertEquals([], self.registry._get_all())
261
self.registry.register_extra(format)
262
self.assertEquals([format], self.registry._get_all())
264
def test_register_extra_lazy(self):
265
self.assertEquals([], self.registry._get_all())
266
self.registry.register_extra_lazy("bzrlib.tests.test_branch",
267
"SampleExtraBranchFormat")
268
formats = self.registry._get_all()
269
self.assertEquals(1, len(formats))
270
self.assertIsInstance(formats[0], SampleExtraBranchFormat)
273
#Used by TestMetaDirBranchFormatFactory
274
FakeLazyFormat = None
277
class TestMetaDirBranchFormatFactory(tests.TestCase):
279
def test_get_format_string_does_not_load(self):
280
"""Formats have a static format string."""
281
factory = _mod_branch.MetaDirBranchFormatFactory("yo", None, None)
282
self.assertEqual("yo", factory.get_format_string())
284
def test_call_loads(self):
285
# __call__ is used by the network_format_registry interface to get a
287
global FakeLazyFormat
289
factory = _mod_branch.MetaDirBranchFormatFactory(None,
290
"bzrlib.tests.test_branch", "FakeLazyFormat")
291
self.assertRaises(AttributeError, factory)
293
def test_call_returns_call_of_referenced_object(self):
294
global FakeLazyFormat
295
FakeLazyFormat = lambda:'called'
296
factory = _mod_branch.MetaDirBranchFormatFactory(None,
297
"bzrlib.tests.test_branch", "FakeLazyFormat")
298
self.assertEqual('called', factory())
301
class TestBranch67(object):
302
"""Common tests for both branch 6 and 7 which are mostly the same."""
304
def get_format_name(self):
305
raise NotImplementedError(self.get_format_name)
307
def get_format_name_subtree(self):
308
raise NotImplementedError(self.get_format_name)
311
raise NotImplementedError(self.get_class)
181
class TestBranch6(TestCaseWithTransport):
313
183
def test_creation(self):
314
format = bzrdir.BzrDirMetaFormat1()
184
format = BzrDirMetaFormat1()
315
185
format.set_branch_format(_mod_branch.BzrBranchFormat6())
316
186
branch = self.make_branch('a', format=format)
317
self.assertIsInstance(branch, self.get_class())
318
branch = self.make_branch('b', format=self.get_format_name())
319
self.assertIsInstance(branch, self.get_class())
187
self.assertIsInstance(branch, _mod_branch.BzrBranch6)
188
branch = self.make_branch('b', format='dirstate-tags')
189
self.assertIsInstance(branch, _mod_branch.BzrBranch6)
320
190
branch = _mod_branch.Branch.open('a')
321
self.assertIsInstance(branch, self.get_class())
191
self.assertIsInstance(branch, _mod_branch.BzrBranch6)
323
193
def test_layout(self):
324
branch = self.make_branch('a', format=self.get_format_name())
325
self.assertPathExists('a/.bzr/branch/last-revision')
326
self.assertPathDoesNotExist('a/.bzr/branch/revision-history')
327
self.assertPathDoesNotExist('a/.bzr/branch/references')
194
branch = self.make_branch('a', format='dirstate-tags')
195
self.failUnlessExists('a/.bzr/branch/last-revision')
196
self.failIfExists('a/.bzr/branch/revision-history')
329
198
def test_config(self):
330
199
"""Ensure that all configuration data is stored in the branch"""
331
branch = self.make_branch('a', format=self.get_format_name())
332
branch.set_parent('http://example.com')
333
self.assertPathDoesNotExist('a/.bzr/branch/parent')
334
self.assertEqual('http://example.com', branch.get_parent())
335
branch.set_push_location('sftp://example.com')
200
branch = self.make_branch('a', format='dirstate-tags')
201
branch.set_parent('http://bazaar-vcs.org')
202
self.failIfExists('a/.bzr/branch/parent')
203
self.assertEqual('http://bazaar-vcs.org', branch.get_parent())
204
branch.set_push_location('sftp://bazaar-vcs.org')
336
205
config = branch.get_config()._get_branch_data_config()
337
self.assertEqual('sftp://example.com',
206
self.assertEqual('sftp://bazaar-vcs.org',
338
207
config.get_user_option('push_location'))
339
branch.set_bound_location('ftp://example.com')
340
self.assertPathDoesNotExist('a/.bzr/branch/bound')
341
self.assertEqual('ftp://example.com', branch.get_bound_location())
208
branch.set_bound_location('ftp://bazaar-vcs.org')
209
self.failIfExists('a/.bzr/branch/bound')
210
self.assertEqual('ftp://bazaar-vcs.org', branch.get_bound_location())
343
212
def test_set_revision_history(self):
344
builder = self.make_branch_builder('.', format=self.get_format_name())
345
builder.build_snapshot('foo', None,
346
[('add', ('', None, 'directory', None))],
348
builder.build_snapshot('bar', None, [], message='bar')
349
branch = builder.get_branch()
351
self.addCleanup(branch.unlock)
352
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
353
branch.set_revision_history, ['foo', 'bar'])
354
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
355
branch.set_revision_history, ['foo'])
356
self.assertRaises(errors.NotLefthandHistory,
357
self.applyDeprecated, symbol_versioning.deprecated_in((2, 4, 0)),
358
branch.set_revision_history, ['bar'])
213
tree = self.make_branch_and_memory_tree('.',
214
format='dirstate-tags')
218
tree.commit('foo', rev_id='foo')
219
tree.commit('bar', rev_id='bar')
220
tree.branch.set_revision_history(['foo', 'bar'])
221
tree.branch.set_revision_history(['foo'])
222
self.assertRaises(errors.NotLefthandHistory,
223
tree.branch.set_revision_history, ['bar'])
227
def test_append_revision(self):
228
tree = self.make_branch_and_tree('branch1',
229
format='dirstate-tags')
232
tree.commit('foo', rev_id='foo')
233
tree.commit('bar', rev_id='bar')
234
tree.commit('baz', rev_id='baz')
235
tree.set_last_revision('bar')
236
tree.branch.set_last_revision_info(2, 'bar')
237
tree.commit('qux', rev_id='qux')
238
tree.add_parent_tree_id('baz')
239
tree.commit('qux', rev_id='quxx')
240
tree.branch.set_last_revision_info(0, 'null:')
241
self.assertRaises(errors.NotLeftParentDescendant,
242
tree.branch.append_revision, 'bar')
243
tree.branch.append_revision('foo')
244
self.assertRaises(errors.NotLeftParentDescendant,
245
tree.branch.append_revision, 'baz')
246
tree.branch.append_revision('bar')
247
tree.branch.append_revision('baz')
248
self.assertRaises(errors.NotLeftParentDescendant,
249
tree.branch.append_revision, 'quxx')
360
253
def do_checkout_test(self, lightweight=False):
361
tree = self.make_branch_and_tree('source',
362
format=self.get_format_name_subtree())
254
tree = self.make_branch_and_tree('source', format='dirstate-with-subtree')
363
255
subtree = self.make_branch_and_tree('source/subtree',
364
format=self.get_format_name_subtree())
256
format='dirstate-with-subtree')
365
257
subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
366
format=self.get_format_name_subtree())
258
format='dirstate-with-subtree')
367
259
self.build_tree(['source/subtree/file',
368
260
'source/subtree/subsubtree/file'])
369
261
subsubtree.add('file')
406
299
self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
407
300
'locations.conf')
410
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
413
return _mod_branch.BzrBranch6
415
def get_format_name(self):
416
return "dirstate-tags"
418
def get_format_name_subtree(self):
419
return "dirstate-with-subtree"
421
def test_set_stacked_on_url_errors(self):
422
branch = self.make_branch('a', format=self.get_format_name())
423
self.assertRaises(errors.UnstackableBranchFormat,
424
branch.set_stacked_on_url, None)
426
def test_default_stacked_location(self):
427
branch = self.make_branch('a', format=self.get_format_name())
428
self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
431
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
434
return _mod_branch.BzrBranch7
436
def get_format_name(self):
439
def get_format_name_subtree(self):
440
return "development-subtree"
442
def test_set_stacked_on_url_unstackable_repo(self):
443
repo = self.make_repository('a', format='dirstate-tags')
444
control = repo.bzrdir
445
branch = _mod_branch.BzrBranchFormat7().initialize(control)
446
target = self.make_branch('b')
447
self.assertRaises(errors.UnstackableRepositoryFormat,
448
branch.set_stacked_on_url, target.base)
450
def test_clone_stacked_on_unstackable_repo(self):
451
repo = self.make_repository('a', format='dirstate-tags')
452
control = repo.bzrdir
453
branch = _mod_branch.BzrBranchFormat7().initialize(control)
454
# Calling clone should not raise UnstackableRepositoryFormat.
455
cloned_bzrdir = control.clone('cloned')
457
def _test_default_stacked_location(self):
458
branch = self.make_branch('a', format=self.get_format_name())
459
self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
461
def test_stack_and_unstack(self):
462
branch = self.make_branch('a', format=self.get_format_name())
463
target = self.make_branch_and_tree('b', format=self.get_format_name())
464
branch.set_stacked_on_url(target.branch.base)
465
self.assertEqual(target.branch.base, branch.get_stacked_on_url())
466
revid = target.commit('foo')
467
self.assertTrue(branch.repository.has_revision(revid))
468
branch.set_stacked_on_url(None)
469
self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
470
self.assertFalse(branch.repository.has_revision(revid))
472
def test_open_opens_stacked_reference(self):
473
branch = self.make_branch('a', format=self.get_format_name())
474
target = self.make_branch_and_tree('b', format=self.get_format_name())
475
branch.set_stacked_on_url(target.branch.base)
476
branch = branch.bzrdir.open_branch()
477
revid = target.commit('foo')
478
self.assertTrue(branch.repository.has_revision(revid))
481
class BzrBranch8(tests.TestCaseWithTransport):
483
def make_branch(self, location, format=None):
485
format = bzrdir.format_registry.make_bzrdir('1.9')
486
format.set_branch_format(_mod_branch.BzrBranchFormat8())
487
return tests.TestCaseWithTransport.make_branch(
488
self, location, format=format)
490
def create_branch_with_reference(self):
491
branch = self.make_branch('branch')
492
branch._set_all_reference_info({'file-id': ('path', 'location')})
496
def instrument_branch(branch, gets):
497
old_get = branch._transport.get
498
def get(*args, **kwargs):
499
gets.append((args, kwargs))
500
return old_get(*args, **kwargs)
501
branch._transport.get = get
503
def test_reference_info_caching_read_locked(self):
505
branch = self.create_branch_with_reference()
507
self.addCleanup(branch.unlock)
508
self.instrument_branch(branch, gets)
509
branch.get_reference_info('file-id')
510
branch.get_reference_info('file-id')
511
self.assertEqual(1, len(gets))
513
def test_reference_info_caching_read_unlocked(self):
515
branch = self.create_branch_with_reference()
516
self.instrument_branch(branch, gets)
517
branch.get_reference_info('file-id')
518
branch.get_reference_info('file-id')
519
self.assertEqual(2, len(gets))
521
def test_reference_info_caching_write_locked(self):
523
branch = self.make_branch('branch')
525
self.instrument_branch(branch, gets)
526
self.addCleanup(branch.unlock)
527
branch._set_all_reference_info({'file-id': ('path2', 'location2')})
528
path, location = branch.get_reference_info('file-id')
529
self.assertEqual(0, len(gets))
530
self.assertEqual('path2', path)
531
self.assertEqual('location2', location)
533
def test_reference_info_caches_cleared(self):
534
branch = self.make_branch('branch')
536
branch.set_reference_info('file-id', 'path2', 'location2')
538
doppelganger = _mod_branch.Branch.open('branch')
539
doppelganger.set_reference_info('file-id', 'path3', 'location3')
540
self.assertEqual(('path3', 'location3'),
541
branch.get_reference_info('file-id'))
543
class TestBranchReference(tests.TestCaseWithTransport):
302
class TestBranchReference(TestCaseWithTransport):
544
303
"""Tests for the branch reference facility."""
546
305
def test_create_open_reference(self):
547
306
bzrdirformat = bzrdir.BzrDirMetaFormat1()
548
t = self.get_transport()
307
t = get_transport(self.get_url('.'))
550
309
dir = bzrdirformat.initialize(self.get_url('repo'))
551
310
dir.create_repository()
552
311
target_branch = dir.create_branch()
553
312
t.mkdir('branch')
554
313
branch_dir = bzrdirformat.initialize(self.get_url('branch'))
555
made_branch = _mod_branch.BranchReferenceFormat().initialize(
556
branch_dir, target_branch=target_branch)
314
made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
557
315
self.assertEqual(made_branch.base, target_branch.base)
558
316
opened_branch = branch_dir.open_branch()
559
317
self.assertEqual(opened_branch.base, target_branch.base)
570
328
_mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
573
class TestHooks(tests.TestCaseWithTransport):
331
class TestHooks(TestCase):
575
333
def test_constructor(self):
576
334
"""Check that creating a BranchHooks instance has the right defaults."""
577
hooks = _mod_branch.BranchHooks()
335
hooks = BranchHooks()
578
336
self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
579
337
self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
580
338
self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
581
self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
582
339
self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
583
self.assertTrue("post_uncommit" in hooks,
584
"post_uncommit not in %s" % hooks)
585
self.assertTrue("post_change_branch_tip" in hooks,
586
"post_change_branch_tip not in %s" % hooks)
587
self.assertTrue("post_branch_init" in hooks,
588
"post_branch_init not in %s" % hooks)
589
self.assertTrue("post_switch" in hooks,
590
"post_switch not in %s" % hooks)
340
self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
592
342
def test_installed_hooks_are_BranchHooks(self):
593
343
"""The installed hooks object should be a BranchHooks."""
594
344
# the installed hooks are saved in self._preserved_hooks.
595
self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
596
_mod_branch.BranchHooks)
598
def test_post_branch_init_hook(self):
600
_mod_branch.Branch.hooks.install_named_hook('post_branch_init',
602
self.assertLength(0, calls)
603
branch = self.make_branch('a')
604
self.assertLength(1, calls)
606
self.assertIsInstance(params, _mod_branch.BranchInitHookParams)
607
self.assertTrue(hasattr(params, 'bzrdir'))
608
self.assertTrue(hasattr(params, 'branch'))
610
def test_post_branch_init_hook_repr(self):
612
_mod_branch.Branch.hooks.install_named_hook('post_branch_init',
613
lambda params: param_reprs.append(repr(params)), None)
614
branch = self.make_branch('a')
615
self.assertLength(1, param_reprs)
616
param_repr = param_reprs[0]
617
self.assertStartsWith(param_repr, '<BranchInitHookParams of ')
619
def test_post_switch_hook(self):
620
from bzrlib import switch
622
_mod_branch.Branch.hooks.install_named_hook('post_switch',
624
tree = self.make_branch_and_tree('branch-1')
625
self.build_tree(['branch-1/file-1'])
628
to_branch = tree.bzrdir.sprout('branch-2').open_branch()
629
self.build_tree(['branch-1/file-2'])
631
tree.remove('file-1')
633
checkout = tree.branch.create_checkout('checkout')
634
self.assertLength(0, calls)
635
switch.switch(checkout.bzrdir, to_branch)
636
self.assertLength(1, calls)
638
self.assertIsInstance(params, _mod_branch.SwitchHookParams)
639
self.assertTrue(hasattr(params, 'to_branch'))
640
self.assertTrue(hasattr(params, 'revision_id'))
643
class TestBranchOptions(tests.TestCaseWithTransport):
646
super(TestBranchOptions, self).setUp()
647
self.branch = self.make_branch('.')
648
self.config = self.branch.get_config()
650
def check_append_revisions_only(self, expected_value, value=None):
651
"""Set append_revisions_only in config and check its interpretation."""
652
if value is not None:
653
self.config.set_user_option('append_revisions_only', value)
654
self.assertEqual(expected_value,
655
self.branch._get_append_revisions_only())
657
def test_valid_append_revisions_only(self):
658
self.assertEquals(None,
659
self.config.get_user_option('append_revisions_only'))
660
self.check_append_revisions_only(None)
661
self.check_append_revisions_only(False, 'False')
662
self.check_append_revisions_only(True, 'True')
663
# The following values will cause compatibility problems on projects
664
# using older bzr versions (<2.2) but are accepted
665
self.check_append_revisions_only(False, 'false')
666
self.check_append_revisions_only(True, 'true')
668
def test_invalid_append_revisions_only(self):
669
"""Ensure warning is noted on invalid settings"""
672
self.warnings.append(args[0] % args[1:])
673
self.overrideAttr(trace, 'warning', warning)
674
self.check_append_revisions_only(None, 'not-a-bool')
675
self.assertLength(1, self.warnings)
677
'Value "not-a-bool" is not a boolean for "append_revisions_only"',
681
class TestPullResult(tests.TestCase):
345
self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch], BranchHooks)
348
class TestPullResult(TestCase):
683
350
def test_pull_result_to_int(self):
684
351
# to support old code, the pull result can be used as an int
685
r = _mod_branch.PullResult()
688
355
# this usage of results is not recommended for new code (because it
689
356
# doesn't describe very well what happened), but for api stability
690
357
# it's still supported
691
self.assertEqual(self.applyDeprecated(
692
symbol_versioning.deprecated_in((2, 3, 0)),
696
def test_report_changed(self):
697
r = _mod_branch.PullResult()
698
r.old_revid = "old-revid"
700
r.new_revid = "new-revid"
704
self.assertEqual("Now on revision 20.\n", f.getvalue())
706
def test_report_unchanged(self):
707
r = _mod_branch.PullResult()
708
r.old_revid = "same-revid"
709
r.new_revid = "same-revid"
712
self.assertEqual("No revisions to pull.\n", f.getvalue())
358
a = "%d revisions pulled" % r
359
self.assertEqual(a, "10 revisions pulled")