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,
116
append_revisions_only=None):
121
def initialize(self, a_bzrdir):
117
122
"""Format 4 branches cannot be created."""
118
t = a_bzrdir.get_branch_transport(self, name=name)
123
t = a_bzrdir.get_branch_transport(self)
119
124
t.put_bytes('format', self.get_format_string())
120
125
return 'A branch'
122
127
def is_supported(self):
125
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
130
def open(self, transport, _found=False):
126
131
return "opened branch."
129
# Demonstrating how lazy loading is often implemented:
130
# A constant string is created.
131
SampleSupportedBranchFormatString = "Sample supported branch format."
133
# And the format class can then reference the constant to avoid skew.
134
class SampleSupportedBranchFormat(_mod_branch.BranchFormat):
135
"""A sample supported format."""
137
def get_format_string(self):
138
"""See BzrBranchFormat.get_format_string()."""
139
return SampleSupportedBranchFormatString
141
def initialize(self, a_bzrdir, name=None, append_revisions_only=None):
142
t = a_bzrdir.get_branch_transport(self, name=name)
143
t.put_bytes('format', self.get_format_string())
146
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
147
return "opened supported branch."
150
class SampleExtraBranchFormat(_mod_branch.BranchFormat):
151
"""A sample format that is not usable in a metadir."""
153
def get_format_string(self):
154
# This format is not usable in a metadir.
157
def network_name(self):
158
# Network name always has to be provided.
161
def initialize(self, a_bzrdir, name=None):
162
raise NotImplementedError(self.initialize)
164
def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
165
raise NotImplementedError(self.open)
168
class TestBzrBranchFormat(tests.TestCaseWithTransport):
134
class TestBzrBranchFormat(TestCaseWithTransport):
169
135
"""Tests for the BzrBranchFormat facility."""
171
137
def test_find_format(self):
172
138
# is the right format object found for a branch?
173
139
# create a branch with a few known format objects.
174
# this is not quite the same as
140
# this is not quite the same as
175
141
self.build_tree(["foo/", "bar/"])
176
142
def check_format(format, url):
177
143
dir = format._matchingbzrdir.initialize(url)
178
144
dir.create_repository()
179
145
format.initialize(dir)
180
found_format = _mod_branch.BranchFormat.find_format(dir)
181
self.assertIsInstance(found_format, format.__class__)
182
check_format(_mod_branch.BzrBranchFormat5(), "bar")
184
def test_find_format_factory(self):
185
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
186
SampleSupportedBranchFormat().initialize(dir)
187
factory = _mod_branch.MetaDirBranchFormatFactory(
188
SampleSupportedBranchFormatString,
189
"bzrlib.tests.test_branch", "SampleSupportedBranchFormat")
190
_mod_branch.format_registry.register(factory)
191
self.addCleanup(_mod_branch.format_registry.remove, factory)
192
b = _mod_branch.Branch.open(self.get_url())
193
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")
195
150
def test_find_format_not_branch(self):
196
151
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
197
self.assertRaises(errors.NotBranchError,
198
_mod_branch.BranchFormat.find_format,
152
self.assertRaises(NotBranchError,
153
BranchFormat.find_format,
201
156
def test_find_format_unknown_format(self):
202
157
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
203
158
SampleBranchFormat().initialize(dir)
204
self.assertRaises(errors.UnknownFormatError,
205
_mod_branch.BranchFormat.find_format,
159
self.assertRaises(UnknownFormatError,
160
BranchFormat.find_format,
208
163
def test_register_unregister_format(self):
209
# Test the deprecated format registration functions
210
164
format = SampleBranchFormat()
211
165
# make a control dir
212
166
dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
214
168
format.initialize(dir)
215
169
# register a format for it.
216
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
217
_mod_branch.BranchFormat.register_format, format)
170
BranchFormat.register_format(format)
218
171
# which branch.Open will refuse (not supported)
219
self.assertRaises(errors.UnsupportedFormatError,
220
_mod_branch.Branch.open, self.get_url())
172
self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
221
173
self.make_branch_and_tree('foo')
222
174
# but open_downlevel will work
225
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))
226
176
# unregister the format
227
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
228
_mod_branch.BranchFormat.unregister_format, format)
177
BranchFormat.unregister_format(format)
229
178
self.make_branch_and_tree('bar')
232
class TestBranchFormatRegistry(tests.TestCase):
235
super(TestBranchFormatRegistry, self).setUp()
236
self.registry = _mod_branch.BranchFormatRegistry()
238
def test_default(self):
239
self.assertIs(None, self.registry.get_default())
240
format = SampleBranchFormat()
241
self.registry.set_default(format)
242
self.assertEquals(format, self.registry.get_default())
244
def test_register_unregister_format(self):
245
format = SampleBranchFormat()
246
self.registry.register(format)
247
self.assertEquals(format,
248
self.registry.get("Sample branch format."))
249
self.registry.remove(format)
250
self.assertRaises(KeyError, self.registry.get,
251
"Sample branch format.")
253
def test_get_all(self):
254
format = SampleBranchFormat()
255
self.assertEquals([], self.registry._get_all())
256
self.registry.register(format)
257
self.assertEquals([format], self.registry._get_all())
259
def test_register_extra(self):
260
format = SampleExtraBranchFormat()
261
self.assertEquals([], self.registry._get_all())
262
self.registry.register_extra(format)
263
self.assertEquals([format], self.registry._get_all())
265
def test_register_extra_lazy(self):
266
self.assertEquals([], self.registry._get_all())
267
self.registry.register_extra_lazy("bzrlib.tests.test_branch",
268
"SampleExtraBranchFormat")
269
formats = self.registry._get_all()
270
self.assertEquals(1, len(formats))
271
self.assertIsInstance(formats[0], SampleExtraBranchFormat)
274
#Used by TestMetaDirBranchFormatFactory
275
FakeLazyFormat = None
278
class TestMetaDirBranchFormatFactory(tests.TestCase):
280
def test_get_format_string_does_not_load(self):
281
"""Formats have a static format string."""
282
factory = _mod_branch.MetaDirBranchFormatFactory("yo", None, None)
283
self.assertEqual("yo", factory.get_format_string())
285
def test_call_loads(self):
286
# __call__ is used by the network_format_registry interface to get a
288
global FakeLazyFormat
290
factory = _mod_branch.MetaDirBranchFormatFactory(None,
291
"bzrlib.tests.test_branch", "FakeLazyFormat")
292
self.assertRaises(AttributeError, factory)
294
def test_call_returns_call_of_referenced_object(self):
295
global FakeLazyFormat
296
FakeLazyFormat = lambda:'called'
297
factory = _mod_branch.MetaDirBranchFormatFactory(None,
298
"bzrlib.tests.test_branch", "FakeLazyFormat")
299
self.assertEqual('called', factory())
302
class TestBranch67(object):
303
"""Common tests for both branch 6 and 7 which are mostly the same."""
305
def get_format_name(self):
306
raise NotImplementedError(self.get_format_name)
308
def get_format_name_subtree(self):
309
raise NotImplementedError(self.get_format_name)
312
raise NotImplementedError(self.get_class)
181
class TestBranch6(TestCaseWithTransport):
314
183
def test_creation(self):
315
format = bzrdir.BzrDirMetaFormat1()
184
format = BzrDirMetaFormat1()
316
185
format.set_branch_format(_mod_branch.BzrBranchFormat6())
317
186
branch = self.make_branch('a', format=format)
318
self.assertIsInstance(branch, self.get_class())
319
branch = self.make_branch('b', format=self.get_format_name())
320
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)
321
190
branch = _mod_branch.Branch.open('a')
322
self.assertIsInstance(branch, self.get_class())
191
self.assertIsInstance(branch, _mod_branch.BzrBranch6)
324
193
def test_layout(self):
325
branch = self.make_branch('a', format=self.get_format_name())
326
self.assertPathExists('a/.bzr/branch/last-revision')
327
self.assertPathDoesNotExist('a/.bzr/branch/revision-history')
328
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')
330
198
def test_config(self):
331
199
"""Ensure that all configuration data is stored in the branch"""
332
branch = self.make_branch('a', format=self.get_format_name())
333
branch.set_parent('http://example.com')
334
self.assertPathDoesNotExist('a/.bzr/branch/parent')
335
self.assertEqual('http://example.com', branch.get_parent())
336
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')
337
205
config = branch.get_config()._get_branch_data_config()
338
self.assertEqual('sftp://example.com',
206
self.assertEqual('sftp://bazaar-vcs.org',
339
207
config.get_user_option('push_location'))
340
branch.set_bound_location('ftp://example.com')
341
self.assertPathDoesNotExist('a/.bzr/branch/bound')
342
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())
344
212
def test_set_revision_history(self):
345
builder = self.make_branch_builder('.', format=self.get_format_name())
346
builder.build_snapshot('foo', None,
347
[('add', ('', None, 'directory', None))],
349
builder.build_snapshot('bar', None, [], message='bar')
350
branch = builder.get_branch()
352
self.addCleanup(branch.unlock)
353
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
354
branch.set_revision_history, ['foo', 'bar'])
355
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
356
branch.set_revision_history, ['foo'])
357
self.assertRaises(errors.NotLefthandHistory,
358
self.applyDeprecated, symbol_versioning.deprecated_in((2, 4, 0)),
359
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')
361
253
def do_checkout_test(self, lightweight=False):
362
tree = self.make_branch_and_tree('source',
363
format=self.get_format_name_subtree())
254
tree = self.make_branch_and_tree('source', format='dirstate-with-subtree')
364
255
subtree = self.make_branch_and_tree('source/subtree',
365
format=self.get_format_name_subtree())
256
format='dirstate-with-subtree')
366
257
subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
367
format=self.get_format_name_subtree())
258
format='dirstate-with-subtree')
368
259
self.build_tree(['source/subtree/file',
369
260
'source/subtree/subsubtree/file'])
370
261
subsubtree.add('file')
407
299
self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
408
300
'locations.conf')
411
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
414
return _mod_branch.BzrBranch6
416
def get_format_name(self):
417
return "dirstate-tags"
419
def get_format_name_subtree(self):
420
return "dirstate-with-subtree"
422
def test_set_stacked_on_url_errors(self):
423
branch = self.make_branch('a', format=self.get_format_name())
424
self.assertRaises(errors.UnstackableBranchFormat,
425
branch.set_stacked_on_url, None)
427
def test_default_stacked_location(self):
428
branch = self.make_branch('a', format=self.get_format_name())
429
self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
432
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
435
return _mod_branch.BzrBranch7
437
def get_format_name(self):
440
def get_format_name_subtree(self):
441
return "development-subtree"
443
def test_set_stacked_on_url_unstackable_repo(self):
444
repo = self.make_repository('a', format='dirstate-tags')
445
control = repo.bzrdir
446
branch = _mod_branch.BzrBranchFormat7().initialize(control)
447
target = self.make_branch('b')
448
self.assertRaises(errors.UnstackableRepositoryFormat,
449
branch.set_stacked_on_url, target.base)
451
def test_clone_stacked_on_unstackable_repo(self):
452
repo = self.make_repository('a', format='dirstate-tags')
453
control = repo.bzrdir
454
branch = _mod_branch.BzrBranchFormat7().initialize(control)
455
# Calling clone should not raise UnstackableRepositoryFormat.
456
cloned_bzrdir = control.clone('cloned')
458
def _test_default_stacked_location(self):
459
branch = self.make_branch('a', format=self.get_format_name())
460
self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
462
def test_stack_and_unstack(self):
463
branch = self.make_branch('a', format=self.get_format_name())
464
target = self.make_branch_and_tree('b', format=self.get_format_name())
465
branch.set_stacked_on_url(target.branch.base)
466
self.assertEqual(target.branch.base, branch.get_stacked_on_url())
467
revid = target.commit('foo')
468
self.assertTrue(branch.repository.has_revision(revid))
469
branch.set_stacked_on_url(None)
470
self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
471
self.assertFalse(branch.repository.has_revision(revid))
473
def test_open_opens_stacked_reference(self):
474
branch = self.make_branch('a', format=self.get_format_name())
475
target = self.make_branch_and_tree('b', format=self.get_format_name())
476
branch.set_stacked_on_url(target.branch.base)
477
branch = branch.bzrdir.open_branch()
478
revid = target.commit('foo')
479
self.assertTrue(branch.repository.has_revision(revid))
482
class BzrBranch8(tests.TestCaseWithTransport):
484
def make_branch(self, location, format=None):
486
format = bzrdir.format_registry.make_bzrdir('1.9')
487
format.set_branch_format(_mod_branch.BzrBranchFormat8())
488
return tests.TestCaseWithTransport.make_branch(
489
self, location, format=format)
491
def create_branch_with_reference(self):
492
branch = self.make_branch('branch')
493
branch._set_all_reference_info({'file-id': ('path', 'location')})
497
def instrument_branch(branch, gets):
498
old_get = branch._transport.get
499
def get(*args, **kwargs):
500
gets.append((args, kwargs))
501
return old_get(*args, **kwargs)
502
branch._transport.get = get
504
def test_reference_info_caching_read_locked(self):
506
branch = self.create_branch_with_reference()
508
self.addCleanup(branch.unlock)
509
self.instrument_branch(branch, gets)
510
branch.get_reference_info('file-id')
511
branch.get_reference_info('file-id')
512
self.assertEqual(1, len(gets))
514
def test_reference_info_caching_read_unlocked(self):
516
branch = self.create_branch_with_reference()
517
self.instrument_branch(branch, gets)
518
branch.get_reference_info('file-id')
519
branch.get_reference_info('file-id')
520
self.assertEqual(2, len(gets))
522
def test_reference_info_caching_write_locked(self):
524
branch = self.make_branch('branch')
526
self.instrument_branch(branch, gets)
527
self.addCleanup(branch.unlock)
528
branch._set_all_reference_info({'file-id': ('path2', 'location2')})
529
path, location = branch.get_reference_info('file-id')
530
self.assertEqual(0, len(gets))
531
self.assertEqual('path2', path)
532
self.assertEqual('location2', location)
534
def test_reference_info_caches_cleared(self):
535
branch = self.make_branch('branch')
537
branch.set_reference_info('file-id', 'path2', 'location2')
539
doppelganger = _mod_branch.Branch.open('branch')
540
doppelganger.set_reference_info('file-id', 'path3', 'location3')
541
self.assertEqual(('path3', 'location3'),
542
branch.get_reference_info('file-id'))
544
class TestBranchReference(tests.TestCaseWithTransport):
302
class TestBranchReference(TestCaseWithTransport):
545
303
"""Tests for the branch reference facility."""
547
305
def test_create_open_reference(self):
548
306
bzrdirformat = bzrdir.BzrDirMetaFormat1()
549
t = self.get_transport()
307
t = get_transport(self.get_url('.'))
551
309
dir = bzrdirformat.initialize(self.get_url('repo'))
552
310
dir.create_repository()
553
311
target_branch = dir.create_branch()
554
312
t.mkdir('branch')
555
313
branch_dir = bzrdirformat.initialize(self.get_url('branch'))
556
made_branch = _mod_branch.BranchReferenceFormat().initialize(
557
branch_dir, target_branch=target_branch)
314
made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
558
315
self.assertEqual(made_branch.base, target_branch.base)
559
316
opened_branch = branch_dir.open_branch()
560
317
self.assertEqual(opened_branch.base, target_branch.base)
571
328
_mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
574
class TestHooks(tests.TestCaseWithTransport):
331
class TestHooks(TestCase):
576
333
def test_constructor(self):
577
334
"""Check that creating a BranchHooks instance has the right defaults."""
578
hooks = _mod_branch.BranchHooks()
335
hooks = BranchHooks()
579
336
self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
580
337
self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
581
338
self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
582
self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
583
339
self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
584
self.assertTrue("post_uncommit" in hooks,
585
"post_uncommit not in %s" % hooks)
586
self.assertTrue("post_change_branch_tip" in hooks,
587
"post_change_branch_tip not in %s" % hooks)
588
self.assertTrue("post_branch_init" in hooks,
589
"post_branch_init not in %s" % hooks)
590
self.assertTrue("post_switch" in hooks,
591
"post_switch not in %s" % hooks)
340
self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
593
342
def test_installed_hooks_are_BranchHooks(self):
594
343
"""The installed hooks object should be a BranchHooks."""
595
344
# the installed hooks are saved in self._preserved_hooks.
596
self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
597
_mod_branch.BranchHooks)
599
def test_post_branch_init_hook(self):
601
_mod_branch.Branch.hooks.install_named_hook('post_branch_init',
603
self.assertLength(0, calls)
604
branch = self.make_branch('a')
605
self.assertLength(1, calls)
607
self.assertIsInstance(params, _mod_branch.BranchInitHookParams)
608
self.assertTrue(hasattr(params, 'bzrdir'))
609
self.assertTrue(hasattr(params, 'branch'))
611
def test_post_branch_init_hook_repr(self):
613
_mod_branch.Branch.hooks.install_named_hook('post_branch_init',
614
lambda params: param_reprs.append(repr(params)), None)
615
branch = self.make_branch('a')
616
self.assertLength(1, param_reprs)
617
param_repr = param_reprs[0]
618
self.assertStartsWith(param_repr, '<BranchInitHookParams of ')
620
def test_post_switch_hook(self):
621
from bzrlib import switch
623
_mod_branch.Branch.hooks.install_named_hook('post_switch',
625
tree = self.make_branch_and_tree('branch-1')
626
self.build_tree(['branch-1/file-1'])
629
to_branch = tree.bzrdir.sprout('branch-2').open_branch()
630
self.build_tree(['branch-1/file-2'])
632
tree.remove('file-1')
634
checkout = tree.branch.create_checkout('checkout')
635
self.assertLength(0, calls)
636
switch.switch(checkout.bzrdir, to_branch)
637
self.assertLength(1, calls)
639
self.assertIsInstance(params, _mod_branch.SwitchHookParams)
640
self.assertTrue(hasattr(params, 'to_branch'))
641
self.assertTrue(hasattr(params, 'revision_id'))
644
class TestBranchOptions(tests.TestCaseWithTransport):
647
super(TestBranchOptions, self).setUp()
648
self.branch = self.make_branch('.')
649
self.config = self.branch.get_config()
651
def check_append_revisions_only(self, expected_value, value=None):
652
"""Set append_revisions_only in config and check its interpretation."""
653
if value is not None:
654
self.config.set_user_option('append_revisions_only', value)
655
self.assertEqual(expected_value,
656
self.branch.get_append_revisions_only())
658
def test_valid_append_revisions_only(self):
659
self.assertEquals(None,
660
self.config.get_user_option('append_revisions_only'))
661
self.check_append_revisions_only(None)
662
self.check_append_revisions_only(False, 'False')
663
self.check_append_revisions_only(True, 'True')
664
# The following values will cause compatibility problems on projects
665
# using older bzr versions (<2.2) but are accepted
666
self.check_append_revisions_only(False, 'false')
667
self.check_append_revisions_only(True, 'true')
669
def test_invalid_append_revisions_only(self):
670
"""Ensure warning is noted on invalid settings"""
673
self.warnings.append(args[0] % args[1:])
674
self.overrideAttr(trace, 'warning', warning)
675
self.check_append_revisions_only(None, 'not-a-bool')
676
self.assertLength(1, self.warnings)
678
'Value "not-a-bool" is not a boolean for "append_revisions_only"',
682
class TestPullResult(tests.TestCase):
345
self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch], BranchHooks)
348
class TestPullResult(TestCase):
684
350
def test_pull_result_to_int(self):
685
351
# to support old code, the pull result can be used as an int
686
r = _mod_branch.PullResult()
689
355
# this usage of results is not recommended for new code (because it
690
356
# doesn't describe very well what happened), but for api stability
691
357
# it's still supported
692
self.assertEqual(self.applyDeprecated(
693
symbol_versioning.deprecated_in((2, 3, 0)),
697
def test_report_changed(self):
698
r = _mod_branch.PullResult()
699
r.old_revid = "old-revid"
701
r.new_revid = "new-revid"
705
self.assertEqual("Now on revision 20.\n", f.getvalue())
707
def test_report_unchanged(self):
708
r = _mod_branch.PullResult()
709
r.old_revid = "same-revid"
710
r.new_revid = "same-revid"
713
self.assertEqual("No revisions or tags to pull.\n", f.getvalue())
358
a = "%d revisions pulled" % r
359
self.assertEqual(a, "10 revisions pulled")