~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/testmerge3.py

  • Committer: Martin Pool
  • Date: 2005-07-05 13:02:38 UTC
  • Revision ID: mbp@sourcefrog.net-20050705130238-485f0343122f8ce6
doc

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2004, 2005 by 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
 
 
18
from bzrlib.selftest import InTempDir, TestBase
 
19
from bzrlib.merge3 import Merge3
 
20
 
 
21
 
 
22
 
 
23
 
 
24
 
 
25
class NoChanges(TestBase):
 
26
    """No conflicts because nothing changed"""
 
27
    def runTest(self):
 
28
        m3 = Merge3(['aaa', 'bbb'],
 
29
                    ['aaa', 'bbb'],
 
30
                    ['aaa', 'bbb'])
 
31
 
 
32
        self.assertEquals(m3.find_unconflicted(),
 
33
                          [(0, 2)])
 
34
 
 
35
        self.assertEquals(list(m3.find_sync_regions()),
 
36
                          [(0, 2,
 
37
                            0, 2,
 
38
                            0, 2),
 
39
                           (2,2, 2,2, 2,2)])
 
40
 
 
41
        self.assertEquals(list(m3.merge_regions()),
 
42
                          [('unchanged', 0, 2)])
 
43
 
 
44
        self.assertEquals(list(m3.merge_groups()),
 
45
                          [('unchanged', ['aaa', 'bbb'])])
 
46
 
 
47
 
 
48
class FrontInsert(TestBase):
 
49
    def runTest(self):
 
50
        m3 = Merge3(['zz'],
 
51
                    ['aaa', 'bbb', 'zz'],
 
52
                    ['zz'])
 
53
 
 
54
        # todo: should use a sentinal at end as from get_matching_blocks
 
55
        # to match without zz
 
56
        self.assertEquals(list(m3.find_sync_regions()),
 
57
                          [(0,1, 2,3, 0,1),
 
58
                           (1,1, 3,3, 1,1),])
 
59
 
 
60
        self.assertEquals(list(m3.merge_regions()),
 
61
                          [('a', 0, 2),
 
62
                           ('unchanged', 0, 1)])
 
63
 
 
64
        self.assertEquals(list(m3.merge_groups()),
 
65
                          [('a', ['aaa', 'bbb']),
 
66
                           ('unchanged', ['zz'])])
 
67
        
 
68
    
 
69
 
 
70
class NullInsert(TestBase):
 
71
    def runTest(self):
 
72
        m3 = Merge3([],
 
73
                    ['aaa', 'bbb'],
 
74
                    [])
 
75
 
 
76
        # todo: should use a sentinal at end as from get_matching_blocks
 
77
        # to match without zz
 
78
        self.assertEquals(list(m3.find_sync_regions()),
 
79
                          [(0,0, 2,2, 0,0)])
 
80
 
 
81
        self.assertEquals(list(m3.merge_regions()),
 
82
                          [('a', 0, 2)])
 
83
 
 
84
        self.assertEquals(list(m3.merge_lines()),
 
85
                          ['aaa', 'bbb'])
 
86
        
 
87
    
 
88
 
 
89
class NoConflicts(TestBase):
 
90
    """No conflicts because only one side changed"""
 
91
    def runTest(self):
 
92
        m3 = Merge3(['aaa', 'bbb'],
 
93
                    ['aaa', '111', 'bbb'],
 
94
                    ['aaa', 'bbb'])
 
95
 
 
96
        self.assertEquals(m3.find_unconflicted(),
 
97
                          [(0, 1), (1, 2)])
 
98
 
 
99
        self.assertEquals(list(m3.find_sync_regions()),
 
100
                          [(0,1, 0,1, 0,1),
 
101
                           (1,2, 2,3, 1,2),
 
102
                           (2,2, 3,3, 2,2),])
 
103
 
 
104
        self.assertEquals(list(m3.merge_regions()),
 
105
                          [('unchanged', 0, 1),
 
106
                           ('a', 1, 2),
 
107
                           ('unchanged', 1, 2),])
 
108
 
 
109
 
 
110
 
 
111
class InsertAgreement(TestBase):
 
112
    def runTest(self):
 
113
        m3 = Merge3(['aaa\n', 'bbb\n'],
 
114
                    ['aaa\n', '222\n', 'bbb\n'],
 
115
                    ['aaa\n', '222\n', 'bbb\n'])
 
116
 
 
117
        self.assertEquals(''.join(m3.merge_lines()),
 
118
                          'aaa\n222\nbbb\n')
 
119
 
 
120
 
 
121
 
 
122
class InsertClash(TestBase):
 
123
    """Both try to insert lines in the same place."""
 
124
    def runTest(self):
 
125
        m3 = Merge3(['aaa\n', 'bbb\n'],
 
126
                    ['aaa\n', '111\n', 'bbb\n'],
 
127
                    ['aaa\n', '222\n', 'bbb\n'])
 
128
 
 
129
        self.assertEquals(m3.find_unconflicted(),
 
130
                          [(0, 1), (1, 2)])
 
131
 
 
132
        self.assertEquals(list(m3.find_sync_regions()),
 
133
                          [(0,1, 0,1, 0,1),
 
134
                           (1,2, 2,3, 2,3),
 
135
                           (2,2, 3,3, 3,3),])
 
136
 
 
137
        self.assertEquals(list(m3.merge_regions()),
 
138
                          [('unchanged', 0,1),
 
139
                           ('conflict', 1,1, 1,2, 1,2),
 
140
                           ('unchanged', 1,2)])
 
141
 
 
142
        self.assertEquals(list(m3.merge_groups()),
 
143
                          [('unchanged', ['aaa\n']),
 
144
                           ('conflict', [], ['111\n'], ['222\n']),
 
145
                           ('unchanged', ['bbb\n']),
 
146
                           ])
 
147
 
 
148
        ml = m3.merge_lines(name_a='a',
 
149
                            name_b='b',
 
150
                            start_marker='<<',
 
151
                            mid_marker='--',
 
152
                            end_marker='>>')
 
153
        self.assertEquals(''.join(ml),
 
154
'''aaa
 
155
<< a
 
156
111
 
157
--
 
158
222
 
159
>> b
 
160
bbb
 
161
''')
 
162
 
 
163
 
 
164
 
 
165
class ReplaceClash(TestBase):
 
166
    """Both try to insert lines in the same place."""
 
167
    def runTest(self):
 
168
        m3 = Merge3(['aaa', '000', 'bbb'],
 
169
                    ['aaa', '111', 'bbb'],
 
170
                    ['aaa', '222', 'bbb'])
 
171
 
 
172
        self.assertEquals(m3.find_unconflicted(),
 
173
                          [(0, 1), (2, 3)])
 
174
 
 
175
        self.assertEquals(list(m3.find_sync_regions()),
 
176
                          [(0,1, 0,1, 0,1),
 
177
                           (2,3, 2,3, 2,3),
 
178
                           (3,3, 3,3, 3,3),])
 
179
 
 
180
 
 
181
 
 
182
class ReplaceMulti(TestBase):
 
183
    """Replacement with regions of different size."""
 
184
    def runTest(self):
 
185
        m3 = Merge3(['aaa', '000', '000', 'bbb'],
 
186
                    ['aaa', '111', '111', '111', 'bbb'],
 
187
                    ['aaa', '222', '222', '222', '222', 'bbb'])
 
188
 
 
189
        self.assertEquals(m3.find_unconflicted(),
 
190
                          [(0, 1), (3, 4)])
 
191
 
 
192
 
 
193
        self.assertEquals(list(m3.find_sync_regions()),
 
194
                          [(0,1, 0,1, 0,1),
 
195
                           (3,4, 4,5, 5,6),
 
196
                           (4,4, 5,5, 6,6),])
 
197
 
 
198
        
 
199
        
 
200
 
 
201
 
 
202
 
 
203
 
 
204
def split_lines(t):
 
205
    from cStringIO import StringIO
 
206
    return StringIO(t).readlines()
 
207
 
 
208
 
 
209
 
 
210
############################################################
 
211
# test case from the gnu diffutils manual
 
212
 
 
213
# common base
 
214
TZU = split_lines("""     The Nameless is the origin of Heaven and Earth;
 
215
     The named is the mother of all things.
 
216
     
 
217
     Therefore let there always be non-being,
 
218
       so we may see their subtlety,
 
219
     And let there always be being,
 
220
       so we may see their outcome.
 
221
     The two are the same,
 
222
     But after they are produced,
 
223
       they have different names.
 
224
     They both may be called deep and profound.
 
225
     Deeper and more profound,
 
226
     The door of all subtleties!
 
227
""")
 
228
 
 
229
LAO = split_lines("""     The Way that can be told of is not the eternal Way;
 
230
     The name that can be named is not the eternal name.
 
231
     The Nameless is the origin of Heaven and Earth;
 
232
     The Named is the mother of all things.
 
233
     Therefore let there always be non-being,
 
234
       so we may see their subtlety,
 
235
     And let there always be being,
 
236
       so we may see their outcome.
 
237
     The two are the same,
 
238
     But after they are produced,
 
239
       they have different names.
 
240
""")
 
241
 
 
242
 
 
243
TAO = split_lines("""     The Way that can be told of is not the eternal Way;
 
244
     The name that can be named is not the eternal name.
 
245
     The Nameless is the origin of Heaven and Earth;
 
246
     The named is the mother of all things.
 
247
     
 
248
     Therefore let there always be non-being,
 
249
       so we may see their subtlety,
 
250
     And let there always be being,
 
251
       so we may see their result.
 
252
     The two are the same,
 
253
     But after they are produced,
 
254
       they have different names.
 
255
     
 
256
       -- The Way of Lao-Tzu, tr. Wing-tsit Chan
 
257
 
 
258
""")
 
259
 
 
260
MERGED_RESULT = split_lines("""     The Way that can be told of is not the eternal Way;
 
261
     The name that can be named is not the eternal name.
 
262
     The Nameless is the origin of Heaven and Earth;
 
263
     The Named is the mother of all things.
 
264
     Therefore let there always be non-being,
 
265
       so we may see their subtlety,
 
266
     And let there always be being,
 
267
       so we may see their result.
 
268
     The two are the same,
 
269
     But after they are produced,
 
270
       they have different names.
 
271
<<<<<<<< LAO
 
272
========
 
273
     
 
274
       -- The Way of Lao-Tzu, tr. Wing-tsit Chan
 
275
 
 
276
>>>>>>>> TAO
 
277
""")
 
278
 
 
279
 
 
280
 
 
281
class MergePoem(TestBase):
 
282
    """Test case from diff3 manual"""
 
283
    def runTest(self):
 
284
        m3 = Merge3(TZU, LAO, TAO)
 
285
        ml = list(m3.merge_lines('LAO', 'TAO'))
 
286
        self.log('merge result:')
 
287
        self.log(''.join(ml))
 
288
        self.assertEquals(ml, MERGED_RESULT)