~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_merge3.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-09-29 22:03:03 UTC
  • mfrom: (5416.2.6 jam-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20100929220303-cr95h8iwtggco721
(mbp) Add 'break-lock --force'

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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.tests import TestCaseInTempDir, TestCase
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
 
 
18
from bzrlib import (
 
19
    errors,
 
20
    merge3,
 
21
    tests,
 
22
    )
19
23
from bzrlib.merge3 import Merge3
20
24
from bzrlib.errors import CantReprocessAndShowBase, BinaryFile
21
25
 
28
32
# common base
29
33
TZU = split_lines("""     The Nameless is the origin of Heaven and Earth;
30
34
     The named is the mother of all things.
31
 
     
 
35
 
32
36
     Therefore let there always be non-being,
33
37
       so we may see their subtlety,
34
38
     And let there always be being,
59
63
     The name that can be named is not the eternal name.
60
64
     The Nameless is the origin of Heaven and Earth;
61
65
     The named is the mother of all things.
62
 
     
 
66
 
63
67
     Therefore let there always be non-being,
64
68
       so we may see their subtlety,
65
69
     And let there always be being,
67
71
     The two are the same,
68
72
     But after they are produced,
69
73
       they have different names.
70
 
     
 
74
 
71
75
       -- The Way of Lao-Tzu, tr. Wing-tsit Chan
72
76
 
73
77
""")
85
89
       they have different names.
86
90
<<<<<<< LAO
87
91
=======
88
 
     
 
92
 
89
93
       -- The Way of Lao-Tzu, tr. Wing-tsit Chan
90
94
 
91
95
>>>>>>> TAO
92
96
""")
93
97
 
94
 
class TestMerge3(TestCase):
 
98
class TestMerge3(tests.TestCase):
95
99
 
96
100
    def test_no_changes(self):
97
101
        """No conflicts because nothing changed"""
98
 
        m3 = Merge3(['aaa', 'bbb'],
99
 
                    ['aaa', 'bbb'],
100
 
                    ['aaa', 'bbb'])
 
102
        m3 = merge3.Merge3(['aaa', 'bbb'],
 
103
                           ['aaa', 'bbb'],
 
104
                           ['aaa', 'bbb'])
101
105
 
102
106
        self.assertEquals(m3.find_unconflicted(),
103
107
                          [(0, 2)])
115
119
                          [('unchanged', ['aaa', 'bbb'])])
116
120
 
117
121
    def test_front_insert(self):
118
 
        m3 = Merge3(['zz'],
119
 
                    ['aaa', 'bbb', 'zz'],
120
 
                    ['zz'])
 
122
        m3 = merge3.Merge3(['zz'],
 
123
                           ['aaa', 'bbb', 'zz'],
 
124
                           ['zz'])
121
125
 
122
126
        # todo: should use a sentinal at end as from get_matching_blocks
123
127
        # to match without zz
132
136
        self.assertEquals(list(m3.merge_groups()),
133
137
                          [('a', ['aaa', 'bbb']),
134
138
                           ('unchanged', ['zz'])])
135
 
        
 
139
 
136
140
    def test_null_insert(self):
137
 
        m3 = Merge3([],
138
 
                    ['aaa', 'bbb'],
139
 
                    [])
 
141
        m3 = merge3.Merge3([],
 
142
                           ['aaa', 'bbb'],
 
143
                           [])
140
144
        # todo: should use a sentinal at end as from get_matching_blocks
141
145
        # to match without zz
142
146
        self.assertEquals(list(m3.find_sync_regions()),
150
154
 
151
155
    def test_no_conflicts(self):
152
156
        """No conflicts because only one side changed"""
153
 
        m3 = Merge3(['aaa', 'bbb'],
154
 
                    ['aaa', '111', 'bbb'],
155
 
                    ['aaa', 'bbb'])
 
157
        m3 = merge3.Merge3(['aaa', 'bbb'],
 
158
                           ['aaa', '111', 'bbb'],
 
159
                           ['aaa', 'bbb'])
156
160
 
157
161
        self.assertEquals(m3.find_unconflicted(),
158
162
                          [(0, 1), (1, 2)])
168
172
                           ('unchanged', 1, 2),])
169
173
 
170
174
    def test_append_a(self):
171
 
        m3 = Merge3(['aaa\n', 'bbb\n'],
172
 
                    ['aaa\n', 'bbb\n', '222\n'],
173
 
                    ['aaa\n', 'bbb\n'])
 
175
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
176
                           ['aaa\n', 'bbb\n', '222\n'],
 
177
                           ['aaa\n', 'bbb\n'])
174
178
 
175
179
        self.assertEquals(''.join(m3.merge_lines()),
176
180
                          'aaa\nbbb\n222\n')
177
181
 
178
182
    def test_append_b(self):
179
 
        m3 = Merge3(['aaa\n', 'bbb\n'],
180
 
                    ['aaa\n', 'bbb\n'],
181
 
                    ['aaa\n', 'bbb\n', '222\n'])
 
183
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
184
                           ['aaa\n', 'bbb\n'],
 
185
                           ['aaa\n', 'bbb\n', '222\n'])
182
186
 
183
187
        self.assertEquals(''.join(m3.merge_lines()),
184
188
                          'aaa\nbbb\n222\n')
185
189
 
186
190
    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'])
 
191
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
192
                           ['aaa\n', 'bbb\n', '222\n'],
 
193
                           ['aaa\n', 'bbb\n', '222\n'])
190
194
 
191
195
        self.assertEquals(''.join(m3.merge_lines()),
192
196
                          'aaa\nbbb\n222\n')
193
197
 
194
198
    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'])
 
199
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
200
                           ['aaa\n', 'bbb\n', '222\n'],
 
201
                           ['aaa\n', 'bbb\n', '333\n'])
198
202
 
199
203
        ml = m3.merge_lines(name_a='a',
200
204
                            name_b='b',
213
217
''')
214
218
 
215
219
    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'])
 
220
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
221
                           ['aaa\n', '222\n', 'bbb\n'],
 
222
                           ['aaa\n', '222\n', 'bbb\n'])
219
223
 
220
224
        ml = m3.merge_lines(name_a='a',
221
225
                            name_b='b',
223
227
                            mid_marker='--',
224
228
                            end_marker='>>')
225
229
        self.assertEquals(''.join(ml), 'aaa\n222\nbbb\n')
226
 
        
 
230
 
227
231
 
228
232
    def test_insert_clash(self):
229
233
        """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'])
 
234
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'],
 
235
                           ['aaa\n', '111\n', 'bbb\n'],
 
236
                           ['aaa\n', '222\n', 'bbb\n'])
233
237
 
234
238
        self.assertEquals(m3.find_unconflicted(),
235
239
                          [(0, 1), (1, 2)])
267
271
 
268
272
    def test_replace_clash(self):
269
273
        """Both try to insert lines in the same place."""
270
 
        m3 = Merge3(['aaa', '000', 'bbb'],
271
 
                    ['aaa', '111', 'bbb'],
272
 
                    ['aaa', '222', 'bbb'])
 
274
        m3 = merge3.Merge3(['aaa', '000', 'bbb'],
 
275
                           ['aaa', '111', 'bbb'],
 
276
                           ['aaa', '222', 'bbb'])
273
277
 
274
278
        self.assertEquals(m3.find_unconflicted(),
275
279
                          [(0, 1), (2, 3)])
281
285
 
282
286
    def test_replace_multi(self):
283
287
        """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'])
 
288
        m3 = merge3.Merge3(['aaa', '000', '000', 'bbb'],
 
289
                           ['aaa', '111', '111', '111', 'bbb'],
 
290
                           ['aaa', '222', '222', '222', '222', 'bbb'])
287
291
 
288
292
        self.assertEquals(m3.find_unconflicted(),
289
293
                          [(0, 1), (3, 4)])
296
300
 
297
301
    def test_merge_poem(self):
298
302
        """Test case from diff3 manual"""
299
 
        m3 = Merge3(TZU, LAO, TAO)
 
303
        m3 = merge3.Merge3(TZU, LAO, TAO)
300
304
        ml = list(m3.merge_lines('LAO', 'TAO'))
301
305
        self.log('merge result:')
302
306
        self.log(''.join(ml))
307
311
        base_text = ("a\n" * 20).splitlines(True)
308
312
        this_text = ("a\n"*10+"b\n" * 10).splitlines(True)
309
313
        other_text = ("a\n"*10+"c\n"+"b\n" * 8 + "c\n").splitlines(True)
310
 
        m3 = Merge3(base_text, other_text, this_text)
 
314
        m3 = merge3.Merge3(base_text, other_text, this_text)
311
315
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
312
316
        merged_text = "".join(list(m_lines))
313
317
        optimal_text = ("a\n" * 10 + "<<<<<<< OTHER\nc\n"
323
327
        base_text = add_newline("abcdefghijklm")
324
328
        this_text = add_newline("abcdefghijklmNOPQRSTUVWXYZ")
325
329
        other_text = add_newline("abcdefghijklm1OPQRSTUVWXY2")
326
 
        m3 = Merge3(base_text, other_text, this_text)
 
330
        m3 = merge3.Merge3(base_text, other_text, this_text)
327
331
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
328
332
        merged_text = "".join(list(m_lines))
329
333
        optimal_text = ''.join(add_newline("abcdefghijklm")
341
345
        base_text = add_newline("abacddefgghij")
342
346
        this_text = add_newline("abacddefgghijkalmontfprz")
343
347
        other_text = add_newline("abacddefgghijknlmontfprd")
344
 
        m3 = Merge3(base_text, other_text, this_text)
 
348
        m3 = merge3.Merge3(base_text, other_text, this_text)
345
349
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
346
350
        merged_text = "".join(list(m_lines))
347
351
        optimal_text = ''.join(add_newline("abacddefgghijk")
356
360
        base_text = ("a\n" * 20).splitlines(True)
357
361
        this_text = ("a\n"*10+"b\n" * 10).splitlines(True)
358
362
        other_text = ("a\n"*10+"c\n"+"b\n" * 8 + "c\n").splitlines(True)
359
 
        m3 = Merge3(base_text, other_text, this_text)
360
 
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True, 
 
363
        m3 = merge3.Merge3(base_text, other_text, this_text)
 
364
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True,
361
365
                                 base_marker='|||||||')
362
366
        self.assertRaises(CantReprocessAndShowBase, list, m_lines)
363
367
 
364
368
    def test_binary(self):
365
 
        self.assertRaises(BinaryFile, Merge3, ['\x00'], ['a'], ['b'])
 
369
        self.assertRaises(BinaryFile, merge3.Merge3, ['\x00'], ['a'], ['b'])
366
370
 
367
371
    def test_dos_text(self):
368
372
        base_text = 'a\r\n'
369
373
        this_text = 'b\r\n'
370
374
        other_text = 'c\r\n'
371
 
        m3 = Merge3(base_text.splitlines(True), other_text.splitlines(True),
372
 
                    this_text.splitlines(True))
 
375
        m3 = merge3.Merge3(base_text.splitlines(True),
 
376
                           other_text.splitlines(True),
 
377
                           this_text.splitlines(True))
373
378
        m_lines = m3.merge_lines('OTHER', 'THIS')
374
379
        self.assertEqual('<<<<<<< OTHER\r\nc\r\n=======\r\nb\r\n'
375
380
            '>>>>>>> THIS\r\n'.splitlines(True), list(m_lines))
378
383
        base_text = 'a\r'
379
384
        this_text = 'b\r'
380
385
        other_text = 'c\r'
381
 
        m3 = Merge3(base_text.splitlines(True), other_text.splitlines(True),
382
 
                    this_text.splitlines(True))
 
386
        m3 = merge3.Merge3(base_text.splitlines(True),
 
387
                           other_text.splitlines(True),
 
388
                           this_text.splitlines(True))
383
389
        m_lines = m3.merge_lines('OTHER', 'THIS')
384
390
        self.assertEqual('<<<<<<< OTHER\rc\r=======\rb\r'
385
391
            '>>>>>>> THIS\r'.splitlines(True), list(m_lines))
389
395
        this_text = "a\n"
390
396
        other_text = "a\nb\nc\n"
391
397
        # 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)
 
398
        m3 = merge3.Merge3(base_text.splitlines(True),
 
399
                           this_text.splitlines(True),
 
400
                           other_text.splitlines(True), is_cherrypick=True)
394
401
        m_lines = m3.merge_lines()
395
402
        self.assertEqualDiff('a\n<<<<<<<\n=======\nc\n>>>>>>>\n',
396
403
                             ''.join(m_lines))
397
404
 
398
405
        # This is not symmetric
399
 
        m3 = Merge3(base_text.splitlines(True), other_text.splitlines(True),
400
 
                    this_text.splitlines(True), is_cherrypick=True)
 
406
        m3 = merge3.Merge3(base_text.splitlines(True),
 
407
                           other_text.splitlines(True),
 
408
                           this_text.splitlines(True), is_cherrypick=True)
401
409
        m_lines = m3.merge_lines()
402
410
        self.assertEqualDiff('a\n<<<<<<<\nb\nc\n=======\n>>>>>>>\n',
403
411
                             ''.join(m_lines))
407
415
        this_text = 'a\nb\nq\n'
408
416
        other_text = 'a\nb\nc\nd\nf\ne\ng\n'
409
417
        # 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)
 
418
        m3 = merge3.Merge3(base_text.splitlines(True),
 
419
                           this_text.splitlines(True),
 
420
                           other_text.splitlines(True), is_cherrypick=True)
412
421
        m_lines = m3.merge_lines()
413
422
        self.assertEqualDiff('a\n'
414
423
                             'b\n'
422
431
                             'g\n'
423
432
                             '>>>>>>>\n',
424
433
                             ''.join(m_lines))
 
434
 
 
435
    def test_allow_objects(self):
 
436
        """Objects other than strs may be used with Merge3 when
 
437
        allow_objects=True.
 
438
        
 
439
        merge_groups and merge_regions work with non-str input.  Methods that
 
440
        return lines like merge_lines fail.
 
441
        """
 
442
        base = [(x,x) for x in 'abcde']
 
443
        a = [(x,x) for x in 'abcdef']
 
444
        b = [(x,x) for x in 'Zabcde']
 
445
        m3 = merge3.Merge3(base, a, b, allow_objects=True)
 
446
        self.assertEqual(
 
447
            [('b', 0, 1),
 
448
             ('unchanged', 0, 5),
 
449
             ('a', 5, 6)],
 
450
            list(m3.merge_regions()))
 
451
        self.assertEqual(
 
452
            [('b', [('Z', 'Z')]),
 
453
             ('unchanged', [(x,x) for x in 'abcde']),
 
454
             ('a', [('f', 'f')])],
 
455
            list(m3.merge_groups()))
 
456