~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_conflicts.py

Add a scenario and activate the compatibility tests.

* bzrlib/tests/test_conflicts.py:
(TestParametrizedResolveConflicts.mirror_scenarios): The common
parameters needs to be specific for each scenario (but still
common for the mirrors).
(TestParametrizedResolveConflicts.assertConflict): Provides the
working tree as a parameter.
(TestParametrizedResolveConflicts.do_rename_file,
TestParametrizedResolveConflicts.check_file_renamed): More
helpers.
(TestResolvePathConflict.scenarios): Add one more scenario.
(TestResolvePathConflict.do_delete_file)
(TestResolvePathConflict.scenarios): Oops, really activate the
compatibility tests.
(TestResolvePathConflict.assertPathConflict): Inject the conflict
object as it was built before the fix.

Show diffs side-by-side

added added

removed removed

Lines of Context:
237
237
    _other_id = None
238
238
 
239
239
    @classmethod
240
 
    def mirror_scenarios(klass, common_params, base_scenarios):
 
240
    def mirror_scenarios(klass, base_scenarios):
241
241
        scenarios = []
242
242
        def adapt(d, side):
243
243
            """Modify dict to apply to the given side.
252
252
            return t
253
253
        # Each base scenario is duplicated switching the roles of 'this' and
254
254
        # 'other'
255
 
        left = [l for l,r in base_scenarios]
256
 
        right = [r for l,r in base_scenarios]
257
 
        for (lname, ldict), (rname, rdict) in zip(left, right):
258
 
            scenarios.extend(tests.multiply_scenarios(
259
 
                    [(lname, adapt(ldict, 'this'))],
260
 
                    [(rname, adapt(rdict, 'other'))]))
261
 
            scenarios.extend(tests.multiply_scenarios(
 
255
        left = [l for l, r, c in base_scenarios]
 
256
        right = [r for l, r, c in base_scenarios]
 
257
        common = [c for l, r, c in base_scenarios]
 
258
        for (lname, ldict), (rname, rdict), common in zip(left, right, common):
 
259
            a = tests.multiply_scenarios([(lname, adapt(ldict, 'this'))],
 
260
                                         [(rname, adapt(rdict, 'other'))])
 
261
            b = tests.multiply_scenarios(
262
262
                    [(rname, adapt(rdict, 'this'))],
263
 
                    [(lname, adapt(ldict, 'other'))]))
264
 
        # Inject the common parameters in all scenarios
265
 
        for name, d in scenarios:
266
 
            d.update(common_params)
 
263
                    [(lname, adapt(ldict, 'other'))])
 
264
            # Inject the common parameters in all scenarios
 
265
            for name, d in a + b:
 
266
                d.update(common)
 
267
            scenarios.extend(a + b)
267
268
        return scenarios
268
269
 
269
270
    @classmethod
306
307
        self.assertLength(1, confs)
307
308
        c = confs[0]
308
309
        self.assertIsInstance(c, self._conflict_type)
309
 
        self._assert_conflict(c)
 
310
        self._assert_conflict(wt, c)
310
311
 
311
312
    def check_resolved(self, wt, path, action):
312
313
        conflicts.resolve(wt, [path], action=action)
334
335
    def check_file_doesnt_exist(self):
335
336
        self.failIfExists('branch/file')
336
337
 
 
338
    def do_rename_file(self):
 
339
        return ('new-file', 'file-id', [('rename', ('file', 'new-file'))])
 
340
 
 
341
    def check_file_renamed(self):
 
342
        self.failIfExists('branch/file')
 
343
        self.failUnlessExists('branch/new-file')
 
344
 
337
345
    def do_rename_dir(self):
338
346
        return ('new-dir', 'dir-id', [('rename', ('dir', 'new-dir'))])
339
347
 
387
395
            (('file_modified', dict(actions='modify_file',
388
396
                                   check='file_has_more_content')),
389
397
             ('file_deleted', dict(actions='delete_file',
390
 
                                   check='file_doesnt_exist'))),
 
398
                                   check='file_doesnt_exist')),
 
399
             dict(_actions_base='create_file',
 
400
                  _item_path='file', item_id='file-id',)),
391
401
            ]
392
 
        return klass.mirror_scenarios(common, base_scenarios)
 
402
        return klass.mirror_scenarios(base_scenarios)
393
403
 
394
 
    def assertContentsConflict(self, c):
 
404
    def assertContentsConflict(self, wt, c):
395
405
        self.assertEqual(self._other_id, c.file_id)
396
406
        self.assertEqual(self._other_path, c.path)
397
407
    _assert_conflict = assertContentsConflict
404
414
 
405
415
    @classmethod
406
416
    def scenarios(klass):
407
 
        common = dict(_actions_base='create_dir',
408
 
                      _item_path='new-dir', _item_id='dir-id',)
 
417
        for_dirs = dict(_actions_base='create_dir',
 
418
                        _item_path='new-dir', _item_id='dir-id',)
409
419
        base_scenarios = [
410
 
        (('dir_renamed', dict(actions='rename_dir', check='dir_renamed')),
411
 
         ('dir_deleted', dict(actions='delete_dir', check='dir_doesnt_exist'))),
412
 
        (('dir_renamed', dict(actions='rename_dir', check='dir_renamed')),
413
 
         ('dir_renamed2', dict(actions='rename_dir2', check='dir_renamed2'))),
414
 
            ]
415
 
        return klass.mirror_scenarios(common, base_scenarios)
416
 
 
417
 
    def assertPathConflict(self, c):
 
420
            (('file_renamed',
 
421
              dict(actions='rename_file', check='file_renamed')),
 
422
             ('file_deleted',
 
423
              dict(actions='delete_file', check='file_doesnt_exist')),
 
424
             dict(_actions_base='create_file',
 
425
                  _item_path='new-file', _item_id='file-id',)),
 
426
            (('dir_renamed',
 
427
              dict(actions='rename_dir', check='dir_renamed')),
 
428
             ('dir_deleted',
 
429
              dict(actions='delete_dir', check='dir_doesnt_exist')),
 
430
             for_dirs),
 
431
            (('dir_renamed',
 
432
              dict(actions='rename_dir', check='dir_renamed')),
 
433
             ('dir_renamed2',
 
434
              dict(actions='rename_dir2', check='dir_renamed2')),
 
435
             for_dirs),
 
436
        ]
 
437
        return klass.mirror_scenarios(base_scenarios)
 
438
 
 
439
    def do_delete_file(self):
 
440
        sup = super(TestResolvePathConflict, self).do_delete_file()
 
441
        # PathConflicts handle deletion differently and requires a special
 
442
        # hard-coded value
 
443
        return ('<deleted>',) + sup[1:]
 
444
 
 
445
    def assertPathConflict(self, wt, c):
418
446
        self.assertEqual(self._item_id, c.file_id)
419
447
        self.assertEqual(self._this_path, c.path)
420
448
        self.assertEqual(self._other_path, c.conflict_path)
421
449
    _assert_conflict = assertPathConflict
422
450
 
423
451
 
424
 
class TestResolvePathConflictBefore531967(TestParametrizedResolveConflicts):
 
452
class TestResolvePathConflictBefore531967(TestResolvePathConflict):
425
453
    """Same as TestResolvePathConflict but a specific conflict object.
426
454
    """
427
455
 
428
 
    # FIXME: Now that bug #531697 is fixed, we need to inject a conflict object
429
 
    # as it existed before the fix.
430
 
 
431
456
    def assertPathConflict(self, c):
432
 
        # bug #531967 is about file_id not being set in some cases
433
 
        self.assertIs(None, c.file_id)
434
 
        # Whatever this and other are saying, the same paths are used
435
 
        self.assertEqual('<deleted>', c.path)
436
 
        self.assertEqual(self._item_path, c.conflict_path)
 
457
        # We create a conflict object as it was created before the fix and
 
458
        # inject it into the working tree, the test will exercise the
 
459
        # compatibility code.
 
460
        old_c = conflicts.PathConflict('<deleted>', self._item_path,
 
461
                                       file_id=None)
 
462
        wt.set_conflicts(conflicts.ConflictList([c]))
437
463
 
438
464
 
439
465
class TestResolveDuplicateEntry(TestResolveConflicts):