~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to tools/testweave.py

  • Committer: Martin Pool
  • Date: 2005-07-15 22:55:36 UTC
  • Revision ID: mbp@sourcefrog.net-20050715225536-47d68404108e4eb8
- shell script to set up a weave merge test case

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/python2.4
 
2
 
 
3
# Copyright (C) 2005 by Canonical Ltd
 
4
 
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by
 
7
# the Free Software Foundation; either version 2 of the License, or
 
8
# (at your option) any later version.
 
9
 
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
 
 
15
# You should have received a copy of the GNU General Public License
 
16
# along with this program; if not, write to the Free Software
 
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
 
 
20
 
 
21
 
 
22
"""test suite for weave algorithm"""
 
23
 
 
24
 
 
25
import testsweet
 
26
from bzrlib.weave import Weave, WeaveFormatError
 
27
from bzrlib.weavefile import write_weave, read_weave
 
28
from pprint import pformat
 
29
 
 
30
 
 
31
 
 
32
try:
 
33
    set
 
34
    frozenset
 
35
except NameError:
 
36
    from sets import Set, ImmutableSet
 
37
    set = Set
 
38
    frozenset = ImmutableSet
 
39
    del Set, ImmutableSet
 
40
 
 
41
 
 
42
 
 
43
# texts for use in testing
 
44
TEXT_0 = ["Hello world"]
 
45
TEXT_1 = ["Hello world",
 
46
          "A second line"]
 
47
 
 
48
 
 
49
 
 
50
class TestBase(testsweet.TestBase):
 
51
    def check_read_write(self, k):
 
52
        """Check the weave k can be written & re-read."""
 
53
        from tempfile import TemporaryFile
 
54
        tf = TemporaryFile()
 
55
 
 
56
        write_weave(k, tf)
 
57
        tf.seek(0)
 
58
        k2 = read_weave(tf)
 
59
 
 
60
        if k != k2:
 
61
            tf.seek(0)
 
62
            self.log('serialized weave:')
 
63
            self.log(tf.read())
 
64
            self.fail('read/write check failed')
 
65
        
 
66
        
 
67
 
 
68
 
 
69
class Easy(TestBase):
 
70
    def runTest(self):
 
71
        k = Weave()
 
72
 
 
73
 
 
74
class StoreText(TestBase):
 
75
    """Store and retrieve a simple text."""
 
76
    def runTest(self):
 
77
        k = Weave()
 
78
        idx = k.add([], TEXT_0)
 
79
        self.assertEqual(k.get(idx), TEXT_0)
 
80
        self.assertEqual(idx, 0)
 
81
 
 
82
 
 
83
 
 
84
class AnnotateOne(TestBase):
 
85
    def runTest(self):
 
86
        k = Weave()
 
87
        k.add([], TEXT_0)
 
88
        self.assertEqual(k.annotate(0),
 
89
                         [(0, TEXT_0[0])])
 
90
 
 
91
 
 
92
class StoreTwo(TestBase):
 
93
    def runTest(self):
 
94
        k = Weave()
 
95
 
 
96
        idx = k.add([], TEXT_0)
 
97
        self.assertEqual(idx, 0)
 
98
 
 
99
        idx = k.add([], TEXT_1)
 
100
        self.assertEqual(idx, 1)
 
101
 
 
102
        self.assertEqual(k.get(0), TEXT_0)
 
103
        self.assertEqual(k.get(1), TEXT_1)
 
104
 
 
105
        k.dump(self.TEST_LOG)
 
106
 
 
107
 
 
108
 
 
109
class DeltaAdd(TestBase):
 
110
    """Detection of changes prior to inserting new revision."""
 
111
    def runTest(self):
 
112
        k = Weave()
 
113
        k.add([], ['line 1'])
 
114
 
 
115
        self.assertEqual(k._l,
 
116
                         [('{', 0),
 
117
                          'line 1',
 
118
                          ('}', 0),
 
119
                          ])
 
120
 
 
121
        changes = list(k._delta(set([0]),
 
122
                                ['line 1',
 
123
                                 'new line']))
 
124
 
 
125
        self.log('raw changes: ' + pformat(changes))
 
126
 
 
127
        # currently there are 3 lines in the weave, and we insert after them
 
128
        self.assertEquals(changes,
 
129
                          [(3, 3, ['new line'])])
 
130
 
 
131
        changes = k._delta(set([0]),
 
132
                           ['top line',
 
133
                            'line 1'])
 
134
        
 
135
        self.assertEquals(list(changes),
 
136
                          [(1, 1, ['top line'])])
 
137
 
 
138
        self.check_read_write(k)
 
139
 
 
140
 
 
141
class InvalidAdd(TestBase):
 
142
    """Try to use invalid version number during add."""
 
143
    def runTest(self):
 
144
        k = Weave()
 
145
 
 
146
        self.assertRaises(ValueError,
 
147
                          k.add,
 
148
                          [69],
 
149
                          ['new text!'])
 
150
 
 
151
 
 
152
class InsertLines(TestBase):
 
153
    """Store a revision that adds one line to the original.
 
154
 
 
155
    Look at the annotations to make sure that the first line is matched
 
156
    and not stored repeatedly."""
 
157
    def runTest(self):
 
158
        k = Weave()
 
159
 
 
160
        k.add([], ['line 1'])
 
161
        k.add([0], ['line 1', 'line 2'])
 
162
 
 
163
        self.assertEqual(k.annotate(0),
 
164
                         [(0, 'line 1')])
 
165
 
 
166
        self.assertEqual(k.get(1),
 
167
                         ['line 1',
 
168
                          'line 2'])
 
169
 
 
170
        self.assertEqual(k.annotate(1),
 
171
                         [(0, 'line 1'),
 
172
                          (1, 'line 2')])
 
173
 
 
174
        k.add([0], ['line 1', 'diverged line'])
 
175
 
 
176
        self.assertEqual(k.annotate(2),
 
177
                         [(0, 'line 1'),
 
178
                          (2, 'diverged line')])
 
179
 
 
180
        text3 = ['line 1', 'middle line', 'line 2']
 
181
        k.add([0, 1],
 
182
              text3)
 
183
 
 
184
        self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]), text3))))
 
185
 
 
186
        self.log("k._l=" + pformat(k._l))
 
187
 
 
188
        self.assertEqual(k.annotate(3),
 
189
                         [(0, 'line 1'),
 
190
                          (3, 'middle line'),
 
191
                          (1, 'line 2')])
 
192
 
 
193
        # now multiple insertions at different places
 
194
        k.add([0, 1, 3],
 
195
              ['line 1', 'aaa', 'middle line', 'bbb', 'line 2', 'ccc'])
 
196
 
 
197
        self.assertEqual(k.annotate(4), 
 
198
                         [(0, 'line 1'),
 
199
                          (4, 'aaa'),
 
200
                          (3, 'middle line'),
 
201
                          (4, 'bbb'),
 
202
                          (1, 'line 2'),
 
203
                          (4, 'ccc')])
 
204
 
 
205
 
 
206
 
 
207
class DeleteLines(TestBase):
 
208
    """Deletion of lines from existing text.
 
209
 
 
210
    Try various texts all based on a common ancestor."""
 
211
    def runTest(self):
 
212
        k = Weave()
 
213
 
 
214
        base_text = ['one', 'two', 'three', 'four']
 
215
 
 
216
        k.add([], base_text)
 
217
        
 
218
        texts = [['one', 'two', 'three'],
 
219
                 ['two', 'three', 'four'],
 
220
                 ['one', 'four'],
 
221
                 ['one', 'two', 'three', 'four'],
 
222
                 ]
 
223
 
 
224
        for t in texts:
 
225
            ver = k.add([0], t)
 
226
 
 
227
        self.log('final weave:')
 
228
        self.log('k._l=' + pformat(k._l))
 
229
 
 
230
        for i in range(len(texts)):
 
231
            self.assertEqual(k.get(i+1),
 
232
                             texts[i])
 
233
            
 
234
 
 
235
 
 
236
 
 
237
class SuicideDelete(TestBase):
 
238
    """Invalid weave which tries to add and delete simultaneously."""
 
239
    def runTest(self):
 
240
        k = Weave()
 
241
 
 
242
        k._v = [(),
 
243
                ]
 
244
        k._l = [('{', 0),
 
245
                'first line',
 
246
                ('[', 0),
 
247
                'deleted in 0',
 
248
                (']', 0),
 
249
                ('}', 0),
 
250
                ]
 
251
        ################################### SKIPPED
 
252
        # Weave.get doesn't trap this anymore
 
253
        return 
 
254
 
 
255
        self.assertRaises(WeaveFormatError,
 
256
                          k.get,
 
257
                          0)        
 
258
 
 
259
 
 
260
 
 
261
class CannedDelete(TestBase):
 
262
    """Unpack canned weave with deleted lines."""
 
263
    def runTest(self):
 
264
        k = Weave()
 
265
 
 
266
        k._v = [(),
 
267
                frozenset([0]),
 
268
                ]
 
269
        k._l = [('{', 0),
 
270
                'first line',
 
271
                ('[', 1),
 
272
                'line to be deleted',
 
273
                (']', 1),
 
274
                'last line',
 
275
                ('}', 0),
 
276
                ]
 
277
 
 
278
        self.assertEqual(k.get(0),
 
279
                         ['first line',
 
280
                          'line to be deleted',
 
281
                          'last line',
 
282
                          ])
 
283
 
 
284
        self.assertEqual(k.get(1),
 
285
                         ['first line',
 
286
                          'last line',
 
287
                          ])
 
288
 
 
289
 
 
290
 
 
291
class CannedReplacement(TestBase):
 
292
    """Unpack canned weave with deleted lines."""
 
293
    def runTest(self):
 
294
        k = Weave()
 
295
 
 
296
        k._v = [frozenset(),
 
297
                frozenset([0]),
 
298
                ]
 
299
        k._l = [('{', 0),
 
300
                'first line',
 
301
                ('[', 1),
 
302
                'line to be deleted',
 
303
                (']', 1),
 
304
                ('{', 1),
 
305
                'replacement line',                
 
306
                ('}', 1),
 
307
                'last line',
 
308
                ('}', 0),
 
309
                ]
 
310
 
 
311
        self.assertEqual(k.get(0),
 
312
                         ['first line',
 
313
                          'line to be deleted',
 
314
                          'last line',
 
315
                          ])
 
316
 
 
317
        self.assertEqual(k.get(1),
 
318
                         ['first line',
 
319
                          'replacement line',
 
320
                          'last line',
 
321
                          ])
 
322
 
 
323
 
 
324
 
 
325
class BadWeave(TestBase):
 
326
    """Test that we trap an insert which should not occur."""
 
327
    def runTest(self):
 
328
        k = Weave()
 
329
 
 
330
        k._v = [frozenset(),
 
331
                ]
 
332
        k._l = ['bad line',
 
333
                ('{', 0),
 
334
                'foo {',
 
335
                ('{', 1),
 
336
                '  added in version 1',
 
337
                ('{', 2),
 
338
                '  added in v2',
 
339
                ('}', 2),
 
340
                '  also from v1',
 
341
                ('}', 1),
 
342
                '}',
 
343
                ('}', 0)]
 
344
 
 
345
        ################################### SKIPPED
 
346
        # Weave.get doesn't trap this anymore
 
347
        return 
 
348
 
 
349
 
 
350
        self.assertRaises(WeaveFormatError,
 
351
                          k.get,
 
352
                          0)
 
353
 
 
354
 
 
355
class BadInsert(TestBase):
 
356
    """Test that we trap an insert which should not occur."""
 
357
    def runTest(self):
 
358
        k = Weave()
 
359
 
 
360
        k._v = [frozenset(),
 
361
                frozenset([0]),
 
362
                frozenset([0]),
 
363
                frozenset([0,1,2]),
 
364
                ]
 
365
        k._l = [('{', 0),
 
366
                'foo {',
 
367
                ('{', 1),
 
368
                '  added in version 1',
 
369
                ('{', 1),
 
370
                '  more in 1',
 
371
                ('}', 1),
 
372
                ('}', 1),
 
373
                ('}', 0)]
 
374
 
 
375
 
 
376
        # this is not currently enforced by get
 
377
        return  ##########################################
 
378
 
 
379
        self.assertRaises(WeaveFormatError,
 
380
                          k.get,
 
381
                          0)
 
382
 
 
383
        self.assertRaises(WeaveFormatError,
 
384
                          k.get,
 
385
                          1)
 
386
 
 
387
 
 
388
class InsertNested(TestBase):
 
389
    """Insertion with nested instructions."""
 
390
    def runTest(self):
 
391
        k = Weave()
 
392
 
 
393
        k._v = [frozenset(),
 
394
                frozenset([0]),
 
395
                frozenset([0]),
 
396
                frozenset([0,1,2]),
 
397
                ]
 
398
        k._l = [('{', 0),
 
399
                'foo {',
 
400
                ('{', 1),
 
401
                '  added in version 1',
 
402
                ('{', 2),
 
403
                '  added in v2',
 
404
                ('}', 2),
 
405
                '  also from v1',
 
406
                ('}', 1),
 
407
                '}',
 
408
                ('}', 0)]
 
409
 
 
410
        self.assertEqual(k.get(0),
 
411
                         ['foo {',
 
412
                          '}'])
 
413
 
 
414
        self.assertEqual(k.get(1),
 
415
                         ['foo {',
 
416
                          '  added in version 1',
 
417
                          '  also from v1',
 
418
                          '}'])
 
419
                       
 
420
        self.assertEqual(k.get(2),
 
421
                         ['foo {',
 
422
                          '  added in v2',
 
423
                          '}'])
 
424
 
 
425
        self.assertEqual(k.get(3),
 
426
                         ['foo {',
 
427
                          '  added in version 1',
 
428
                          '  added in v2',
 
429
                          '  also from v1',
 
430
                          '}'])
 
431
                         
 
432
 
 
433
 
 
434
class DeleteLines2(TestBase):
 
435
    """Test recording revisions that delete lines.
 
436
 
 
437
    This relies on the weave having a way to represent lines knocked
 
438
    out by a later revision."""
 
439
    def runTest(self):
 
440
        k = Weave()
 
441
 
 
442
        k.add([], ["line the first",
 
443
                   "line 2",
 
444
                   "line 3",
 
445
                   "fine"])
 
446
 
 
447
        self.assertEqual(len(k.get(0)), 4)
 
448
 
 
449
        k.add([0], ["line the first",
 
450
                   "fine"])
 
451
 
 
452
        self.assertEqual(k.get(1),
 
453
                         ["line the first",
 
454
                          "fine"])
 
455
 
 
456
        self.assertEqual(k.annotate(1),
 
457
                         [(0, "line the first"),
 
458
                          (0, "fine")])
 
459
 
 
460
 
 
461
 
 
462
class IncludeVersions(TestBase):
 
463
    """Check texts that are stored across multiple revisions.
 
464
 
 
465
    Here we manually create a weave with particular encoding and make
 
466
    sure it unpacks properly.
 
467
 
 
468
    Text 0 includes nothing; text 1 includes text 0 and adds some
 
469
    lines.
 
470
    """
 
471
 
 
472
    def runTest(self):
 
473
        k = Weave()
 
474
 
 
475
        k._v = [frozenset(), frozenset([0])]
 
476
        k._l = [('{', 0),
 
477
                "first line",
 
478
                ('}', 0),
 
479
                ('{', 1),
 
480
                "second line",
 
481
                ('}', 1)]
 
482
 
 
483
        self.assertEqual(k.get(1),
 
484
                         ["first line",
 
485
                          "second line"])
 
486
 
 
487
        self.assertEqual(k.get(0),
 
488
                         ["first line"])
 
489
 
 
490
        k.dump(self.TEST_LOG)
 
491
 
 
492
 
 
493
class DivergedIncludes(TestBase):
 
494
    """Weave with two diverged texts based on version 0.
 
495
    """
 
496
    def runTest(self):
 
497
        k = Weave()
 
498
 
 
499
        k._v = [frozenset(),
 
500
                frozenset([0]),
 
501
                frozenset([0]),
 
502
                ]
 
503
        k._l = [('{', 0),
 
504
                "first line",
 
505
                ('}', 0),
 
506
                ('{', 1),
 
507
                "second line",
 
508
                ('}', 1),
 
509
                ('{', 2),
 
510
                "alternative second line",
 
511
                ('}', 2),                
 
512
                ]
 
513
 
 
514
        self.assertEqual(k.get(0),
 
515
                         ["first line"])
 
516
 
 
517
        self.assertEqual(k.get(1),
 
518
                         ["first line",
 
519
                          "second line"])
 
520
 
 
521
        self.assertEqual(k.get(2),
 
522
                         ["first line",
 
523
                          "alternative second line"])
 
524
 
 
525
        self.assertEqual(k.inclusions([2]),
 
526
                         set([0, 2]))
 
527
 
 
528
 
 
529
 
 
530
class ReplaceLine(TestBase):
 
531
    def runTest(self):
 
532
        k = Weave()
 
533
 
 
534
        text0 = ['cheddar', 'stilton', 'gruyere']
 
535
        text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
 
536
        
 
537
        k.add([], text0)
 
538
        k.add([0], text1)
 
539
 
 
540
        self.log('k._l=' + pformat(k._l))
 
541
 
 
542
        self.assertEqual(k.get(0), text0)
 
543
        self.assertEqual(k.get(1), text1)
 
544
 
 
545
 
 
546
 
 
547
class Merge(TestBase):
 
548
    """Storage of versions that merge diverged parents"""
 
549
    def runTest(self):
 
550
        k = Weave()
 
551
 
 
552
        texts = [['header'],
 
553
                 ['header', '', 'line from 1'],
 
554
                 ['header', '', 'line from 2', 'more from 2'],
 
555
                 ['header', '', 'line from 1', 'fixup line', 'line from 2'],
 
556
                 ]
 
557
 
 
558
        k.add([], texts[0])
 
559
        k.add([0], texts[1])
 
560
        k.add([0], texts[2])
 
561
        k.add([0, 1, 2], texts[3])
 
562
 
 
563
        for i, t in enumerate(texts):
 
564
            self.assertEqual(k.get(i), t)
 
565
 
 
566
        self.assertEqual(k.annotate(3),
 
567
                         [(0, 'header'),
 
568
                          (1, ''),
 
569
                          (1, 'line from 1'),
 
570
                          (3, 'fixup line'),
 
571
                          (2, 'line from 2'),
 
572
                          ])
 
573
 
 
574
        self.assertEqual(k.inclusions([3]),
 
575
                         set([0, 1, 2, 3]))
 
576
 
 
577
        self.log('k._l=' + pformat(k._l))
 
578
 
 
579
        self.check_read_write(k)
 
580
 
 
581
 
 
582
class Conflicts(TestBase):
 
583
    """Test detection of conflicting regions during a merge.
 
584
 
 
585
    A base version is inserted, then two descendents try to
 
586
    insert different lines in the same place.  These should be
 
587
    reported as a possible conflict and forwarded to the user."""
 
588
    def runTest(self):
 
589
        return  # NOT RUN
 
590
        k = Weave()
 
591
 
 
592
        k.add([], ['aaa', 'bbb'])
 
593
        k.add([0], ['aaa', '111', 'bbb'])
 
594
        k.add([1], ['aaa', '222', 'bbb'])
 
595
 
 
596
        merged = k.merge([1, 2])
 
597
 
 
598
        self.assertEquals([[['aaa']],
 
599
                           [['111'], ['222']],
 
600
                           [['bbb']]])
 
601
 
 
602
 
 
603
 
 
604
class NonConflict(TestBase):
 
605
    """Two descendants insert compatible changes.
 
606
 
 
607
    No conflict should be reported."""
 
608
    def runTest(self):
 
609
        return  # NOT RUN
 
610
        k = Weave()
 
611
 
 
612
        k.add([], ['aaa', 'bbb'])
 
613
        k.add([0], ['111', 'aaa', 'ccc', 'bbb'])
 
614
        k.add([1], ['aaa', 'ccc', 'bbb', '222'])
 
615
 
 
616
    
 
617
    
 
618
 
 
619
 
 
620
class AutoMerge(TestBase):
 
621
    def runTest(self):
 
622
        k = Weave()
 
623
 
 
624
        texts = [['header', 'aaa', 'bbb'],
 
625
                 ['header', 'aaa', 'line from 1', 'bbb'],
 
626
                 ['header', 'aaa', 'bbb', 'line from 2', 'more from 2'],
 
627
                 ]
 
628
 
 
629
        k.add([], texts[0])
 
630
        k.add([0], texts[1])
 
631
        k.add([0], texts[2])
 
632
 
 
633
        self.log('k._l=' + pformat(k._l))
 
634
 
 
635
        m = list(k.mash_iter([0, 1, 2]))
 
636
 
 
637
        self.assertEqual(m,
 
638
                         ['header', 'aaa',
 
639
                          'line from 1',
 
640
                          'bbb',
 
641
                          'line from 2', 'more from 2'])
 
642
        
 
643
 
 
644
 
 
645
class Khayyam(TestBase):
 
646
    """Test changes to multi-line texts, and read/write"""
 
647
    def runTest(self):
 
648
        rawtexts = [
 
649
            """A Book of Verses underneath the Bough,
 
650
            A Jug of Wine, a Loaf of Bread, -- and Thou
 
651
            Beside me singing in the Wilderness --
 
652
            Oh, Wilderness were Paradise enow!""",
 
653
            
 
654
            """A Book of Verses underneath the Bough,
 
655
            A Jug of Wine, a Loaf of Bread, -- and Thou
 
656
            Beside me singing in the Wilderness --
 
657
            Oh, Wilderness were Paradise now!""",
 
658
 
 
659
            """A Book of poems underneath the tree,
 
660
            A Jug of Wine, a Loaf of Bread,
 
661
            and Thou
 
662
            Beside me singing in the Wilderness --
 
663
            Oh, Wilderness were Paradise now!
 
664
 
 
665
            -- O. Khayyam""",
 
666
 
 
667
            """A Book of Verses underneath the Bough,
 
668
            A Jug of Wine, a Loaf of Bread,
 
669
            and Thou
 
670
            Beside me singing in the Wilderness --
 
671
            Oh, Wilderness were Paradise now!""",
 
672
            ]
 
673
        texts = [[l.strip() for l in t.split('\n')] for t in rawtexts]
 
674
 
 
675
        k = Weave()
 
676
        parents = set()
 
677
        for t in texts:
 
678
            ver = k.add(list(parents), t)
 
679
            parents.add(ver)
 
680
 
 
681
        self.log("k._l=" + pformat(k._l))
 
682
 
 
683
        for i, t in enumerate(texts):
 
684
            self.assertEqual(k.get(i), t)
 
685
 
 
686
        self.check_read_write(k)
 
687
 
 
688
 
 
689
 
 
690
class MergeCases(TestBase):
 
691
    def doMerge(self, base, a, b, mp):
 
692
        from cStringIO import StringIO
 
693
        from textwrap import dedent
 
694
 
 
695
        def addcrlf(x):
 
696
            return x + '\n'
 
697
        
 
698
        w = Weave()
 
699
        w.add([], map(addcrlf, base))
 
700
        w.add([0], map(addcrlf, a))
 
701
        w.add([0], map(addcrlf, b))
 
702
 
 
703
        self.log('merge plan:')
 
704
        p = list(w.plan_merge(1, 2))
 
705
        for state, line in p:
 
706
            if line:
 
707
                self.log('%12s | %s' % (state, line[:-1]))
 
708
 
 
709
        self.log('merge:')
 
710
        mt = StringIO()
 
711
        mt.writelines(w.weave_merge(p))
 
712
        mt.seek(0)
 
713
        self.log(mt.getvalue())
 
714
 
 
715
        mp = map(addcrlf, mp)
 
716
        self.assertEqual(mt.readlines(), mp)
 
717
        
 
718
        
 
719
    def testOneInsert(self):
 
720
        self.doMerge([],
 
721
                     ['aa'],
 
722
                     [],
 
723
                     ['aa'])
 
724
 
 
725
    def testSeparateInserts(self):
 
726
        self.doMerge(['aaa', 'bbb', 'ccc'],
 
727
                     ['aaa', 'xxx', 'bbb', 'ccc'],
 
728
                     ['aaa', 'bbb', 'yyy', 'ccc'],
 
729
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'])
 
730
 
 
731
    def testSameInsert(self):
 
732
        self.doMerge(['aaa', 'bbb', 'ccc'],
 
733
                     ['aaa', 'xxx', 'bbb', 'ccc'],
 
734
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'],
 
735
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'])
 
736
 
 
737
    def testOverlappedInsert(self):
 
738
        self.doMerge(['aaa', 'bbb'],
 
739
                     ['aaa', 'xxx', 'yyy', 'bbb'],
 
740
                     ['aaa', 'xxx', 'bbb'],
 
741
                     ['aaa', '<<<<', 'xxx', 'yyy', '====', 'xxx', '>>>>', 'bbb'])
 
742
 
 
743
        # really it ought to reduce this to 
 
744
        # ['aaa', 'xxx', 'yyy', 'bbb']
 
745
 
 
746
 
 
747
    def testClashReplace(self):
 
748
        self.doMerge(['aaa'],
 
749
                     ['xxx'],
 
750
                     ['yyy', 'zzz'],
 
751
                     ['<<<<', 'xxx', '====', 'yyy', 'zzz', '>>>>'])
 
752
 
 
753
    def testNonClashInsert(self):
 
754
        self.doMerge(['aaa'],
 
755
                     ['xxx', 'aaa'],
 
756
                     ['yyy', 'zzz'],
 
757
                     ['<<<<', 'xxx', 'aaa', '====', 'yyy', 'zzz', '>>>>'])
 
758
 
 
759
        self.doMerge(['aaa'],
 
760
                     ['aaa'],
 
761
                     ['yyy', 'zzz'],
 
762
                     ['yyy', 'zzz'])
 
763
    
 
764
 
 
765
 
 
766
def testweave():
 
767
    import testsweet
 
768
    from unittest import TestSuite, TestLoader
 
769
    import testweave
 
770
 
 
771
    tl = TestLoader()
 
772
    suite = TestSuite()
 
773
    suite.addTest(tl.loadTestsFromModule(testweave))
 
774
    
 
775
    return int(not testsweet.run_suite(suite)) # for shell 0=true
 
776
 
 
777
 
 
778
if __name__ == '__main__':
 
779
    import sys
 
780
    sys.exit(testweave())
 
781