~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_conflicts.py

  • Committer: Andrew Bennetts
  • Date: 2010-10-08 04:25:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5472.
  • Revision ID: andrew.bennetts@canonical.com-20101008042510-sg9vdhmnggilzxsk
Fix stray TAB in source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
18
18
import os
19
19
 
20
20
from bzrlib import (
 
21
    branchbuilder,
21
22
    bzrdir,
22
23
    conflicts,
23
24
    errors,
24
25
    option,
25
 
    osutils,
26
26
    tests,
27
 
    )
28
 
from bzrlib.tests import (
29
 
    script,
30
 
    scenarios,
31
 
    )
32
 
 
33
 
 
34
 
load_tests = scenarios.load_tests_apply_scenarios
 
27
    workingtree,
 
28
    )
 
29
from bzrlib.tests import script
 
30
 
 
31
 
 
32
def load_tests(standard_tests, module, loader):
 
33
    result = loader.suiteClass()
 
34
 
 
35
    sp_tests, remaining_tests = tests.split_suite_by_condition(
 
36
        standard_tests, tests.condition_isinstance((
 
37
                TestParametrizedResolveConflicts,
 
38
                )))
 
39
    # Each test class defines its own scenarios. This is needed for
 
40
    # TestResolvePathConflictBefore531967 that verifies that the same tests as
 
41
    # TestResolvePathConflict still pass.
 
42
    for test in tests.iter_suite_tests(sp_tests):
 
43
        tests.apply_scenarios(test, test.scenarios(), result)
 
44
 
 
45
    # No parametrization for the remaining tests
 
46
    result.addTests(remaining_tests)
 
47
 
 
48
    return result
35
49
 
36
50
 
37
51
# TODO: Test commit with some added, and added-but-missing files
64
78
 
65
79
class TestConflicts(tests.TestCaseWithTransport):
66
80
 
 
81
    def test_conflicts(self):
 
82
        """Conflicts are detected properly"""
 
83
        # Use BzrDirFormat6 so we can fake conflicts
 
84
        tree = self.make_branch_and_tree('.', format=bzrdir.BzrDirFormat6())
 
85
        self.build_tree_contents([('hello', 'hello world4'),
 
86
                                  ('hello.THIS', 'hello world2'),
 
87
                                  ('hello.BASE', 'hello world1'),
 
88
                                  ('hello.OTHER', 'hello world3'),
 
89
                                  ('hello.sploo.BASE', 'yellowworld'),
 
90
                                  ('hello.sploo.OTHER', 'yellowworld2'),
 
91
                                  ])
 
92
        tree.lock_read()
 
93
        self.assertLength(6, list(tree.list_files()))
 
94
        tree.unlock()
 
95
        tree_conflicts = tree.conflicts()
 
96
        self.assertLength(2, tree_conflicts)
 
97
        self.assertTrue('hello' in tree_conflicts[0].path)
 
98
        self.assertTrue('hello.sploo' in tree_conflicts[1].path)
 
99
        conflicts.restore('hello')
 
100
        conflicts.restore('hello.sploo')
 
101
        self.assertLength(0, tree.conflicts())
 
102
        self.assertFileEqual('hello world2', 'hello')
 
103
        self.assertFalse(os.path.lexists('hello.sploo'))
 
104
        self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
 
105
        self.assertRaises(errors.NotConflicted,
 
106
                          conflicts.restore, 'hello.sploo')
 
107
 
67
108
    def test_resolve_conflict_dir(self):
68
109
        tree = self.make_branch_and_tree('.')
69
110
        self.build_tree_contents([('hello', 'hello world4'),
169
210
        self.run_script(self.preamble)
170
211
 
171
212
 
 
213
class TestResolveTextConflicts(TestResolveConflicts):
 
214
    # TBC
 
215
    pass
 
216
 
 
217
 
172
218
def mirror_scenarios(base_scenarios):
173
219
    """Return a list of mirrored scenarios.
174
220
 
247
293
    _this = None
248
294
    _other = None
249
295
 
250
 
    scenarios = []
251
 
    """The scenario list for the conflict type defined by the class.
252
 
 
253
 
    Each scenario is of the form:
254
 
    (common, (left_name, left_dict), (right_name, right_dict))
255
 
 
256
 
    * common is a dict
257
 
 
258
 
    * left_name and right_name are the scenario names that will be combined
259
 
 
260
 
    * left_dict and right_dict are the attributes specific to each half of
261
 
      the scenario. They should include at least 'actions' and 'check' and
262
 
      will be available as '_this' and '_other' test instance attributes.
263
 
 
264
 
    Daughters classes are free to add their specific attributes as they see
265
 
    fit in any of the three dicts.
266
 
 
267
 
    This is a class method so that load_tests can find it.
268
 
 
269
 
    '_base_actions' in the common dict, 'actions' and 'check' in the left
270
 
    and right dicts use names that map to methods in the test classes. Some
271
 
    prefixes are added to these names to get the correspong methods (see
272
 
    _get_actions() and _get_check()). The motivation here is to avoid
273
 
    collisions in the class namespace.
274
 
    """
 
296
    @staticmethod
 
297
    def scenarios():
 
298
        """Return the scenario list for the conflict type defined by the class.
 
299
 
 
300
        Each scenario is of the form:
 
301
        (common, (left_name, left_dict), (right_name, right_dict))
 
302
 
 
303
        * common is a dict
 
304
 
 
305
        * left_name and right_name are the scenario names that will be combined
 
306
 
 
307
        * left_dict and right_dict are the attributes specific to each half of
 
308
          the scenario. They should include at least 'actions' and 'check' and
 
309
          will be available as '_this' and '_other' test instance attributes.
 
310
 
 
311
        Daughters classes are free to add their specific attributes as they see
 
312
        fit in any of the three dicts.
 
313
 
 
314
        This is a class method so that load_tests can find it.
 
315
 
 
316
        '_base_actions' in the common dict, 'actions' and 'check' in the left
 
317
        and right dicts use names that map to methods in the test classes. Some
 
318
        prefixes are added to these names to get the correspong methods (see
 
319
        _get_actions() and _get_check()). The motivation here is to avoid
 
320
        collisions in the class namespace.
 
321
        """
 
322
        # Only concrete classes return actual scenarios
 
323
        return []
275
324
 
276
325
    def setUp(self):
277
326
        super(TestParametrizedResolveConflicts, self).setUp()
339
388
        check_other()
340
389
 
341
390
 
342
 
class TestResolveTextConflicts(TestParametrizedResolveConflicts):
343
 
 
344
 
    _conflict_type = conflicts.TextConflict
345
 
 
346
 
    # Set by the scenarios
347
 
    # path and file-id for the file involved in the conflict
348
 
    _path = None
349
 
    _file_id = None
350
 
 
351
 
    scenarios = mirror_scenarios(
352
 
        [
353
 
            # File modified on both sides
354
 
            (dict(_base_actions='create_file',
355
 
                  _path='file', _file_id='file-id'),
356
 
             ('filed_modified_A',
357
 
              dict(actions='modify_file_A', check='file_has_content_A')),
358
 
             ('file_modified_B',
359
 
              dict(actions='modify_file_B', check='file_has_content_B')),),
360
 
            # File modified on both sides in dir
361
 
            (dict(_base_actions='create_file_in_dir',
362
 
                  _path='dir/file', _file_id='file-id'),
363
 
             ('filed_modified_A_in_dir',
364
 
              dict(actions='modify_file_A',
365
 
                   check='file_in_dir_has_content_A')),
366
 
             ('file_modified_B',
367
 
              dict(actions='modify_file_B',
368
 
                   check='file_in_dir_has_content_B')),),
369
 
            ])
370
 
 
371
 
    def do_create_file(self, path='file'):
372
 
        return [('add', (path, 'file-id', 'file', 'trunk content\n'))]
373
 
 
374
 
    def do_modify_file_A(self):
375
 
        return [('modify', ('file-id', 'trunk content\nfeature A\n'))]
376
 
 
377
 
    def do_modify_file_B(self):
378
 
        return [('modify', ('file-id', 'trunk content\nfeature B\n'))]
379
 
 
380
 
    def check_file_has_content_A(self, path='file'):
381
 
        self.assertFileEqual('trunk content\nfeature A\n',
382
 
                             osutils.pathjoin('branch', path))
383
 
 
384
 
    def check_file_has_content_B(self, path='file'):
385
 
        self.assertFileEqual('trunk content\nfeature B\n',
386
 
                             osutils.pathjoin('branch', path))
387
 
 
388
 
    def do_create_file_in_dir(self):
389
 
        return [('add', ('dir', 'dir-id', 'directory', '')),
390
 
            ] + self.do_create_file('dir/file')
391
 
 
392
 
    def check_file_in_dir_has_content_A(self):
393
 
        self.check_file_has_content_A('dir/file')
394
 
 
395
 
    def check_file_in_dir_has_content_B(self):
396
 
        self.check_file_has_content_B('dir/file')
397
 
 
398
 
    def _get_resolve_path_arg(self, wt, action):
399
 
        return self._path
400
 
 
401
 
    def assertTextConflict(self, wt, c):
402
 
        self.assertEqual(self._file_id, c.file_id)
403
 
        self.assertEqual(self._path, c.path)
404
 
    _assert_conflict = assertTextConflict
405
 
 
406
 
 
407
391
class TestResolveContentsConflict(TestParametrizedResolveConflicts):
408
392
 
409
 
    _conflict_type = conflicts.ContentsConflict
 
393
    _conflict_type = conflicts.ContentsConflict,
410
394
 
411
 
    # Set by the scenarios
 
395
    # Set by load_tests from scenarios()
412
396
    # path and file-id for the file involved in the conflict
413
397
    _path = None
414
398
    _file_id = None
415
399
 
416
 
    scenarios = mirror_scenarios(
417
 
        [
 
400
    @staticmethod
 
401
    def scenarios():
 
402
        base_scenarios = [
418
403
            # File modified/deleted
419
404
            (dict(_base_actions='create_file',
420
405
                  _path='file', _file_id='file-id'),
422
407
              dict(actions='modify_file', check='file_has_more_content')),
423
408
             ('file_deleted',
424
409
              dict(actions='delete_file', check='file_doesnt_exist')),),
425
 
            # File modified/deleted in dir
426
 
            (dict(_base_actions='create_file_in_dir',
427
 
                  _path='dir/file', _file_id='file-id'),
428
 
             ('file_modified_in_dir',
429
 
              dict(actions='modify_file_in_dir',
430
 
                   check='file_in_dir_has_more_content')),
431
 
             ('file_deleted_in_dir',
432
 
              dict(actions='delete_file',
433
 
                   check='file_in_dir_doesnt_exist')),),
434
 
            ])
 
410
            ]
 
411
        return mirror_scenarios(base_scenarios)
435
412
 
436
413
    def do_create_file(self):
437
414
        return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
446
423
        return [('unversion', 'file-id')]
447
424
 
448
425
    def check_file_doesnt_exist(self):
449
 
        self.assertPathDoesNotExist('branch/file')
450
 
 
451
 
    def do_create_file_in_dir(self):
452
 
        return [('add', ('dir', 'dir-id', 'directory', '')),
453
 
                ('add', ('dir/file', 'file-id', 'file', 'trunk content\n'))]
454
 
 
455
 
    def do_modify_file_in_dir(self):
456
 
        return [('modify', ('file-id', 'trunk content\nmore content\n'))]
457
 
 
458
 
    def check_file_in_dir_has_more_content(self):
459
 
        self.assertFileEqual('trunk content\nmore content\n', 'branch/dir/file')
460
 
 
461
 
    def check_file_in_dir_doesnt_exist(self):
462
 
        self.assertPathDoesNotExist('branch/dir/file')
 
426
        self.failIfExists('branch/file')
463
427
 
464
428
    def _get_resolve_path_arg(self, wt, action):
465
429
        return self._path
472
436
 
473
437
class TestResolvePathConflict(TestParametrizedResolveConflicts):
474
438
 
475
 
    _conflict_type = conflicts.PathConflict
 
439
    _conflict_type = conflicts.PathConflict,
476
440
 
477
441
    def do_nothing(self):
478
442
        return []
479
443
 
480
 
    # Each side dict additionally defines:
481
 
    # - path path involved (can be '<deleted>')
482
 
    # - file-id involved
483
 
    scenarios = mirror_scenarios(
484
 
        [
 
444
    @staticmethod
 
445
    def scenarios():
 
446
        # Each side dict additionally defines:
 
447
        # - path path involved (can be '<deleted>')
 
448
        # - file-id involved
 
449
        base_scenarios = [
485
450
            # File renamed/deleted
486
451
            (dict(_base_actions='create_file'),
487
452
             ('file_renamed',
492
457
                   # PathConflicts deletion handling requires a special
493
458
                   # hard-coded value
494
459
                   path='<deleted>', file_id='file-id')),),
495
 
            # File renamed/deleted in dir
496
 
            (dict(_base_actions='create_file_in_dir'),
497
 
             ('file_renamed_in_dir',
498
 
              dict(actions='rename_file_in_dir', check='file_in_dir_renamed',
499
 
                   path='dir/new-file', file_id='file-id')),
500
 
             ('file_deleted',
501
 
              dict(actions='delete_file', check='file_in_dir_doesnt_exist',
502
 
                   # PathConflicts deletion handling requires a special
503
 
                   # hard-coded value
504
 
                   path='<deleted>', file_id='file-id')),),
505
460
            # File renamed/renamed differently
506
461
            (dict(_base_actions='create_file'),
507
462
             ('file_renamed',
528
483
             ('dir_renamed2',
529
484
              dict(actions='rename_dir2', check='dir_renamed2',
530
485
                   path='new-dir2', file_id='dir-id')),),
531
 
            ])
 
486
        ]
 
487
        return mirror_scenarios(base_scenarios)
532
488
 
533
489
    def do_create_file(self):
534
490
        return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
540
496
        return [('rename', ('file', 'new-file'))]
541
497
 
542
498
    def check_file_renamed(self):
543
 
        self.assertPathDoesNotExist('branch/file')
544
 
        self.assertPathExists('branch/new-file')
 
499
        self.failIfExists('branch/file')
 
500
        self.failUnlessExists('branch/new-file')
545
501
 
546
502
    def do_rename_file2(self):
547
503
        return [('rename', ('file', 'new-file2'))]
548
504
 
549
505
    def check_file_renamed2(self):
550
 
        self.assertPathDoesNotExist('branch/file')
551
 
        self.assertPathExists('branch/new-file2')
 
506
        self.failIfExists('branch/file')
 
507
        self.failUnlessExists('branch/new-file2')
552
508
 
553
509
    def do_rename_dir(self):
554
510
        return [('rename', ('dir', 'new-dir'))]
555
511
 
556
512
    def check_dir_renamed(self):
557
 
        self.assertPathDoesNotExist('branch/dir')
558
 
        self.assertPathExists('branch/new-dir')
 
513
        self.failIfExists('branch/dir')
 
514
        self.failUnlessExists('branch/new-dir')
559
515
 
560
516
    def do_rename_dir2(self):
561
517
        return [('rename', ('dir', 'new-dir2'))]
562
518
 
563
519
    def check_dir_renamed2(self):
564
 
        self.assertPathDoesNotExist('branch/dir')
565
 
        self.assertPathExists('branch/new-dir2')
 
520
        self.failIfExists('branch/dir')
 
521
        self.failUnlessExists('branch/new-dir2')
566
522
 
567
523
    def do_delete_file(self):
568
524
        return [('unversion', 'file-id')]
569
525
 
570
526
    def check_file_doesnt_exist(self):
571
 
        self.assertPathDoesNotExist('branch/file')
 
527
        self.failIfExists('branch/file')
572
528
 
573
529
    def do_delete_dir(self):
574
530
        return [('unversion', 'dir-id')]
575
531
 
576
532
    def check_dir_doesnt_exist(self):
577
 
        self.assertPathDoesNotExist('branch/dir')
578
 
 
579
 
    def do_create_file_in_dir(self):
580
 
        return [('add', ('dir', 'dir-id', 'directory', '')),
581
 
                ('add', ('dir/file', 'file-id', 'file', 'trunk content\n'))]
582
 
 
583
 
    def do_rename_file_in_dir(self):
584
 
        return [('rename', ('dir/file', 'dir/new-file'))]
585
 
 
586
 
    def check_file_in_dir_renamed(self):
587
 
        self.assertPathDoesNotExist('branch/dir/file')
588
 
        self.assertPathExists('branch/dir/new-file')
589
 
 
590
 
    def check_file_in_dir_doesnt_exist(self):
591
 
        self.assertPathDoesNotExist('branch/dir/file')
 
533
        self.failIfExists('branch/dir')
592
534
 
593
535
    def _get_resolve_path_arg(self, wt, action):
594
536
        tpath = self._this['path']
626
568
 
627
569
class TestResolveDuplicateEntry(TestParametrizedResolveConflicts):
628
570
 
629
 
    _conflict_type = conflicts.DuplicateEntry
 
571
    _conflict_type = conflicts.DuplicateEntry,
630
572
 
631
 
    scenarios = mirror_scenarios(
632
 
        [
 
573
    @staticmethod
 
574
    def scenarios():
 
575
        # Each side dict additionally defines:
 
576
        # - path involved
 
577
        # - file-id involved
 
578
        base_scenarios = [
633
579
            # File created with different file-ids
634
580
            (dict(_base_actions='nothing'),
635
581
             ('filea_created',
638
584
             ('fileb_created',
639
585
              dict(actions='create_file_b', check='file_content_b',
640
586
                   path='file', file_id='file-b-id')),),
641
 
            ])
 
587
            ]
 
588
        return mirror_scenarios(base_scenarios)
642
589
 
643
590
    def do_nothing(self):
644
591
        return []
678
625
    # tests MissingParent resolution :-/
679
626
    preamble = """
680
627
$ bzr init trunk
681
 
...
682
628
$ cd trunk
683
629
$ mkdir dir
684
 
$ bzr add -q dir
685
 
$ bzr commit -m 'Create trunk' -q
 
630
$ bzr add dir
 
631
$ bzr commit -m 'Create trunk'
 
632
 
686
633
$ echo 'trunk content' >dir/file
687
 
$ bzr add -q dir/file
688
 
$ bzr commit -q -m 'Add dir/file in trunk'
689
 
$ bzr branch -q . -r 1 ../branch
 
634
$ bzr add dir/file
 
635
$ bzr commit -m 'Add dir/file in trunk'
 
636
 
 
637
$ bzr branch . -r 1 ../branch
690
638
$ cd ../branch
691
 
$ bzr rm dir -q
692
 
$ bzr commit -q -m 'Remove dir in branch'
 
639
$ bzr rm dir
 
640
$ bzr commit -m 'Remove dir in branch'
 
641
 
693
642
$ bzr merge ../trunk
694
643
2>+N  dir/
695
644
2>+N  dir/file
700
649
 
701
650
    def test_take_this(self):
702
651
        self.run_script("""
703
 
$ bzr rm -q dir  --force
 
652
$ bzr rm dir  --force
704
653
$ bzr resolve dir
705
 
2>2 conflict(s) resolved, 0 remaining
706
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
654
$ bzr commit --strict -m 'No more conflicts nor unknown files'
707
655
""")
708
656
 
709
657
    def test_take_other(self):
710
658
        self.run_script("""
711
659
$ bzr resolve dir
712
 
2>2 conflict(s) resolved, 0 remaining
713
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
660
$ bzr commit --strict -m 'No more conflicts nor unknown files'
714
661
""")
715
662
 
716
663
 
718
665
 
719
666
    preamble = """
720
667
$ bzr init trunk
721
 
...
722
668
$ cd trunk
723
669
$ mkdir dir
724
670
$ echo 'trunk content' >dir/file
725
 
$ bzr add -q
726
 
$ bzr commit -m 'Create trunk' -q
 
671
$ bzr add
 
672
$ bzr commit -m 'Create trunk'
 
673
 
727
674
$ echo 'trunk content' >dir/file2
728
 
$ bzr add -q dir/file2
729
 
$ bzr commit -q -m 'Add dir/file2 in branch'
730
 
$ bzr branch -q . -r 1 ../branch
 
675
$ bzr add dir/file2
 
676
$ bzr commit -m 'Add dir/file2 in branch'
 
677
 
 
678
$ bzr branch . -r 1 ../branch
731
679
$ cd ../branch
732
 
$ bzr rm -q dir/file --force
733
 
$ bzr rm -q dir
734
 
$ bzr commit -q -m 'Remove dir/file'
 
680
$ bzr rm dir/file --force
 
681
$ bzr rm dir
 
682
$ bzr commit -m 'Remove dir/file'
 
683
 
735
684
$ bzr merge ../trunk
736
685
2>+N  dir/
737
686
2>+N  dir/file2
743
692
    def test_keep_them_all(self):
744
693
        self.run_script("""
745
694
$ bzr resolve dir
746
 
2>2 conflict(s) resolved, 0 remaining
747
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
695
$ bzr commit --strict -m 'No more conflicts nor unknown files'
748
696
""")
749
697
 
750
698
    def test_adopt_child(self):
751
699
        self.run_script("""
752
 
$ bzr mv -q dir/file2 file2
753
 
$ bzr rm -q dir --force
 
700
$ bzr mv dir/file2 file2
 
701
$ bzr rm dir --force
754
702
$ bzr resolve dir
755
 
2>2 conflict(s) resolved, 0 remaining
756
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
703
$ bzr commit --strict -m 'No more conflicts nor unknown files'
757
704
""")
758
705
 
759
706
    def test_kill_them_all(self):
760
707
        self.run_script("""
761
 
$ bzr rm -q dir --force
 
708
$ bzr rm dir --force
762
709
$ bzr resolve dir
763
 
2>2 conflict(s) resolved, 0 remaining
764
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
710
$ bzr commit --strict -m 'No more conflicts nor unknown files'
765
711
""")
766
712
 
767
713
    def test_resolve_taking_this(self):
768
714
        self.run_script("""
769
715
$ bzr resolve --take-this dir
770
 
2>...
771
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
716
$ bzr commit --strict -m 'No more conflicts nor unknown files'
772
717
""")
773
718
 
774
719
    def test_resolve_taking_other(self):
775
720
        self.run_script("""
776
721
$ bzr resolve --take-other dir
777
 
2>...
778
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
722
$ bzr commit --strict -m 'No more conflicts nor unknown files'
779
723
""")
780
724
 
781
725
 
783
727
 
784
728
    preamble = """
785
729
$ bzr init trunk
786
 
...
787
730
$ cd trunk
788
731
$ mkdir dir
789
732
$ echo 'trunk content' >dir/file
790
 
$ bzr add -q
791
 
$ bzr commit -m 'Create trunk' -q
792
 
$ bzr rm -q dir/file --force
793
 
$ bzr rm -q dir --force
794
 
$ bzr commit -q -m 'Remove dir/file'
795
 
$ bzr branch -q . -r 1 ../branch
 
733
$ bzr add
 
734
$ bzr commit -m 'Create trunk'
 
735
 
 
736
$ bzr rm dir/file --force
 
737
$ bzr rm dir --force
 
738
$ bzr commit -m 'Remove dir/file'
 
739
 
 
740
$ bzr branch . -r 1 ../branch
796
741
$ cd ../branch
797
742
$ echo 'branch content' >dir/file2
798
 
$ bzr add -q dir/file2
799
 
$ bzr commit -q -m 'Add dir/file2 in branch'
 
743
$ bzr add dir/file2
 
744
$ bzr commit -m 'Add dir/file2 in branch'
 
745
 
800
746
$ bzr merge ../trunk
801
747
2>-D  dir/file
802
748
2>Conflict: can't delete dir because it is not empty.  Not deleting.
807
753
    def test_keep_them_all(self):
808
754
        self.run_script("""
809
755
$ bzr resolve dir
810
 
2>2 conflict(s) resolved, 0 remaining
811
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
756
$ bzr commit --strict -m 'No more conflicts nor unknown files'
812
757
""")
813
758
 
814
759
    def test_adopt_child(self):
815
760
        self.run_script("""
816
 
$ bzr mv -q dir/file2 file2
817
 
$ bzr rm -q dir --force
 
761
$ bzr mv dir/file2 file2
 
762
$ bzr rm dir --force
818
763
$ bzr resolve dir
819
 
2>2 conflict(s) resolved, 0 remaining
820
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
764
$ bzr commit --strict -m 'No more conflicts nor unknown files'
821
765
""")
822
766
 
823
767
    def test_kill_them_all(self):
824
768
        self.run_script("""
825
 
$ bzr rm -q dir --force
 
769
$ bzr rm dir --force
826
770
$ bzr resolve dir
827
 
2>2 conflict(s) resolved, 0 remaining
828
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
771
$ bzr commit --strict -m 'No more conflicts nor unknown files'
829
772
""")
830
773
 
831
774
    def test_resolve_taking_this(self):
832
775
        self.run_script("""
833
776
$ bzr resolve --take-this dir
834
 
2>2 conflict(s) resolved, 0 remaining
835
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
777
$ bzr commit --strict -m 'No more conflicts nor unknown files'
836
778
""")
837
779
 
838
780
    def test_resolve_taking_other(self):
839
781
        self.run_script("""
840
782
$ bzr resolve --take-other dir
841
 
2>deleted dir/file2
842
 
2>deleted dir
843
 
2>2 conflict(s) resolved, 0 remaining
844
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
783
$ bzr commit --strict -m 'No more conflicts nor unknown files'
845
784
""")
846
785
 
847
786
 
848
787
class TestResolveParentLoop(TestParametrizedResolveConflicts):
849
788
 
850
 
    _conflict_type = conflicts.ParentLoop
 
789
    _conflict_type = conflicts.ParentLoop,
851
790
 
852
791
    _this_args = None
853
792
    _other_args = None
854
793
 
855
 
    # Each side dict additionally defines:
856
 
    # - dir_id: the directory being moved
857
 
    # - target_id: The target directory
858
 
    # - xfail: whether the test is expected to fail if the action is
859
 
    #   involved as 'other'
860
 
    scenarios = mirror_scenarios(
861
 
        [
 
794
    @staticmethod
 
795
    def scenarios():
 
796
        # Each side dict additionally defines:
 
797
        # - dir_id: the directory being moved
 
798
        # - target_id: The target directory
 
799
        # - xfail: whether the test is expected to fail if the action is
 
800
        #     involved as 'other'
 
801
        base_scenarios = [
862
802
            # Dirs moved into each other
863
803
            (dict(_base_actions='create_dir1_dir2'),
864
804
             ('dir1_into_dir2',
875
815
             ('dir3_into_dir2',
876
816
              dict(actions='move_dir3_into_dir2', check='dir3_4_moved',
877
817
                   dir_id='dir3-id', target_id='dir2-id', xfail=True))),
878
 
            ])
 
818
            ]
 
819
        return mirror_scenarios(base_scenarios)
879
820
 
880
821
    def do_create_dir1_dir2(self):
881
822
        return [('add', ('dir1', 'dir1-id', 'directory', '')),
885
826
        return [('rename', ('dir1', 'dir2/dir1'))]
886
827
 
887
828
    def check_dir1_moved(self):
888
 
        self.assertPathDoesNotExist('branch/dir1')
889
 
        self.assertPathExists('branch/dir2/dir1')
 
829
        self.failIfExists('branch/dir1')
 
830
        self.failUnlessExists('branch/dir2/dir1')
890
831
 
891
832
    def do_move_dir2_into_dir1(self):
892
833
        return [('rename', ('dir2', 'dir1/dir2'))]
893
834
 
894
835
    def check_dir2_moved(self):
895
 
        self.assertPathDoesNotExist('branch/dir2')
896
 
        self.assertPathExists('branch/dir1/dir2')
 
836
        self.failIfExists('branch/dir2')
 
837
        self.failUnlessExists('branch/dir1/dir2')
897
838
 
898
839
    def do_create_dir1_4(self):
899
840
        return [('add', ('dir1', 'dir1-id', 'directory', '')),
905
846
        return [('rename', ('dir1', 'dir3/dir4/dir1'))]
906
847
 
907
848
    def check_dir1_2_moved(self):
908
 
        self.assertPathDoesNotExist('branch/dir1')
909
 
        self.assertPathExists('branch/dir3/dir4/dir1')
910
 
        self.assertPathExists('branch/dir3/dir4/dir1/dir2')
 
849
        self.failIfExists('branch/dir1')
 
850
        self.failUnlessExists('branch/dir3/dir4/dir1')
 
851
        self.failUnlessExists('branch/dir3/dir4/dir1/dir2')
911
852
 
912
853
    def do_move_dir3_into_dir2(self):
913
854
        return [('rename', ('dir3', 'dir1/dir2/dir3'))]
914
855
 
915
856
    def check_dir3_4_moved(self):
916
 
        self.assertPathDoesNotExist('branch/dir3')
917
 
        self.assertPathExists('branch/dir1/dir2/dir3')
918
 
        self.assertPathExists('branch/dir1/dir2/dir3/dir4')
 
857
        self.failIfExists('branch/dir3')
 
858
        self.failUnlessExists('branch/dir1/dir2/dir3')
 
859
        self.failUnlessExists('branch/dir1/dir2/dir3/dir4')
919
860
 
920
861
    def _get_resolve_path_arg(self, wt, action):
921
862
        # ParentLoop says: moving <conflict_path> into <path>. Cancelled move.
941
882
 
942
883
    preamble = """
943
884
$ bzr init trunk
944
 
...
945
885
$ cd trunk
946
886
$ bzr mkdir foo
947
 
...
948
 
$ bzr commit -m 'Create trunk' -q
 
887
$ bzr commit -m 'Create trunk'
949
888
$ echo "Boing" >foo/bar
950
 
$ bzr add -q foo/bar
951
 
$ bzr commit -q -m 'Add foo/bar'
952
 
$ bzr branch -q . -r 1 ../branch
 
889
$ bzr add foo/bar
 
890
$ bzr commit -m 'Add foo/bar'
 
891
 
 
892
$ bzr branch . -r 1 ../branch
953
893
$ cd ../branch
954
894
$ rm -r foo
955
895
$ echo "Boo!" >foo
956
 
$ bzr commit -q -m 'foo is now a file'
 
896
$ bzr commit -m 'foo is now a file'
 
897
 
957
898
$ bzr merge ../trunk
958
899
2>+N  foo.new/bar
959
900
2>RK  foo => foo.new/
965
906
 
966
907
    def test_take_this(self):
967
908
        self.run_script("""
968
 
$ bzr rm -q foo.new --force
 
909
$ bzr rm foo.new --force
969
910
# FIXME: Isn't it weird that foo is now unkown even if foo.new has been put
970
911
# aside ? -- vila 090916
971
 
$ bzr add -q foo
 
912
$ bzr add foo
972
913
$ bzr resolve foo.new
973
 
2>1 conflict(s) resolved, 0 remaining
974
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
914
$ bzr commit --strict -m 'No more conflicts nor unknown files'
975
915
""")
976
916
 
977
917
    def test_take_other(self):
978
918
        self.run_script("""
979
 
$ bzr rm -q foo --force
980
 
$ bzr mv -q foo.new foo
 
919
$ bzr rm foo --force
 
920
$ bzr mv foo.new foo
981
921
$ bzr resolve foo
982
 
2>1 conflict(s) resolved, 0 remaining
983
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
922
$ bzr commit --strict -m 'No more conflicts nor unknown files'
984
923
""")
985
924
 
986
925
    def test_resolve_taking_this(self):
987
926
        self.run_script("""
988
927
$ bzr resolve --take-this foo.new
989
 
2>...
990
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
928
$ bzr commit --strict -m 'No more conflicts nor unknown files'
991
929
""")
992
930
 
993
931
    def test_resolve_taking_other(self):
994
932
        self.run_script("""
995
933
$ bzr resolve --take-other foo.new
996
 
2>...
997
 
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
 
934
$ bzr commit --strict -m 'No more conflicts nor unknown files'
998
935
""")
999
936
 
1000
937
 
1006
943
        # conflict.
1007
944
        self.run_script("""
1008
945
$ bzr init trunk
1009
 
...
1010
946
$ cd trunk
1011
947
$ bzr mkdir foo
1012
 
...
1013
 
$ bzr commit -m 'Create trunk' -q
 
948
$ bzr commit -m 'Create trunk'
1014
949
$ rm -r foo
1015
950
$ echo "Boo!" >foo
1016
 
$ bzr commit -m 'foo is now a file' -q
1017
 
$ bzr branch -q . -r 1 ../branch -q
 
951
$ bzr commit -m 'foo is now a file'
 
952
 
 
953
$ bzr branch . -r 1 ../branch
1018
954
$ cd ../branch
1019
955
$ echo "Boing" >foo/bar
1020
 
$ bzr add -q foo/bar -q
1021
 
$ bzr commit -m 'Add foo/bar' -q
 
956
$ bzr add foo/bar
 
957
$ bzr commit -m 'Add foo/bar'
 
958
 
1022
959
$ bzr merge ../trunk
1023
960
2>bzr: ERROR: Tree transform is malformed [('unversioned executability', 'new-1')]
1024
961
""")