~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to tools/testweave.py

  • Committer: Martin Pool
  • Date: 2005-06-28 05:33:40 UTC
  • Revision ID: mbp@sourcefrog.net-20050628053340-ea73b03fbcde9c46
- Remove XMLMixin class in favour of simple pack_xml, unpack_xml functions
  called as needed.  

- Avoid importing xml and ElementTree library unless needed.

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