~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to testweave.py

  • Committer: Martin Pool
  • Date: 2005-06-30 10:00:57 UTC
  • mto: This revision was merged to the branch mainline in revision 852.
  • Revision ID: mbp@sourcefrog.net-20050630100057-32a93074b0f1faa8
doc

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
 
19
19
 
20
 
# TODO: tests regarding version names
21
 
# TODO: rbc 20050108 test that join does not leave an inconsistent weave 
22
 
#       if it fails.
 
20
 
23
21
 
24
22
"""test suite for weave algorithm"""
25
23
 
 
24
 
 
25
import testsweet
 
26
from weave import Weave, WeaveFormatError
26
27
from pprint import pformat
27
28
 
28
 
import bzrlib.errors as errors
29
 
from bzrlib.weave import Weave, WeaveFormatError, WeaveError, reweave
30
 
from bzrlib.weavefile import write_weave, read_weave
31
 
from bzrlib.selftest import TestCase
32
 
from bzrlib.osutils import sha_string
 
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
 
33
40
 
34
41
 
35
42
# texts for use in testing
39
46
 
40
47
 
41
48
 
42
 
class TestBase(TestCase):
 
49
class TestBase(testsweet.TestBase):
43
50
    def check_read_write(self, k):
44
51
        """Check the weave k can be written & re-read."""
45
52
        from tempfile import TemporaryFile
 
53
        from weavefile import write_weave, read_weave
46
54
        tf = TemporaryFile()
47
55
 
48
56
        write_weave(k, tf)
53
61
            tf.seek(0)
54
62
            self.log('serialized weave:')
55
63
            self.log(tf.read())
56
 
 
57
 
            self.log('')
58
 
            self.log('parents: %s' % (k._parents == k2._parents))
59
 
            self.log('         %r' % k._parents)
60
 
            self.log('         %r' % k2._parents)
61
 
            self.log('')
62
 
 
63
 
            
64
64
            self.fail('read/write check failed')
65
65
        
66
66
        
75
75
    """Store and retrieve a simple text."""
76
76
    def runTest(self):
77
77
        k = Weave()
78
 
        idx = k.add('text0', [], TEXT_0)
 
78
        idx = k.add([], TEXT_0)
79
79
        self.assertEqual(k.get(idx), TEXT_0)
80
80
        self.assertEqual(idx, 0)
81
81
 
84
84
class AnnotateOne(TestBase):
85
85
    def runTest(self):
86
86
        k = Weave()
87
 
        k.add('text0', [], TEXT_0)
 
87
        k.add([], TEXT_0)
88
88
        self.assertEqual(k.annotate(0),
89
89
                         [(0, TEXT_0[0])])
90
90
 
93
93
    def runTest(self):
94
94
        k = Weave()
95
95
 
96
 
        idx = k.add('text0', [], TEXT_0)
 
96
        idx = k.add([], TEXT_0)
97
97
        self.assertEqual(idx, 0)
98
98
 
99
 
        idx = k.add('text1', [], TEXT_1)
 
99
        idx = k.add([], TEXT_1)
100
100
        self.assertEqual(idx, 1)
101
101
 
102
102
        self.assertEqual(k.get(0), TEXT_0)
103
103
        self.assertEqual(k.get(1), TEXT_1)
104
104
 
105
 
 
106
 
 
107
 
class AddWithGivenSha(TestBase):
 
105
        k.dump(self.TEST_LOG)
 
106
 
 
107
 
 
108
 
 
109
class DeltaAdd(TestBase):
 
110
    """Detection of changes prior to inserting new revision."""
108
111
    def runTest(self):
109
 
        """Add with caller-supplied SHA-1"""
110
112
        k = Weave()
111
 
 
112
 
        t = 'text0'
113
 
        k.add('text0', [], [t], sha1=sha_string(t))
114
 
 
 
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)
115
139
 
116
140
 
117
141
class InvalidAdd(TestBase):
121
145
 
122
146
        self.assertRaises(IndexError,
123
147
                          k.add,
124
 
                          'text0',
125
148
                          [69],
126
149
                          ['new text!'])
127
150
 
128
151
 
129
 
class RepeatedAdd(TestBase):
130
 
    """Add the same version twice; harmless."""
131
 
    def runTest(self):
132
 
        k = Weave()
133
 
        idx = k.add('text0', [], TEXT_0)
134
 
        idx2 = k.add('text0', [], TEXT_0)
135
 
        self.assertEqual(idx, idx2)
136
 
 
137
 
 
138
 
 
139
 
class InvalidRepeatedAdd(TestBase):
140
 
    def runTest(self):
141
 
        k = Weave()
142
 
        idx = k.add('text0', [], TEXT_0)
143
 
        self.assertRaises(WeaveError,
144
 
                          k.add,
145
 
                          'text0',
146
 
                          [],
147
 
                          ['not the same text'])
148
 
        self.assertRaises(WeaveError,
149
 
                          k.add,
150
 
                          'text0',
151
 
                          [12],         # not the right parents
152
 
                          TEXT_0)
153
 
        
154
 
 
155
 
 
156
152
class InsertLines(TestBase):
157
153
    """Store a revision that adds one line to the original.
158
154
 
161
157
    def runTest(self):
162
158
        k = Weave()
163
159
 
164
 
        k.add('text0', [], ['line 1'])
165
 
        k.add('text1', [0], ['line 1', 'line 2'])
 
160
        k.add([], ['line 1'])
 
161
        k.add([0], ['line 1', 'line 2'])
166
162
 
167
163
        self.assertEqual(k.annotate(0),
168
164
                         [(0, 'line 1')])
175
171
                         [(0, 'line 1'),
176
172
                          (1, 'line 2')])
177
173
 
178
 
        k.add('text2', [0], ['line 1', 'diverged line'])
 
174
        k.add([0], ['line 1', 'diverged line'])
179
175
 
180
176
        self.assertEqual(k.annotate(2),
181
177
                         [(0, 'line 1'),
182
178
                          (2, 'diverged line')])
183
179
 
184
180
        text3 = ['line 1', 'middle line', 'line 2']
185
 
        k.add('text3',
186
 
              [0, 1],
 
181
        k.add([0, 1],
187
182
              text3)
188
183
 
189
 
        # self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]), text3))))
 
184
        self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]), text3))))
190
185
 
191
 
        self.log("k._weave=" + pformat(k._weave))
 
186
        self.log("k._l=" + pformat(k._l))
192
187
 
193
188
        self.assertEqual(k.annotate(3),
194
189
                         [(0, 'line 1'),
196
191
                          (1, 'line 2')])
197
192
 
198
193
        # now multiple insertions at different places
199
 
        k.add('text4',
200
 
              [0, 1, 3],
 
194
        k.add([0, 1, 3],
201
195
              ['line 1', 'aaa', 'middle line', 'bbb', 'line 2', 'ccc'])
202
196
 
203
197
        self.assertEqual(k.annotate(4), 
219
213
 
220
214
        base_text = ['one', 'two', 'three', 'four']
221
215
 
222
 
        k.add('text0', [], base_text)
 
216
        k.add([], base_text)
223
217
        
224
218
        texts = [['one', 'two', 'three'],
225
219
                 ['two', 'three', 'four'],
227
221
                 ['one', 'two', 'three', 'four'],
228
222
                 ]
229
223
 
230
 
        i = 1
231
224
        for t in texts:
232
 
            ver = k.add('text%d' % i,
233
 
                        [0], t)
234
 
            i += 1
 
225
            ver = k.add([0], t)
235
226
 
236
227
        self.log('final weave:')
237
 
        self.log('k._weave=' + pformat(k._weave))
 
228
        self.log('k._l=' + pformat(k._l))
238
229
 
239
230
        for i in range(len(texts)):
240
231
            self.assertEqual(k.get(i+1),
248
239
    def runTest(self):
249
240
        k = Weave()
250
241
 
251
 
        k._parents = [(),
 
242
        k._v = [(),
252
243
                ]
253
 
        k._weave = [('{', 0),
 
244
        k._l = [('{', 0),
254
245
                'first line',
255
246
                ('[', 0),
256
247
                'deleted in 0',
257
248
                (']', 0),
258
249
                ('}', 0),
259
250
                ]
260
 
        ################################### SKIPPED
261
 
        # Weave.get doesn't trap this anymore
262
 
        return 
263
251
 
264
252
        self.assertRaises(WeaveFormatError,
265
253
                          k.get,
272
260
    def runTest(self):
273
261
        k = Weave()
274
262
 
275
 
        k._parents = [(),
 
263
        k._v = [(),
276
264
                frozenset([0]),
277
265
                ]
278
 
        k._weave = [('{', 0),
 
266
        k._l = [('{', 0),
279
267
                'first line',
280
268
                ('[', 1),
281
269
                'line to be deleted',
302
290
    def runTest(self):
303
291
        k = Weave()
304
292
 
305
 
        k._parents = [frozenset(),
 
293
        k._v = [frozenset(),
306
294
                frozenset([0]),
307
295
                ]
308
 
        k._weave = [('{', 0),
 
296
        k._l = [('{', 0),
309
297
                'first line',
310
298
                ('[', 1),
311
299
                'line to be deleted',
336
324
    def runTest(self):
337
325
        k = Weave()
338
326
 
339
 
        k._parents = [frozenset(),
 
327
        k._v = [frozenset(),
340
328
                ]
341
 
        k._weave = ['bad line',
 
329
        k._l = ['bad line',
342
330
                ('{', 0),
343
331
                'foo {',
344
332
                ('{', 1),
351
339
                '}',
352
340
                ('}', 0)]
353
341
 
354
 
        ################################### SKIPPED
355
 
        # Weave.get doesn't trap this anymore
356
 
        return 
357
 
 
358
 
 
359
342
        self.assertRaises(WeaveFormatError,
360
343
                          k.get,
361
344
                          0)
366
349
    def runTest(self):
367
350
        k = Weave()
368
351
 
369
 
        k._parents = [frozenset(),
 
352
        k._v = [frozenset(),
370
353
                frozenset([0]),
371
354
                frozenset([0]),
372
355
                frozenset([0,1,2]),
373
356
                ]
374
 
        k._weave = [('{', 0),
 
357
        k._l = [('{', 0),
375
358
                'foo {',
376
359
                ('{', 1),
377
360
                '  added in version 1',
381
364
                ('}', 1),
382
365
                ('}', 0)]
383
366
 
384
 
 
385
 
        # this is not currently enforced by get
386
 
        return  ##########################################
387
 
 
388
367
        self.assertRaises(WeaveFormatError,
389
368
                          k.get,
390
369
                          0)
399
378
    def runTest(self):
400
379
        k = Weave()
401
380
 
402
 
        k._parents = [frozenset(),
 
381
        k._v = [frozenset(),
403
382
                frozenset([0]),
404
383
                frozenset([0]),
405
384
                frozenset([0,1,2]),
406
385
                ]
407
 
        k._weave = [('{', 0),
 
386
        k._l = [('{', 0),
408
387
                'foo {',
409
388
                ('{', 1),
410
389
                '  added in version 1',
448
427
    def runTest(self):
449
428
        k = Weave()
450
429
 
451
 
        k.add('text0', [], ["line the first",
 
430
        k.add([], ["line the first",
452
431
                   "line 2",
453
432
                   "line 3",
454
433
                   "fine"])
455
434
 
456
435
        self.assertEqual(len(k.get(0)), 4)
457
436
 
458
 
        k.add('text1', [0], ["line the first",
 
437
        k.add([0], ["line the first",
459
438
                   "fine"])
460
439
 
461
440
        self.assertEqual(k.get(1),
481
460
    def runTest(self):
482
461
        k = Weave()
483
462
 
484
 
        k._parents = [frozenset(), frozenset([0])]
485
 
        k._weave = [('{', 0),
 
463
        k._v = [frozenset(), frozenset([0])]
 
464
        k._l = [('{', 0),
486
465
                "first line",
487
466
                ('}', 0),
488
467
                ('{', 1),
496
475
        self.assertEqual(k.get(0),
497
476
                         ["first line"])
498
477
 
 
478
        k.dump(self.TEST_LOG)
 
479
 
499
480
 
500
481
class DivergedIncludes(TestBase):
501
482
    """Weave with two diverged texts based on version 0.
503
484
    def runTest(self):
504
485
        k = Weave()
505
486
 
506
 
        k._parents = [frozenset(),
 
487
        k._v = [frozenset(),
507
488
                frozenset([0]),
508
489
                frozenset([0]),
509
490
                ]
510
 
        k._weave = [('{', 0),
 
491
        k._l = [('{', 0),
511
492
                "first line",
512
493
                ('}', 0),
513
494
                ('{', 1),
529
510
                         ["first line",
530
511
                          "alternative second line"])
531
512
 
532
 
        self.assertEqual(list(k.inclusions([2])),
533
 
                         [0, 2])
 
513
        self.assertEqual(k.inclusions([2]),
 
514
                         set([0, 2]))
534
515
 
535
516
 
536
517
 
541
522
        text0 = ['cheddar', 'stilton', 'gruyere']
542
523
        text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
543
524
        
544
 
        k.add('text0', [], text0)
545
 
        k.add('text1', [0], text1)
 
525
        k.add([], text0)
 
526
        k.add([0], text1)
546
527
 
547
 
        self.log('k._weave=' + pformat(k._weave))
 
528
        self.log('k._l=' + pformat(k._l))
548
529
 
549
530
        self.assertEqual(k.get(0), text0)
550
531
        self.assertEqual(k.get(1), text1)
552
533
 
553
534
 
554
535
class Merge(TestBase):
555
 
    """Storage of versions that merge diverged parents"""
 
536
    """Versions that merge diverged parents"""
556
537
    def runTest(self):
557
538
        k = Weave()
558
539
 
562
543
                 ['header', '', 'line from 1', 'fixup line', 'line from 2'],
563
544
                 ]
564
545
 
565
 
        k.add('text0', [], texts[0])
566
 
        k.add('text1', [0], texts[1])
567
 
        k.add('text2', [0], texts[2])
568
 
        k.add('merge', [0, 1, 2], texts[3])
 
546
        k.add([], texts[0])
 
547
        k.add([0], texts[1])
 
548
        k.add([0], texts[2])
 
549
        k.add([0, 1, 2], texts[3])
569
550
 
570
551
        for i, t in enumerate(texts):
571
552
            self.assertEqual(k.get(i), t)
578
559
                          (2, 'line from 2'),
579
560
                          ])
580
561
 
581
 
        self.assertEqual(list(k.inclusions([3])),
582
 
                         [0, 1, 2, 3])
 
562
        self.assertEqual(k.inclusions([3]),
 
563
                         set([0, 1, 2, 3]))
583
564
 
584
 
        self.log('k._weave=' + pformat(k._weave))
 
565
        self.log('k._l=' + pformat(k._l))
585
566
 
586
567
        self.check_read_write(k)
587
568
 
588
569
 
589
 
class Conflicts(TestBase):
590
 
    """Test detection of conflicting regions during a merge.
591
 
 
592
 
    A base version is inserted, then two descendents try to
593
 
    insert different lines in the same place.  These should be
594
 
    reported as a possible conflict and forwarded to the user."""
595
 
    def runTest(self):
596
 
        return  # NOT RUN
597
 
        k = Weave()
598
 
 
599
 
        k.add([], ['aaa', 'bbb'])
600
 
        k.add([0], ['aaa', '111', 'bbb'])
601
 
        k.add([1], ['aaa', '222', 'bbb'])
602
 
 
603
 
        merged = k.merge([1, 2])
604
 
 
605
 
        self.assertEquals([[['aaa']],
606
 
                           [['111'], ['222']],
607
 
                           [['bbb']]])
608
 
 
609
 
 
610
 
 
611
 
class NonConflict(TestBase):
612
 
    """Two descendants insert compatible changes.
613
 
 
614
 
    No conflict should be reported."""
615
 
    def runTest(self):
616
 
        return  # NOT RUN
617
 
        k = Weave()
618
 
 
619
 
        k.add([], ['aaa', 'bbb'])
620
 
        k.add([0], ['111', 'aaa', 'ccc', 'bbb'])
621
 
        k.add([1], ['aaa', 'ccc', 'bbb', '222'])
622
 
 
623
 
    
624
 
    
625
 
 
626
 
 
627
570
class AutoMerge(TestBase):
628
571
    def runTest(self):
629
572
        k = Weave()
633
576
                 ['header', 'aaa', 'bbb', 'line from 2', 'more from 2'],
634
577
                 ]
635
578
 
636
 
        k.add('text0', [], texts[0])
637
 
        k.add('text1', [0], texts[1])
638
 
        k.add('text2', [0], texts[2])
639
 
 
640
 
        self.log('k._weave=' + pformat(k._weave))
641
 
 
642
 
        m = list(k.mash_iter([0, 1, 2]))
 
579
        k.add([], texts[0])
 
580
        k.add([0], texts[1])
 
581
        k.add([0], texts[2])
 
582
 
 
583
        self.log('k._l=' + pformat(k._l))
 
584
 
 
585
        m = list(k.merge_iter([0, 1, 2]))
643
586
 
644
587
        self.assertEqual(m,
645
588
                         ['header', 'aaa',
681
624
 
682
625
        k = Weave()
683
626
        parents = set()
684
 
        i = 0
685
627
        for t in texts:
686
 
            ver = k.add('text%d' % i,
687
 
                        list(parents), t)
 
628
            ver = k.add(list(parents), t)
688
629
            parents.add(ver)
689
 
            i += 1
690
630
 
691
 
        self.log("k._weave=" + pformat(k._weave))
 
631
        self.log("k._l=" + pformat(k._l))
692
632
 
693
633
        for i, t in enumerate(texts):
694
634
            self.assertEqual(k.get(i), t)
696
636
        self.check_read_write(k)
697
637
 
698
638
 
699
 
 
700
 
class MergeCases(TestBase):
701
 
    def doMerge(self, base, a, b, mp):
702
 
        from cStringIO import StringIO
703
 
        from textwrap import dedent
704
 
 
705
 
        def addcrlf(x):
706
 
            return x + '\n'
707
 
        
708
 
        w = Weave()
709
 
        w.add('text0', [], map(addcrlf, base))
710
 
        w.add('text1', [0], map(addcrlf, a))
711
 
        w.add('text2', [0], map(addcrlf, b))
712
 
 
713
 
        self.log('weave is:')
714
 
        tmpf = StringIO()
715
 
        write_weave(w, tmpf)
716
 
        self.log(tmpf.getvalue())
717
 
 
718
 
        self.log('merge plan:')
719
 
        p = list(w.plan_merge(1, 2))
720
 
        for state, line in p:
721
 
            if line:
722
 
                self.log('%12s | %s' % (state, line[:-1]))
723
 
 
724
 
        self.log('merge:')
725
 
        mt = StringIO()
726
 
        mt.writelines(w.weave_merge(p))
727
 
        mt.seek(0)
728
 
        self.log(mt.getvalue())
729
 
 
730
 
        mp = map(addcrlf, mp)
731
 
        self.assertEqual(mt.readlines(), mp)
732
 
        
733
 
        
734
 
    def testOneInsert(self):
735
 
        self.doMerge([],
736
 
                     ['aa'],
737
 
                     [],
738
 
                     ['aa'])
739
 
 
740
 
    def testSeparateInserts(self):
741
 
        self.doMerge(['aaa', 'bbb', 'ccc'],
742
 
                     ['aaa', 'xxx', 'bbb', 'ccc'],
743
 
                     ['aaa', 'bbb', 'yyy', 'ccc'],
744
 
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'])
745
 
 
746
 
    def testSameInsert(self):
747
 
        self.doMerge(['aaa', 'bbb', 'ccc'],
748
 
                     ['aaa', 'xxx', 'bbb', 'ccc'],
749
 
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'],
750
 
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'])
751
 
 
752
 
    def testOverlappedInsert(self):
753
 
        self.doMerge(['aaa', 'bbb'],
754
 
                     ['aaa', 'xxx', 'yyy', 'bbb'],
755
 
                     ['aaa', 'xxx', 'bbb'],
756
 
                     ['aaa', '<<<<', 'xxx', 'yyy', '====', 'xxx', '>>>>', 'bbb'])
757
 
 
758
 
        # really it ought to reduce this to 
759
 
        # ['aaa', 'xxx', 'yyy', 'bbb']
760
 
 
761
 
 
762
 
    def testClashReplace(self):
763
 
        self.doMerge(['aaa'],
764
 
                     ['xxx'],
765
 
                     ['yyy', 'zzz'],
766
 
                     ['<<<<', 'xxx', '====', 'yyy', 'zzz', '>>>>'])
767
 
 
768
 
    def testNonClashInsert(self):
769
 
        self.doMerge(['aaa'],
770
 
                     ['xxx', 'aaa'],
771
 
                     ['yyy', 'zzz'],
772
 
                     ['<<<<', 'xxx', 'aaa', '====', 'yyy', 'zzz', '>>>>'])
773
 
 
774
 
        self.doMerge(['aaa'],
775
 
                     ['aaa'],
776
 
                     ['yyy', 'zzz'],
777
 
                     ['yyy', 'zzz'])
778
 
 
779
 
 
780
 
    def testDeleteAndModify(self):
781
 
        """Clashing delete and modification.
782
 
 
783
 
        If one side modifies a region and the other deletes it then
784
 
        there should be a conflict with one side blank.
785
 
        """
786
 
 
787
 
        #######################################
788
 
        # skippd, not working yet
789
 
        return
790
 
        
791
 
        self.doMerge(['aaa', 'bbb', 'ccc'],
792
 
                     ['aaa', 'ddd', 'ccc'],
793
 
                     ['aaa', 'ccc'],
794
 
                     ['<<<<', 'aaa', '====', '>>>>', 'ccc'])
795
 
 
796
 
 
797
 
class JoinWeavesTests(TestBase):
798
 
    def setUp(self):
799
 
        super(JoinWeavesTests, self).setUp()
800
 
        self.weave1 = Weave()
801
 
        self.lines1 = ['hello\n']
802
 
        self.lines3 = ['hello\n', 'cruel\n', 'world\n']
803
 
        self.weave1.add('v1', [], self.lines1)
804
 
        self.weave1.add('v2', [0], ['hello\n', 'world\n'])
805
 
        self.weave1.add('v3', [1], self.lines3)
806
 
        
807
 
    def test_join_empty(self):
808
 
        """Join two empty weaves."""
809
 
        eq = self.assertEqual
810
 
        w1 = Weave()
811
 
        w2 = Weave()
812
 
        w1.join(w2)
813
 
        eq(w1.numversions(), 0)
814
 
        
815
 
    def test_join_empty_to_nonempty(self):
816
 
        """Join empty weave onto nonempty."""
817
 
        self.weave1.join(Weave())
818
 
        self.assertEqual(len(self.weave1), 3)
819
 
 
820
 
    def test_join_unrelated(self):
821
 
        """Join two weaves with no history in common."""
822
 
        wb = Weave()
823
 
        wb.add('b1', [], ['line from b\n'])
824
 
        w1 = self.weave1
825
 
        w1.join(wb)
826
 
        eq = self.assertEqual
827
 
        eq(len(w1), 4)
828
 
        eq(sorted(list(w1.iter_names())),
829
 
           ['b1', 'v1', 'v2', 'v3'])
830
 
 
831
 
    def test_join_related(self):
832
 
        wa = self.weave1.copy()
833
 
        wb = self.weave1.copy()
834
 
        wa.add('a1', ['v3'], ['hello\n', 'sweet\n', 'world\n'])
835
 
        wb.add('b1', ['v3'], ['hello\n', 'pale blue\n', 'world\n'])
836
 
        eq = self.assertEquals
837
 
        eq(len(wa), 4)
838
 
        eq(len(wb), 4)
839
 
        wa.join(wb)
840
 
        eq(len(wa), 5)
841
 
        eq(wa.get_lines('b1'),
842
 
           ['hello\n', 'pale blue\n', 'world\n'])
843
 
 
844
 
    def test_join_parent_disagreement(self):
845
 
        """Cannot join weaves with different parents for a version."""
846
 
        wa = Weave()
847
 
        wb = Weave()
848
 
        wa.add('v1', [], ['hello\n'])
849
 
        wb.add('v0', [], [])
850
 
        wb.add('v1', ['v0'], ['hello\n'])
851
 
        self.assertRaises(WeaveError,
852
 
                          wa.join, wb)
853
 
 
854
 
    def test_join_text_disagreement(self):
855
 
        """Cannot join weaves with different texts for a version."""
856
 
        wa = Weave()
857
 
        wb = Weave()
858
 
        wa.add('v1', [], ['hello\n'])
859
 
        wb.add('v1', [], ['not\n', 'hello\n'])
860
 
        self.assertRaises(WeaveError,
861
 
                          wa.join, wb)
862
 
 
863
 
    def test_join_unordered(self):
864
 
        """Join weaves where indexes differ.
865
 
        
866
 
        The source weave contains a different version at index 0."""
867
 
        wa = self.weave1.copy()
868
 
        wb = Weave()
869
 
        wb.add('x1', [], ['line from x1\n'])
870
 
        wb.add('v1', [], ['hello\n'])
871
 
        wb.add('v2', ['v1'], ['hello\n', 'world\n'])
872
 
        wa.join(wb)
873
 
        eq = self.assertEquals
874
 
        eq(sorted(wa.iter_names()), ['v1', 'v2', 'v3', 'x1',])
875
 
        eq(wa.get_text('x1'), 'line from x1\n')
876
 
 
877
 
    def test_reweave_with_empty(self):
878
 
        wb = Weave()
879
 
        wr = reweave(self.weave1, wb)
880
 
        eq = self.assertEquals
881
 
        eq(sorted(wr.iter_names()), ['v1', 'v2', 'v3'])
882
 
        eq(wr.get_lines('v3'), ['hello\n', 'cruel\n', 'world\n'])
883
 
        self.weave1.reweave(wb)
884
 
        self.assertEquals(wr, self.weave1)
885
 
 
886
 
    def test_join_with_ghosts_raises_parent_mismatch(self):
887
 
        wa = self.weave1.copy()
888
 
        wb = Weave()
889
 
        wb.add('x1', [], ['line from x1\n'])
890
 
        wb.add('v1', [], ['hello\n'])
891
 
        wb.add('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
892
 
        self.assertRaises(errors.WeaveParentMismatch, wa.join, wb)
893
 
 
894
 
    def test_reweave_with_ghosts(self):
895
 
        """Join that inserts parents of an existing revision.
896
 
 
897
 
        This can happen when merging from another branch who
898
 
        knows about revisions the destination does not.  In 
899
 
        this test the second weave knows of an additional parent of 
900
 
        v2.  Any revisions which are in common still have to have the 
901
 
        same text."""
902
 
        wa = self.weave1.copy()
903
 
        wb = Weave()
904
 
        wb.add('x1', [], ['line from x1\n'])
905
 
        wb.add('v1', [], ['hello\n'])
906
 
        wb.add('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
907
 
        wc = reweave(wa, wb)
908
 
        eq = self.assertEquals
909
 
        eq(sorted(wc.iter_names()), ['v1', 'v2', 'v3', 'x1',])
910
 
        eq(wc.get_text('x1'), 'line from x1\n')
911
 
        eq(wc.get_lines('v2'), ['hello\n', 'world\n'])
912
 
        eq(wc.parent_names('v2'), ['v1', 'x1'])
913
 
        self.weave1.reweave(wb)
914
 
        self.assertEquals(wc, self.weave1)
 
639
def testweave():
 
640
    import testsweet
 
641
    from unittest import TestSuite, TestLoader
 
642
    import testweave
 
643
 
 
644
    tl = TestLoader()
 
645
    suite = TestSuite()
 
646
    suite.addTest(tl.loadTestsFromModule(testweave))
 
647
    
 
648
    return int(not testsweet.run_suite(suite)) # for shell 0=true
915
649
 
916
650
 
917
651
if __name__ == '__main__':
918
652
    import sys
919
 
    import unittest
920
 
    sys.exit(unittest.main())
 
653
    sys.exit(testweave())
921
654