~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_merge3.py

  • Committer: Jelmer Vernooij
  • Date: 2011-09-26 15:21:01 UTC
  • mfrom: (6165.2.3 avoid-revision-history)
  • mto: This revision was merged to the branch mainline in revision 6216.
  • Revision ID: jelmer@samba.org-20110926152101-afcxw1hikybyivfd
merge avoid-revision-history.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005 Canonical Ltd
 
1
# Copyright (C) 2005-2011 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
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
 
18
 
from bzrlib.tests import TestCaseInTempDir, TestCase
19
 
from bzrlib.merge3 import Merge3
 
18
from bzrlib import (
 
19
    merge3,
 
20
    tests,
 
21
    )
20
22
from bzrlib.errors import CantReprocessAndShowBase, BinaryFile
21
23
 
22
24
def split_lines(t):
91
93
>>>>>>> TAO
92
94
""")
93
95
 
94
 
class TestMerge3(TestCase):
 
96
class TestMerge3(tests.TestCase):
95
97
 
96
98
    def test_no_changes(self):
97
99
        """No conflicts because nothing changed"""
98
 
        m3 = Merge3(['aaa', 'bbb'],
99
 
                    ['aaa', 'bbb'],
100
 
                    ['aaa', 'bbb'])
 
100
        m3 = merge3.Merge3(['aaa', 'bbb'],
 
101
                           ['aaa', 'bbb'],
 
102
                           ['aaa', 'bbb'])
101
103
 
102
104
        self.assertEquals(m3.find_unconflicted(),
103
105
                          [(0, 2)])
115
117
                          [('unchanged', ['aaa', 'bbb'])])
116
118
 
117
119
    def test_front_insert(self):
118
 
        m3 = Merge3(['zz'],
119
 
                    ['aaa', 'bbb', 'zz'],
120
 
                    ['zz'])
 
120
        m3 = merge3.Merge3(['zz'],
 
121
                           ['aaa', 'bbb', 'zz'],
 
122
                           ['zz'])
121
123
 
122
124
        # todo: should use a sentinal at end as from get_matching_blocks
123
125
        # to match without zz
134
136
                           ('unchanged', ['zz'])])
135
137
 
136
138
    def test_null_insert(self):
137
 
        m3 = Merge3([],
138
 
                    ['aaa', 'bbb'],
139
 
                    [])
 
139
        m3 = merge3.Merge3([],
 
140
                           ['aaa', 'bbb'],
 
141
                           [])
140
142
        # todo: should use a sentinal at end as from get_matching_blocks
141
143
        # to match without zz
142
144
        self.assertEquals(list(m3.find_sync_regions()),
150
152
 
151
153
    def test_no_conflicts(self):
152
154
        """No conflicts because only one side changed"""
153
 
        m3 = Merge3(['aaa', 'bbb'],
154
 
                    ['aaa', '111', 'bbb'],
155
 
                    ['aaa', 'bbb'])
 
155
        m3 = merge3.Merge3(['aaa', 'bbb'],
 
156
                           ['aaa', '111', 'bbb'],
 
157
                           ['aaa', 'bbb'])
156
158
 
157
159
        self.assertEquals(m3.find_unconflicted(),
158
160
                          [(0, 1), (1, 2)])
168
170
                           ('unchanged', 1, 2),])
169
171
 
170
172
    def test_append_a(self):
171
 
        m3 = Merge3(['aaa\n', 'bbb\n'],
172
 
                    ['aaa\n', 'bbb\n', '222\n'],
173
 
                    ['aaa\n', 'bbb\n'])
 
173
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
174
                           ['aaa\n', 'bbb\n', '222\n'],
 
175
                           ['aaa\n', 'bbb\n'])
174
176
 
175
177
        self.assertEquals(''.join(m3.merge_lines()),
176
178
                          'aaa\nbbb\n222\n')
177
179
 
178
180
    def test_append_b(self):
179
 
        m3 = Merge3(['aaa\n', 'bbb\n'],
180
 
                    ['aaa\n', 'bbb\n'],
181
 
                    ['aaa\n', 'bbb\n', '222\n'])
 
181
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
182
                           ['aaa\n', 'bbb\n'],
 
183
                           ['aaa\n', 'bbb\n', '222\n'])
182
184
 
183
185
        self.assertEquals(''.join(m3.merge_lines()),
184
186
                          'aaa\nbbb\n222\n')
185
187
 
186
188
    def test_append_agreement(self):
187
 
        m3 = Merge3(['aaa\n', 'bbb\n'],
188
 
                    ['aaa\n', 'bbb\n', '222\n'],
189
 
                    ['aaa\n', 'bbb\n', '222\n'])
 
189
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
190
                           ['aaa\n', 'bbb\n', '222\n'],
 
191
                           ['aaa\n', 'bbb\n', '222\n'])
190
192
 
191
193
        self.assertEquals(''.join(m3.merge_lines()),
192
194
                          'aaa\nbbb\n222\n')
193
195
 
194
196
    def test_append_clash(self):
195
 
        m3 = Merge3(['aaa\n', 'bbb\n'],
196
 
                    ['aaa\n', 'bbb\n', '222\n'],
197
 
                    ['aaa\n', 'bbb\n', '333\n'])
 
197
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
198
                           ['aaa\n', 'bbb\n', '222\n'],
 
199
                           ['aaa\n', 'bbb\n', '333\n'])
198
200
 
199
201
        ml = m3.merge_lines(name_a='a',
200
202
                            name_b='b',
213
215
''')
214
216
 
215
217
    def test_insert_agreement(self):
216
 
        m3 = Merge3(['aaa\n', 'bbb\n'],
217
 
                    ['aaa\n', '222\n', 'bbb\n'],
218
 
                    ['aaa\n', '222\n', 'bbb\n'])
 
218
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
219
                           ['aaa\n', '222\n', 'bbb\n'],
 
220
                           ['aaa\n', '222\n', 'bbb\n'])
219
221
 
220
222
        ml = m3.merge_lines(name_a='a',
221
223
                            name_b='b',
227
229
 
228
230
    def test_insert_clash(self):
229
231
        """Both try to insert lines in the same place."""
230
 
        m3 = Merge3(['aaa\n', 'bbb\n'],
231
 
                    ['aaa\n', '111\n', 'bbb\n'],
232
 
                    ['aaa\n', '222\n', 'bbb\n'])
 
232
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
233
                           ['aaa\n', '111\n', 'bbb\n'],
 
234
                           ['aaa\n', '222\n', 'bbb\n'])
233
235
 
234
236
        self.assertEquals(m3.find_unconflicted(),
235
237
                          [(0, 1), (1, 2)])
267
269
 
268
270
    def test_replace_clash(self):
269
271
        """Both try to insert lines in the same place."""
270
 
        m3 = Merge3(['aaa', '000', 'bbb'],
271
 
                    ['aaa', '111', 'bbb'],
272
 
                    ['aaa', '222', 'bbb'])
 
272
        m3 = merge3.Merge3(['aaa', '000', 'bbb'],
 
273
                           ['aaa', '111', 'bbb'],
 
274
                           ['aaa', '222', 'bbb'])
273
275
 
274
276
        self.assertEquals(m3.find_unconflicted(),
275
277
                          [(0, 1), (2, 3)])
281
283
 
282
284
    def test_replace_multi(self):
283
285
        """Replacement with regions of different size."""
284
 
        m3 = Merge3(['aaa', '000', '000', 'bbb'],
285
 
                    ['aaa', '111', '111', '111', 'bbb'],
286
 
                    ['aaa', '222', '222', '222', '222', 'bbb'])
 
286
        m3 = merge3.Merge3(['aaa', '000', '000', 'bbb'],
 
287
                           ['aaa', '111', '111', '111', 'bbb'],
 
288
                           ['aaa', '222', '222', '222', '222', 'bbb'])
287
289
 
288
290
        self.assertEquals(m3.find_unconflicted(),
289
291
                          [(0, 1), (3, 4)])
296
298
 
297
299
    def test_merge_poem(self):
298
300
        """Test case from diff3 manual"""
299
 
        m3 = Merge3(TZU, LAO, TAO)
 
301
        m3 = merge3.Merge3(TZU, LAO, TAO)
300
302
        ml = list(m3.merge_lines('LAO', 'TAO'))
301
303
        self.log('merge result:')
302
304
        self.log(''.join(ml))
307
309
        base_text = ("a\n" * 20).splitlines(True)
308
310
        this_text = ("a\n"*10+"b\n" * 10).splitlines(True)
309
311
        other_text = ("a\n"*10+"c\n"+"b\n" * 8 + "c\n").splitlines(True)
310
 
        m3 = Merge3(base_text, other_text, this_text)
 
312
        m3 = merge3.Merge3(base_text, other_text, this_text)
311
313
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
312
314
        merged_text = "".join(list(m_lines))
313
315
        optimal_text = ("a\n" * 10 + "<<<<<<< OTHER\nc\n"
323
325
        base_text = add_newline("abcdefghijklm")
324
326
        this_text = add_newline("abcdefghijklmNOPQRSTUVWXYZ")
325
327
        other_text = add_newline("abcdefghijklm1OPQRSTUVWXY2")
326
 
        m3 = Merge3(base_text, other_text, this_text)
 
328
        m3 = merge3.Merge3(base_text, other_text, this_text)
327
329
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
328
330
        merged_text = "".join(list(m_lines))
329
331
        optimal_text = ''.join(add_newline("abcdefghijklm")
341
343
        base_text = add_newline("abacddefgghij")
342
344
        this_text = add_newline("abacddefgghijkalmontfprz")
343
345
        other_text = add_newline("abacddefgghijknlmontfprd")
344
 
        m3 = Merge3(base_text, other_text, this_text)
 
346
        m3 = merge3.Merge3(base_text, other_text, this_text)
345
347
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
346
348
        merged_text = "".join(list(m_lines))
347
349
        optimal_text = ''.join(add_newline("abacddefgghijk")
356
358
        base_text = ("a\n" * 20).splitlines(True)
357
359
        this_text = ("a\n"*10+"b\n" * 10).splitlines(True)
358
360
        other_text = ("a\n"*10+"c\n"+"b\n" * 8 + "c\n").splitlines(True)
359
 
        m3 = Merge3(base_text, other_text, this_text)
 
361
        m3 = merge3.Merge3(base_text, other_text, this_text)
360
362
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True,
361
363
                                 base_marker='|||||||')
362
364
        self.assertRaises(CantReprocessAndShowBase, list, m_lines)
363
365
 
364
366
    def test_binary(self):
365
 
        self.assertRaises(BinaryFile, Merge3, ['\x00'], ['a'], ['b'])
 
367
        self.assertRaises(BinaryFile, merge3.Merge3, ['\x00'], ['a'], ['b'])
366
368
 
367
369
    def test_dos_text(self):
368
370
        base_text = 'a\r\n'
369
371
        this_text = 'b\r\n'
370
372
        other_text = 'c\r\n'
371
 
        m3 = Merge3(base_text.splitlines(True), other_text.splitlines(True),
372
 
                    this_text.splitlines(True))
 
373
        m3 = merge3.Merge3(base_text.splitlines(True),
 
374
                           other_text.splitlines(True),
 
375
                           this_text.splitlines(True))
373
376
        m_lines = m3.merge_lines('OTHER', 'THIS')
374
377
        self.assertEqual('<<<<<<< OTHER\r\nc\r\n=======\r\nb\r\n'
375
378
            '>>>>>>> THIS\r\n'.splitlines(True), list(m_lines))
378
381
        base_text = 'a\r'
379
382
        this_text = 'b\r'
380
383
        other_text = 'c\r'
381
 
        m3 = Merge3(base_text.splitlines(True), other_text.splitlines(True),
382
 
                    this_text.splitlines(True))
 
384
        m3 = merge3.Merge3(base_text.splitlines(True),
 
385
                           other_text.splitlines(True),
 
386
                           this_text.splitlines(True))
383
387
        m_lines = m3.merge_lines('OTHER', 'THIS')
384
388
        self.assertEqual('<<<<<<< OTHER\rc\r=======\rb\r'
385
389
            '>>>>>>> THIS\r'.splitlines(True), list(m_lines))
389
393
        this_text = "a\n"
390
394
        other_text = "a\nb\nc\n"
391
395
        # When cherrypicking, lines in base are not part of the conflict
392
 
        m3 = Merge3(base_text.splitlines(True), this_text.splitlines(True),
393
 
                    other_text.splitlines(True), is_cherrypick=True)
 
396
        m3 = merge3.Merge3(base_text.splitlines(True),
 
397
                           this_text.splitlines(True),
 
398
                           other_text.splitlines(True), is_cherrypick=True)
394
399
        m_lines = m3.merge_lines()
395
400
        self.assertEqualDiff('a\n<<<<<<<\n=======\nc\n>>>>>>>\n',
396
401
                             ''.join(m_lines))
397
402
 
398
403
        # This is not symmetric
399
 
        m3 = Merge3(base_text.splitlines(True), other_text.splitlines(True),
400
 
                    this_text.splitlines(True), is_cherrypick=True)
 
404
        m3 = merge3.Merge3(base_text.splitlines(True),
 
405
                           other_text.splitlines(True),
 
406
                           this_text.splitlines(True), is_cherrypick=True)
401
407
        m_lines = m3.merge_lines()
402
408
        self.assertEqualDiff('a\n<<<<<<<\nb\nc\n=======\n>>>>>>>\n',
403
409
                             ''.join(m_lines))
407
413
        this_text = 'a\nb\nq\n'
408
414
        other_text = 'a\nb\nc\nd\nf\ne\ng\n'
409
415
        # When cherrypicking, lines in base are not part of the conflict
410
 
        m3 = Merge3(base_text.splitlines(True), this_text.splitlines(True),
411
 
                    other_text.splitlines(True), is_cherrypick=True)
 
416
        m3 = merge3.Merge3(base_text.splitlines(True),
 
417
                           this_text.splitlines(True),
 
418
                           other_text.splitlines(True), is_cherrypick=True)
412
419
        m_lines = m3.merge_lines()
413
420
        self.assertEqualDiff('a\n'
414
421
                             'b\n'
422
429
                             'g\n'
423
430
                             '>>>>>>>\n',
424
431
                             ''.join(m_lines))
 
432
 
 
433
    def test_allow_objects(self):
 
434
        """Objects other than strs may be used with Merge3 when
 
435
        allow_objects=True.
 
436
        
 
437
        merge_groups and merge_regions work with non-str input.  Methods that
 
438
        return lines like merge_lines fail.
 
439
        """
 
440
        base = [(x,x) for x in 'abcde']
 
441
        a = [(x,x) for x in 'abcdef']
 
442
        b = [(x,x) for x in 'Zabcde']
 
443
        m3 = merge3.Merge3(base, a, b, allow_objects=True)
 
444
        self.assertEqual(
 
445
            [('b', 0, 1),
 
446
             ('unchanged', 0, 5),
 
447
             ('a', 5, 6)],
 
448
            list(m3.merge_regions()))
 
449
        self.assertEqual(
 
450
            [('b', [('Z', 'Z')]),
 
451
             ('unchanged', [(x,x) for x in 'abcde']),
 
452
             ('a', [('f', 'f')])],
 
453
            list(m3.merge_groups()))
 
454