1
# Copyright (C) 2005-2011, 2016 Canonical Ltd
1
# Copyright (C) 2005-2011 Canonical Ltd
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
22
from ..errors import CantReprocessAndShowBase, BinaryFile
23
from ..sixish import (
22
from bzrlib.errors import CantReprocessAndShowBase, BinaryFile
27
24
def split_lines(t):
28
return BytesIO(t).readlines()
25
from cStringIO import StringIO
26
return StringIO(t).readlines()
30
28
############################################################
31
29
# test case data from the gnu diffutils manual
33
TZU = split_lines(b""" The Nameless is the origin of Heaven and Earth;
31
TZU = split_lines(""" The Nameless is the origin of Heaven and Earth;
34
32
The named is the mother of all things.
36
34
Therefore let there always be non-being,
45
43
The door of all subtleties!
48
LAO = split_lines(b""" The Way that can be told of is not the eternal Way;
46
LAO = split_lines(""" The Way that can be told of is not the eternal Way;
49
47
The name that can be named is not the eternal name.
50
48
The Nameless is the origin of Heaven and Earth;
51
49
The Named is the mother of all things.
62
TAO = split_lines(b""" The Way that can be told of is not the eternal Way;
60
TAO = split_lines(""" The Way that can be told of is not the eternal Way;
63
61
The name that can be named is not the eternal name.
64
62
The Nameless is the origin of Heaven and Earth;
65
63
The named is the mother of all things.
79
MERGED_RESULT = split_lines(b""" The Way that can be told of is not the eternal Way;
77
MERGED_RESULT = split_lines(""" The Way that can be told of is not the eternal Way;
80
78
The name that can be named is not the eternal name.
81
79
The Nameless is the origin of Heaven and Earth;
82
80
The Named is the mother of all things.
106
self.assertEqual(m3.find_unconflicted(),
104
self.assertEquals(m3.find_unconflicted(),
109
self.assertEqual(list(m3.find_sync_regions()),
107
self.assertEquals(list(m3.find_sync_regions()),
115
self.assertEqual(list(m3.merge_regions()),
113
self.assertEquals(list(m3.merge_regions()),
116
114
[('unchanged', 0, 2)])
118
self.assertEqual(list(m3.merge_groups()),
116
self.assertEquals(list(m3.merge_groups()),
119
117
[('unchanged', ['aaa', 'bbb'])])
121
119
def test_front_insert(self):
126
124
# todo: should use a sentinal at end as from get_matching_blocks
127
125
# to match without zz
128
self.assertEqual(list(m3.find_sync_regions()),
130
(1, 1, 3, 3, 1, 1),])
126
self.assertEquals(list(m3.find_sync_regions()),
132
self.assertEqual(list(m3.merge_regions()),
130
self.assertEquals(list(m3.merge_regions()),
134
132
('unchanged', 0, 1)])
136
self.assertEqual(list(m3.merge_groups()),
134
self.assertEquals(list(m3.merge_groups()),
137
135
[('a', ['aaa', 'bbb']),
138
136
('unchanged', ['zz'])])
144
142
# todo: should use a sentinal at end as from get_matching_blocks
145
143
# to match without zz
146
self.assertEqual(list(m3.find_sync_regions()),
147
[(0, 0, 2, 2, 0, 0)])
144
self.assertEquals(list(m3.find_sync_regions()),
149
self.assertEqual(list(m3.merge_regions()),
147
self.assertEquals(list(m3.merge_regions()),
152
self.assertEqual(list(m3.merge_lines()),
150
self.assertEquals(list(m3.merge_lines()),
155
153
def test_no_conflicts(self):
158
156
['aaa', '111', 'bbb'],
161
self.assertEqual(m3.find_unconflicted(),
159
self.assertEquals(m3.find_unconflicted(),
162
160
[(0, 1), (1, 2)])
164
self.assertEqual(list(m3.find_sync_regions()),
167
(2, 2, 3, 3, 2, 2),])
162
self.assertEquals(list(m3.find_sync_regions()),
169
self.assertEqual(list(m3.merge_regions()),
167
self.assertEquals(list(m3.merge_regions()),
170
168
[('unchanged', 0, 1),
172
170
('unchanged', 1, 2),])
176
174
['aaa\n', 'bbb\n', '222\n'],
177
175
['aaa\n', 'bbb\n'])
179
self.assertEqual(''.join(m3.merge_lines()),
177
self.assertEquals(''.join(m3.merge_lines()),
180
178
'aaa\nbbb\n222\n')
182
180
def test_append_b(self):
184
182
['aaa\n', 'bbb\n'],
185
183
['aaa\n', 'bbb\n', '222\n'])
187
self.assertEqual(''.join(m3.merge_lines()),
185
self.assertEquals(''.join(m3.merge_lines()),
188
186
'aaa\nbbb\n222\n')
190
188
def test_append_agreement(self):
192
190
['aaa\n', 'bbb\n', '222\n'],
193
191
['aaa\n', 'bbb\n', '222\n'])
195
self.assertEqual(''.join(m3.merge_lines()),
193
self.assertEquals(''.join(m3.merge_lines()),
196
194
'aaa\nbbb\n222\n')
198
196
def test_append_clash(self):
235
233
['aaa\n', '111\n', 'bbb\n'],
236
234
['aaa\n', '222\n', 'bbb\n'])
238
self.assertEqual(m3.find_unconflicted(),
236
self.assertEquals(m3.find_unconflicted(),
239
237
[(0, 1), (1, 2)])
241
self.assertEqual(list(m3.find_sync_regions()),
244
(2, 2, 3, 3, 3, 3),])
246
self.assertEqual(list(m3.merge_regions()),
247
[('unchanged', 0, 1),
248
('conflict', 1, 1, 1, 2, 1, 2),
249
('unchanged', 1, 2)])
251
self.assertEqual(list(m3.merge_groups()),
239
self.assertEquals(list(m3.find_sync_regions()),
244
self.assertEquals(list(m3.merge_regions()),
246
('conflict', 1,1, 1,2, 1,2),
249
self.assertEquals(list(m3.merge_groups()),
252
250
[('unchanged', ['aaa\n']),
253
251
('conflict', [], ['111\n'], ['222\n']),
254
252
('unchanged', ['bbb\n']),
275
273
['aaa', '111', 'bbb'],
276
274
['aaa', '222', 'bbb'])
278
self.assertEqual(m3.find_unconflicted(),
276
self.assertEquals(m3.find_unconflicted(),
279
277
[(0, 1), (2, 3)])
281
self.assertEqual(list(m3.find_sync_regions()),
284
(3, 3, 3, 3, 3, 3),])
279
self.assertEquals(list(m3.find_sync_regions()),
286
284
def test_replace_multi(self):
287
285
"""Replacement with regions of different size."""
289
287
['aaa', '111', '111', '111', 'bbb'],
290
288
['aaa', '222', '222', '222', '222', 'bbb'])
292
self.assertEqual(m3.find_unconflicted(),
290
self.assertEquals(m3.find_unconflicted(),
293
291
[(0, 1), (3, 4)])
296
self.assertEqual(list(m3.find_sync_regions()),
299
(4, 4, 5, 5, 6, 6),])
294
self.assertEquals(list(m3.find_sync_regions()),
301
299
def test_merge_poem(self):
302
300
"""Test case from diff3 manual"""
304
302
ml = list(m3.merge_lines('LAO', 'TAO'))
305
303
self.log('merge result:')
306
304
self.log(''.join(ml))
307
self.assertEqual(ml, MERGED_RESULT)
305
self.assertEquals(ml, MERGED_RESULT)
309
307
def test_minimal_conflicts_common(self):
310
308
"""Reprocessing"""
439
437
merge_groups and merge_regions work with non-str input. Methods that
440
438
return lines like merge_lines fail.
442
base = [(x, x) for x in 'abcde']
443
a = [(x, x) for x in 'abcdef']
444
b = [(x, x) for x in 'Zabcde']
440
base = [(x,x) for x in 'abcde']
441
a = [(x,x) for x in 'abcdef']
442
b = [(x,x) for x in 'Zabcde']
445
443
m3 = merge3.Merge3(base, a, b, allow_objects=True)
446
444
self.assertEqual(
450
448
list(m3.merge_regions()))
451
449
self.assertEqual(
452
450
[('b', [('Z', 'Z')]),
453
('unchanged', [(x, x) for x in 'abcde']),
451
('unchanged', [(x,x) for x in 'abcde']),
454
452
('a', [('f', 'f')])],
455
453
list(m3.merge_groups()))