~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 12:52:34 UTC
  • Revision ID: mbp@sourcefrog.net-20050705125234-97a16455db25c23a
- Small performance optimization for merge3

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
# common base
 
210
TZU = split_lines("""     The Nameless is the origin of Heaven and Earth;
 
211
     The named is the mother of all things.
 
212
     
 
213
     Therefore let there always be non-being,
 
214
       so we may see their subtlety,
 
215
     And let there always be being,
 
216
       so we may see their outcome.
 
217
     The two are the same,
 
218
     But after they are produced,
 
219
       they have different names.
 
220
     They both may be called deep and profound.
 
221
     Deeper and more profound,
 
222
     The door of all subtleties!
 
223
""")
 
224
 
 
225
LAO = split_lines("""     The Way that can be told of is not the eternal Way;
 
226
     The name that can be named is not the eternal name.
 
227
     The Nameless is the origin of Heaven and Earth;
 
228
     The Named is the mother of all things.
 
229
     Therefore let there always be non-being,
 
230
       so we may see their subtlety,
 
231
     And let there always be being,
 
232
       so we may see their outcome.
 
233
     The two are the same,
 
234
     But after they are produced,
 
235
       they have different names.
 
236
""")
 
237
 
 
238
 
 
239
TAO = split_lines("""     The Way that can be told of is not the eternal Way;
 
240
     The name that can be named is not the eternal name.
 
241
     The Nameless is the origin of Heaven and Earth;
 
242
     The named is the mother of all things.
 
243
     
 
244
     Therefore let there always be non-being,
 
245
       so we may see their subtlety,
 
246
     And let there always be being,
 
247
       so we may see their result.
 
248
     The two are the same,
 
249
     But after they are produced,
 
250
       they have different names.
 
251
     
 
252
       -- The Way of Lao-Tzu, tr. Wing-tsit Chan
 
253
 
 
254
""")
 
255
 
 
256
MERGED_RESULT = split_lines("""     The Way that can be told of is not the eternal Way;
 
257
     The name that can be named is not the eternal name.
 
258
     The Nameless is the origin of Heaven and Earth;
 
259
     The Named is the mother of all things.
 
260
     Therefore let there always be non-being,
 
261
       so we may see their subtlety,
 
262
     And let there always be being,
 
263
       so we may see their result.
 
264
     The two are the same,
 
265
     But after they are produced,
 
266
       they have different names.
 
267
<<<<<<<< LAO
 
268
========
 
269
     
 
270
       -- The Way of Lao-Tzu, tr. Wing-tsit Chan
 
271
 
 
272
>>>>>>>> TAO
 
273
""")
 
274
 
 
275
 
 
276
 
 
277
class MergePoem(TestBase):
 
278
    """Test case from diff3 manual"""
 
279
    def runTest(self):
 
280
        m3 = Merge3(TZU, LAO, TAO)
 
281
        ml = list(m3.merge_lines('LAO', 'TAO'))
 
282
        self.log('merge result:')
 
283
        self.log(''.join(ml))
 
284
        self.assertEquals(ml, MERGED_RESULT)