65
def vary_by_conflicts():
66
for conflict in example_conflicts:
67
yield (conflict.__class__.__name__, {"conflict": conflict})
70
64
class TestConflicts(tests.TestCaseWithTransport):
66
def test_conflicts(self):
67
"""Conflicts are detected properly"""
68
# Use BzrDirFormat6 so we can fake conflicts
69
tree = self.make_branch_and_tree('.', format=bzrdir.BzrDirFormat6())
70
self.build_tree_contents([('hello', 'hello world4'),
71
('hello.THIS', 'hello world2'),
72
('hello.BASE', 'hello world1'),
73
('hello.OTHER', 'hello world3'),
74
('hello.sploo.BASE', 'yellowworld'),
75
('hello.sploo.OTHER', 'yellowworld2'),
78
self.assertLength(6, list(tree.list_files()))
80
tree_conflicts = tree.conflicts()
81
self.assertLength(2, tree_conflicts)
82
self.assertTrue('hello' in tree_conflicts[0].path)
83
self.assertTrue('hello.sploo' in tree_conflicts[1].path)
84
conflicts.restore('hello')
85
conflicts.restore('hello.sploo')
86
self.assertLength(0, tree.conflicts())
87
self.assertFileEqual('hello world2', 'hello')
88
self.assertFalse(os.path.lexists('hello.sploo'))
89
self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
90
self.assertRaises(errors.NotConflicted,
91
conflicts.restore, 'hello.sploo')
72
93
def test_resolve_conflict_dir(self):
73
94
tree = self.make_branch_and_tree('.')
74
95
self.build_tree_contents([('hello', 'hello world4'),
125
146
self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
128
class TestPerConflict(tests.TestCase):
130
scenarios = scenarios.multiply_scenarios(vary_by_conflicts())
132
def test_stringification(self):
133
text = unicode(self.conflict)
134
self.assertContainsString(text, self.conflict.path)
135
self.assertContainsString(text.lower(), "conflict")
136
self.assertContainsString(repr(self.conflict),
137
self.conflict.__class__.__name__)
149
class TestConflictStanzas(tests.TestCase):
139
151
def test_stanza_roundtrip(self):
141
o = conflicts.Conflict.factory(**p.as_stanza().as_dict())
142
self.assertEqual(o, p)
144
self.assertIsInstance(o.path, unicode)
146
if o.file_id is not None:
147
self.assertIsInstance(o.file_id, str)
149
conflict_path = getattr(o, 'conflict_path', None)
150
if conflict_path is not None:
151
self.assertIsInstance(conflict_path, unicode)
153
conflict_file_id = getattr(o, 'conflict_file_id', None)
154
if conflict_file_id is not None:
155
self.assertIsInstance(conflict_file_id, str)
152
# write and read our example stanza.
153
stanza_iter = example_conflicts.to_stanzas()
154
processed = conflicts.ConflictList.from_stanzas(stanza_iter)
155
for o, p in zip(processed, example_conflicts):
156
self.assertEqual(o, p)
158
self.assertIsInstance(o.path, unicode)
160
if o.file_id is not None:
161
self.assertIsInstance(o.file_id, str)
163
conflict_path = getattr(o, 'conflict_path', None)
164
if conflict_path is not None:
165
self.assertIsInstance(conflict_path, unicode)
167
conflict_file_id = getattr(o, 'conflict_file_id', None)
168
if conflict_file_id is not None:
169
self.assertIsInstance(conflict_file_id, str)
157
171
def test_stanzification(self):
158
stanza = self.conflict.as_stanza()
159
if 'file_id' in stanza:
160
# In Stanza form, the file_id has to be unicode.
161
self.assertStartsWith(stanza['file_id'], u'\xeed')
162
self.assertStartsWith(stanza['path'], u'p\xe5th')
163
if 'conflict_path' in stanza:
164
self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
165
if 'conflict_file_id' in stanza:
166
self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
169
class TestConflictList(tests.TestCase):
171
def test_stanzas_roundtrip(self):
172
stanzas_iter = example_conflicts.to_stanzas()
173
processed = conflicts.ConflictList.from_stanzas(stanzas_iter)
174
self.assertEqual(example_conflicts, processed)
176
def test_stringification(self):
177
for text, o in zip(example_conflicts.to_strings(), example_conflicts):
178
self.assertEqual(text, unicode(o))
172
for stanza in example_conflicts.to_stanzas():
173
if 'file_id' in stanza:
174
# In Stanza form, the file_id has to be unicode.
175
self.assertStartsWith(stanza['file_id'], u'\xeed')
176
self.assertStartsWith(stanza['path'], u'p\xe5th')
177
if 'conflict_path' in stanza:
178
self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
179
if 'conflict_file_id' in stanza:
180
self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
181
183
# FIXME: The shell-like tests should be converted to real whitebox tests... or
375
377
scenarios = mirror_scenarios(
377
# File modified on both sides
379
# File modified/deleted
378
380
(dict(_base_actions='create_file',
379
381
_path='file', _file_id='file-id'),
380
382
('filed_modified_A',
381
383
dict(actions='modify_file_A', check='file_has_content_A')),
382
384
('file_modified_B',
383
385
dict(actions='modify_file_B', check='file_has_content_B')),),
384
# File modified on both sides in dir
385
(dict(_base_actions='create_file_in_dir',
386
_path='dir/file', _file_id='file-id'),
387
('filed_modified_A_in_dir',
388
dict(actions='modify_file_A',
389
check='file_in_dir_has_content_A')),
391
dict(actions='modify_file_B',
392
check='file_in_dir_has_content_B')),),
395
def do_create_file(self, path='file'):
396
return [('add', (path, 'file-id', 'file', 'trunk content\n'))]
388
def do_create_file(self):
389
return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
398
391
def do_modify_file_A(self):
399
392
return [('modify', ('file-id', 'trunk content\nfeature A\n'))]
401
394
def do_modify_file_B(self):
402
395
return [('modify', ('file-id', 'trunk content\nfeature B\n'))]
404
def check_file_has_content_A(self, path='file'):
405
self.assertFileEqual('trunk content\nfeature A\n',
406
osutils.pathjoin('branch', path))
408
def check_file_has_content_B(self, path='file'):
409
self.assertFileEqual('trunk content\nfeature B\n',
410
osutils.pathjoin('branch', path))
412
def do_create_file_in_dir(self):
413
return [('add', ('dir', 'dir-id', 'directory', '')),
414
] + self.do_create_file('dir/file')
416
def check_file_in_dir_has_content_A(self):
417
self.check_file_has_content_A('dir/file')
419
def check_file_in_dir_has_content_B(self):
420
self.check_file_has_content_B('dir/file')
397
def check_file_has_content_A(self):
398
self.assertFileEqual('trunk content\nfeature A\n', 'branch/file')
400
def check_file_has_content_B(self):
401
self.assertFileEqual('trunk content\nfeature B\n', 'branch/file')
422
403
def _get_resolve_path_arg(self, wt, action):
423
404
return self._path
446
427
dict(actions='modify_file', check='file_has_more_content')),
448
429
dict(actions='delete_file', check='file_doesnt_exist')),),
449
# File renamed-modified/deleted
450
(dict(_base_actions='create_file',
451
_path='new-file', _file_id='file-id'),
452
('file_renamed_and_modified',
453
dict(actions='modify_and_rename_file',
454
check='file_renamed_and_more_content')),
456
dict(actions='delete_file', check='file_doesnt_exist')),),
457
430
# File modified/deleted in dir
458
431
(dict(_base_actions='create_file_in_dir',
459
432
_path='dir/file', _file_id='file-id'),
471
444
def do_modify_file(self):
472
445
return [('modify', ('file-id', 'trunk content\nmore content\n'))]
474
def do_modify_and_rename_file(self):
475
return [('modify', ('file-id', 'trunk content\nmore content\n')),
476
('rename', ('file', 'new-file'))]
478
447
def check_file_has_more_content(self):
479
448
self.assertFileEqual('trunk content\nmore content\n', 'branch/file')
481
def check_file_renamed_and_more_content(self):
482
self.assertFileEqual('trunk content\nmore content\n', 'branch/new-file')
484
450
def do_delete_file(self):
485
451
return [('unversion', 'file-id')]
487
453
def check_file_doesnt_exist(self):
488
self.assertPathDoesNotExist('branch/file')
454
self.failIfExists('branch/file')
490
456
def do_create_file_in_dir(self):
491
457
return [('add', ('dir', 'dir-id', 'directory', '')),
579
545
return [('rename', ('file', 'new-file'))]
581
547
def check_file_renamed(self):
582
self.assertPathDoesNotExist('branch/file')
583
self.assertPathExists('branch/new-file')
548
self.failIfExists('branch/file')
549
self.failUnlessExists('branch/new-file')
585
551
def do_rename_file2(self):
586
552
return [('rename', ('file', 'new-file2'))]
588
554
def check_file_renamed2(self):
589
self.assertPathDoesNotExist('branch/file')
590
self.assertPathExists('branch/new-file2')
555
self.failIfExists('branch/file')
556
self.failUnlessExists('branch/new-file2')
592
558
def do_rename_dir(self):
593
559
return [('rename', ('dir', 'new-dir'))]
595
561
def check_dir_renamed(self):
596
self.assertPathDoesNotExist('branch/dir')
597
self.assertPathExists('branch/new-dir')
562
self.failIfExists('branch/dir')
563
self.failUnlessExists('branch/new-dir')
599
565
def do_rename_dir2(self):
600
566
return [('rename', ('dir', 'new-dir2'))]
602
568
def check_dir_renamed2(self):
603
self.assertPathDoesNotExist('branch/dir')
604
self.assertPathExists('branch/new-dir2')
569
self.failIfExists('branch/dir')
570
self.failUnlessExists('branch/new-dir2')
606
572
def do_delete_file(self):
607
573
return [('unversion', 'file-id')]
609
575
def check_file_doesnt_exist(self):
610
self.assertPathDoesNotExist('branch/file')
576
self.failIfExists('branch/file')
612
578
def do_delete_dir(self):
613
579
return [('unversion', 'dir-id')]
615
581
def check_dir_doesnt_exist(self):
616
self.assertPathDoesNotExist('branch/dir')
582
self.failIfExists('branch/dir')
618
584
def do_create_file_in_dir(self):
619
585
return [('add', ('dir', 'dir-id', 'directory', '')),
623
589
return [('rename', ('dir/file', 'dir/new-file'))]
625
591
def check_file_in_dir_renamed(self):
626
self.assertPathDoesNotExist('branch/dir/file')
627
self.assertPathExists('branch/dir/new-file')
592
self.failIfExists('branch/dir/file')
593
self.failUnlessExists('branch/dir/new-file')
629
595
def check_file_in_dir_doesnt_exist(self):
630
self.assertPathDoesNotExist('branch/dir/file')
596
self.failIfExists('branch/dir/file')
632
598
def _get_resolve_path_arg(self, wt, action):
633
599
tpath = self._this['path']
924
890
return [('rename', ('dir1', 'dir2/dir1'))]
926
892
def check_dir1_moved(self):
927
self.assertPathDoesNotExist('branch/dir1')
928
self.assertPathExists('branch/dir2/dir1')
893
self.failIfExists('branch/dir1')
894
self.failUnlessExists('branch/dir2/dir1')
930
896
def do_move_dir2_into_dir1(self):
931
897
return [('rename', ('dir2', 'dir1/dir2'))]
933
899
def check_dir2_moved(self):
934
self.assertPathDoesNotExist('branch/dir2')
935
self.assertPathExists('branch/dir1/dir2')
900
self.failIfExists('branch/dir2')
901
self.failUnlessExists('branch/dir1/dir2')
937
903
def do_create_dir1_4(self):
938
904
return [('add', ('dir1', 'dir1-id', 'directory', '')),
944
910
return [('rename', ('dir1', 'dir3/dir4/dir1'))]
946
912
def check_dir1_2_moved(self):
947
self.assertPathDoesNotExist('branch/dir1')
948
self.assertPathExists('branch/dir3/dir4/dir1')
949
self.assertPathExists('branch/dir3/dir4/dir1/dir2')
913
self.failIfExists('branch/dir1')
914
self.failUnlessExists('branch/dir3/dir4/dir1')
915
self.failUnlessExists('branch/dir3/dir4/dir1/dir2')
951
917
def do_move_dir3_into_dir2(self):
952
918
return [('rename', ('dir3', 'dir1/dir2/dir3'))]
954
920
def check_dir3_4_moved(self):
955
self.assertPathDoesNotExist('branch/dir3')
956
self.assertPathExists('branch/dir1/dir2/dir3')
957
self.assertPathExists('branch/dir1/dir2/dir3/dir4')
921
self.failIfExists('branch/dir3')
922
self.failUnlessExists('branch/dir1/dir2/dir3')
923
self.failUnlessExists('branch/dir1/dir2/dir3/dir4')
959
925
def _get_resolve_path_arg(self, wt, action):
960
926
# ParentLoop says: moving <conflict_path> into <path>. Cancelled move.
1066
class TestNoFinalPath(script.TestCaseWithTransportAndScript):
1068
def test_bug_805809(self):
1071
Created a standalone tree (format: 2a)
1076
$ bzr commit -m 'create file on trunk'
1077
2>Committing to: .../trunk/
1079
2>Committed revision 1.
1080
# Create a debian branch based on trunk
1082
$ bzr branch trunk -r 1 debian
1083
2>Branched 1 revision.
1090
$ bzr commit -m 'rename file to dir/file for debian'
1091
2>Committing to: .../debian/
1093
2>renamed file => dir/file
1094
2>Committed revision 2.
1095
# Create an experimental branch with a new root-id
1097
$ bzr init experimental
1098
Created a standalone tree (format: 2a)
1100
# Work around merging into empty branch not being supported
1101
# (http://pad.lv/308562)
1102
$ echo something >not-empty
1105
$ bzr commit -m 'Add some content in experimental'
1106
2>Committing to: .../experimental/
1108
2>Committed revision 1.
1109
# merge debian even without a common ancestor
1110
$ bzr merge ../debian -r0..2
1113
2>All changes applied successfully.
1114
$ bzr commit -m 'merging debian into experimental'
1115
2>Committing to: .../experimental/
1118
2>Committed revision 2.
1119
# Create an ubuntu branch with yet another root-id
1122
Created a standalone tree (format: 2a)
1124
# Work around merging into empty branch not being supported
1125
# (http://pad.lv/308562)
1126
$ echo something >not-empty-ubuntu
1128
adding not-empty-ubuntu
1129
$ bzr commit -m 'Add some content in experimental'
1130
2>Committing to: .../ubuntu/
1131
2>added not-empty-ubuntu
1132
2>Committed revision 1.
1134
$ bzr merge ../debian -r0..2
1137
2>All changes applied successfully.
1138
$ bzr commit -m 'merging debian'
1139
2>Committing to: .../ubuntu/
1142
2>Committed revision 2.
1143
# Now try to merge experimental
1144
$ bzr merge ../experimental
1146
2>Path conflict: dir / dir
1147
2>1 conflicts encountered.
1151
1032
class TestResolveActionOption(tests.TestCase):
1153
1034
def setUp(self):