/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_merger.py

  • Committer: John Arbash Meinel
  • Date: 2009-12-22 16:28:47 UTC
  • mto: This revision was merged to the branch mainline in revision 4922.
  • Revision ID: john@arbash-meinel.com-20091222162847-tvnsc69to4l4uf5r
Implement a permute_for_extension helper.

Use it for all of the 'simple' extension permutations.
It basically permutes all tests in the current module, by setting TestCase.module.
Which works well for most of our extension tests. Some had more advanced
handling of permutations (extra permutations, custom vars, etc.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2009 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
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
 
16
 
 
17
"""Implementation tests for bzrlib.merge.Merger."""
 
18
 
 
19
import os
 
20
 
 
21
from bzrlib import (
 
22
    errors,
 
23
    merge as _mod_merge,
 
24
    option,
 
25
    progress,
 
26
    )
 
27
from bzrlib.tests import (
 
28
    multiply_tests,
 
29
    TestCaseWithTransport,
 
30
    )
 
31
from bzrlib.transform import TreeTransform
 
32
 
 
33
 
 
34
 
 
35
def load_tests(standard_tests, module, loader):
 
36
    """Multiply tests for tranport implementations."""
 
37
    result = loader.suiteClass()
 
38
    scenarios = [
 
39
        (name, {'merge_type': merger})
 
40
        for name, merger in option._merge_type_registry.items()]
 
41
    return multiply_tests(standard_tests, scenarios, result)
 
42
 
 
43
 
 
44
class TestMergeImplementation(TestCaseWithTransport):
 
45
 
 
46
    def do_merge(self, target_tree, source_tree, **kwargs):
 
47
        merger = _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
 
48
            target_tree, source_tree.last_revision(),
 
49
            other_branch=source_tree.branch)
 
50
        merger.merge_type=self.merge_type
 
51
        for name, value in kwargs.items():
 
52
            setattr(merger, name, value)
 
53
        merger.do_merge()
 
54
 
 
55
    def test_merge_specific_file(self):
 
56
        this_tree = self.make_branch_and_tree('this')
 
57
        this_tree.lock_write()
 
58
        self.addCleanup(this_tree.unlock)
 
59
        self.build_tree_contents([
 
60
            ('this/file1', 'a\nb\n'),
 
61
            ('this/file2', 'a\nb\n')
 
62
        ])
 
63
        this_tree.add(['file1', 'file2'])
 
64
        this_tree.commit('Added files')
 
65
        other_tree = this_tree.bzrdir.sprout('other').open_workingtree()
 
66
        self.build_tree_contents([
 
67
            ('other/file1', 'a\nb\nc\n'),
 
68
            ('other/file2', 'a\nb\nc\n')
 
69
        ])
 
70
        other_tree.commit('modified both')
 
71
        self.build_tree_contents([
 
72
            ('this/file1', 'd\na\nb\n'),
 
73
            ('this/file2', 'd\na\nb\n')
 
74
        ])
 
75
        this_tree.commit('modified both')
 
76
        self.do_merge(this_tree, other_tree, interesting_files=['file1'])
 
77
        self.assertFileEqual('d\na\nb\nc\n', 'this/file1')
 
78
        self.assertFileEqual('d\na\nb\n', 'this/file2')
 
79
 
 
80
    def test_merge_move_and_change(self):
 
81
        this_tree = self.make_branch_and_tree('this')
 
82
        this_tree.lock_write()
 
83
        self.addCleanup(this_tree.unlock)
 
84
        self.build_tree_contents([
 
85
            ('this/file1', 'line 1\nline 2\nline 3\nline 4\n'),
 
86
        ])
 
87
        this_tree.add('file1',)
 
88
        this_tree.commit('Added file')
 
89
        other_tree = this_tree.bzrdir.sprout('other').open_workingtree()
 
90
        self.build_tree_contents([
 
91
            ('other/file1', 'line 1\nline 2 to 2.1\nline 3\nline 4\n'),
 
92
        ])
 
93
        other_tree.commit('Changed 2 to 2.1')
 
94
        self.build_tree_contents([
 
95
            ('this/file1', 'line 1\nline 3\nline 2\nline 4\n'),
 
96
        ])
 
97
        this_tree.commit('Swapped 2 & 3')
 
98
        self.do_merge(this_tree, other_tree)
 
99
        if self.merge_type is _mod_merge.LCAMerger:
 
100
            self.expectFailure(
 
101
                "lca merge doesn't conflict for move and change",
 
102
                self.assertFileEqual,
 
103
                'line 1\n'
 
104
                '<<<<<<< TREE\n'
 
105
                'line 3\n'
 
106
                'line 2\n'
 
107
                '=======\n'
 
108
                'line 2 to 2.1\n'
 
109
                'line 3\n'
 
110
                '>>>>>>> MERGE-SOURCE\n'
 
111
                'line 4\n', 'this/file1')
 
112
        else:
 
113
            self.assertFileEqual('line 1\n'
 
114
                '<<<<<<< TREE\n'
 
115
                'line 3\n'
 
116
                'line 2\n'
 
117
                '=======\n'
 
118
                'line 2 to 2.1\n'
 
119
                'line 3\n'
 
120
                '>>>>>>> MERGE-SOURCE\n'
 
121
                'line 4\n', 'this/file1')
 
122
 
 
123
    def test_modify_conflicts_with_delete(self):
 
124
        # If one side deletes a line, and the other modifies that line, then
 
125
        # the modification should be considered a conflict
 
126
        builder = self.make_branch_builder('test')
 
127
        builder.start_series()
 
128
        builder.build_snapshot('BASE-id', None,
 
129
            [('add', ('', None, 'directory', None)),
 
130
             ('add', ('foo', 'foo-id', 'file', 'a\nb\nc\nd\ne\n')),
 
131
            ])
 
132
        # Delete 'b\n'
 
133
        builder.build_snapshot('OTHER-id', ['BASE-id'],
 
134
            [('modify', ('foo-id', 'a\nc\nd\ne\n'))])
 
135
        # Modify 'b\n', add 'X\n'
 
136
        builder.build_snapshot('THIS-id', ['BASE-id'],
 
137
            [('modify', ('foo-id', 'a\nb2\nc\nd\nX\ne\n'))])
 
138
        builder.finish_series()
 
139
        branch = builder.get_branch()
 
140
        this_tree = branch.bzrdir.create_workingtree()
 
141
        this_tree.lock_write()
 
142
        self.addCleanup(this_tree.unlock)
 
143
        other_tree = this_tree.bzrdir.sprout('other', 'OTHER-id').open_workingtree()
 
144
        self.do_merge(this_tree, other_tree)
 
145
        if self.merge_type is _mod_merge.LCAMerger:
 
146
            self.expectFailure("lca merge doesn't track deleted lines",
 
147
                self.assertFileEqual,
 
148
                    'a\n'
 
149
                    '<<<<<<< TREE\n'
 
150
                    'b2\n'
 
151
                    '=======\n'
 
152
                    '>>>>>>> MERGE-SOURCE\n'
 
153
                    'c\n'
 
154
                    'd\n'
 
155
                    'X\n'
 
156
                    'e\n', 'test/foo')
 
157
        else:
 
158
            self.assertFileEqual(
 
159
                'a\n'
 
160
                '<<<<<<< TREE\n'
 
161
                'b2\n'
 
162
                '=======\n'
 
163
                '>>>>>>> MERGE-SOURCE\n'
 
164
                'c\n'
 
165
                'd\n'
 
166
                'X\n'
 
167
                'e\n', 'test/foo')
 
168
 
 
169
    def get_limbodir_deletiondir(self, wt):
 
170
        transform = TreeTransform(wt)
 
171
        limbodir = transform._limbodir
 
172
        deletiondir = transform._deletiondir
 
173
        transform.finalize()
 
174
        return (limbodir, deletiondir)
 
175
    
 
176
    def test_merge_with_existing_limbo(self):
 
177
        wt = self.make_branch_and_tree('this')
 
178
        (limbodir, deletiondir) =  self.get_limbodir_deletiondir(wt)
 
179
        os.mkdir(limbodir)
 
180
        self.assertRaises(errors.ExistingLimbo, self.do_merge, wt, wt)
 
181
        self.assertRaises(errors.LockError, wt.unlock)
 
182
 
 
183
    def test_merge_with_pending_deletion(self):
 
184
        wt = self.make_branch_and_tree('this')
 
185
        (limbodir, deletiondir) =  self.get_limbodir_deletiondir(wt)
 
186
        os.mkdir(deletiondir)
 
187
        self.assertRaises(errors.ExistingPendingDeletion, self.do_merge, wt, wt)
 
188
        self.assertRaises(errors.LockError, wt.unlock)
 
189
 
 
190
 
 
191