~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to tools/testweave.py

  • Committer: Aaron Bentley
  • Date: 2005-08-26 16:58:52 UTC
  • mto: (1185.3.4)
  • mto: This revision was merged to the branch mainline in revision 1178.
  • Revision ID: abentley@panoramicfeedback.com-20050826165852-470d0fd6768a17ab
TEST NEEDED: fixed fetch when same revision is added twice to new_missing

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 bzrlib.weave import Weave, WeaveFormatError
 
27
from bzrlib.weavefile import write_weave, read_weave
26
28
from pprint import pformat
27
29
 
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
 
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
60
            tf.seek(0)
54
61
            self.log('serialized weave:')
55
62
            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
63
            self.fail('read/write check failed')
65
64
        
66
65
        
75
74
    """Store and retrieve a simple text."""
76
75
    def runTest(self):
77
76
        k = Weave()
78
 
        idx = k.add('text0', [], TEXT_0)
 
77
        idx = k.add([], TEXT_0)
79
78
        self.assertEqual(k.get(idx), TEXT_0)
80
79
        self.assertEqual(idx, 0)
81
80
 
84
83
class AnnotateOne(TestBase):
85
84
    def runTest(self):
86
85
        k = Weave()
87
 
        k.add('text0', [], TEXT_0)
 
86
        k.add([], TEXT_0)
88
87
        self.assertEqual(k.annotate(0),
89
88
                         [(0, TEXT_0[0])])
90
89
 
93
92
    def runTest(self):
94
93
        k = Weave()
95
94
 
96
 
        idx = k.add('text0', [], TEXT_0)
 
95
        idx = k.add([], TEXT_0)
97
96
        self.assertEqual(idx, 0)
98
97
 
99
 
        idx = k.add('text1', [], TEXT_1)
 
98
        idx = k.add([], TEXT_1)
100
99
        self.assertEqual(idx, 1)
101
100
 
102
101
        self.assertEqual(k.get(0), TEXT_0)
103
102
        self.assertEqual(k.get(1), TEXT_1)
104
103
 
105
 
 
106
 
 
107
 
class AddWithGivenSha(TestBase):
108
 
    def runTest(self):
109
 
        """Add with caller-supplied SHA-1"""
110
 
        k = Weave()
111
 
 
112
 
        t = 'text0'
113
 
        k.add('text0', [], [t], sha1=sha_string(t))
 
104
        k.dump(self.TEST_LOG)
114
105
 
115
106
 
116
107
 
121
112
 
122
113
        self.assertRaises(IndexError,
123
114
                          k.add,
124
 
                          'text0',
125
115
                          [69],
126
116
                          ['new text!'])
127
117
 
128
118
 
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
119
class InsertLines(TestBase):
157
120
    """Store a revision that adds one line to the original.
158
121
 
161
124
    def runTest(self):
162
125
        k = Weave()
163
126
 
164
 
        k.add('text0', [], ['line 1'])
165
 
        k.add('text1', [0], ['line 1', 'line 2'])
 
127
        k.add([], ['line 1'])
 
128
        k.add([0], ['line 1', 'line 2'])
166
129
 
167
130
        self.assertEqual(k.annotate(0),
168
131
                         [(0, 'line 1')])
175
138
                         [(0, 'line 1'),
176
139
                          (1, 'line 2')])
177
140
 
178
 
        k.add('text2', [0], ['line 1', 'diverged line'])
 
141
        k.add([0], ['line 1', 'diverged line'])
179
142
 
180
143
        self.assertEqual(k.annotate(2),
181
144
                         [(0, 'line 1'),
182
145
                          (2, 'diverged line')])
183
146
 
184
147
        text3 = ['line 1', 'middle line', 'line 2']
185
 
        k.add('text3',
186
 
              [0, 1],
 
148
        k.add([0, 1],
187
149
              text3)
188
150
 
189
151
        # self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]), text3))))
196
158
                          (1, 'line 2')])
197
159
 
198
160
        # now multiple insertions at different places
199
 
        k.add('text4',
200
 
              [0, 1, 3],
 
161
        k.add([0, 1, 3],
201
162
              ['line 1', 'aaa', 'middle line', 'bbb', 'line 2', 'ccc'])
202
163
 
203
164
        self.assertEqual(k.annotate(4), 
219
180
 
220
181
        base_text = ['one', 'two', 'three', 'four']
221
182
 
222
 
        k.add('text0', [], base_text)
 
183
        k.add([], base_text)
223
184
        
224
185
        texts = [['one', 'two', 'three'],
225
186
                 ['two', 'three', 'four'],
227
188
                 ['one', 'two', 'three', 'four'],
228
189
                 ]
229
190
 
230
 
        i = 1
231
191
        for t in texts:
232
 
            ver = k.add('text%d' % i,
233
 
                        [0], t)
234
 
            i += 1
 
192
            ver = k.add([0], t)
235
193
 
236
194
        self.log('final weave:')
237
195
        self.log('k._weave=' + pformat(k._weave))
448
406
    def runTest(self):
449
407
        k = Weave()
450
408
 
451
 
        k.add('text0', [], ["line the first",
 
409
        k.add([], ["line the first",
452
410
                   "line 2",
453
411
                   "line 3",
454
412
                   "fine"])
455
413
 
456
414
        self.assertEqual(len(k.get(0)), 4)
457
415
 
458
 
        k.add('text1', [0], ["line the first",
 
416
        k.add([0], ["line the first",
459
417
                   "fine"])
460
418
 
461
419
        self.assertEqual(k.get(1),
496
454
        self.assertEqual(k.get(0),
497
455
                         ["first line"])
498
456
 
 
457
        k.dump(self.TEST_LOG)
 
458
 
499
459
 
500
460
class DivergedIncludes(TestBase):
501
461
    """Weave with two diverged texts based on version 0.
541
501
        text0 = ['cheddar', 'stilton', 'gruyere']
542
502
        text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
543
503
        
544
 
        k.add('text0', [], text0)
545
 
        k.add('text1', [0], text1)
 
504
        k.add([], text0)
 
505
        k.add([0], text1)
546
506
 
547
507
        self.log('k._weave=' + pformat(k._weave))
548
508
 
562
522
                 ['header', '', 'line from 1', 'fixup line', 'line from 2'],
563
523
                 ]
564
524
 
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])
 
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])
569
529
 
570
530
        for i, t in enumerate(texts):
571
531
            self.assertEqual(k.get(i), t)
633
593
                 ['header', 'aaa', 'bbb', 'line from 2', 'more from 2'],
634
594
                 ]
635
595
 
636
 
        k.add('text0', [], texts[0])
637
 
        k.add('text1', [0], texts[1])
638
 
        k.add('text2', [0], texts[2])
 
596
        k.add([], texts[0])
 
597
        k.add([0], texts[1])
 
598
        k.add([0], texts[2])
639
599
 
640
600
        self.log('k._weave=' + pformat(k._weave))
641
601
 
681
641
 
682
642
        k = Weave()
683
643
        parents = set()
684
 
        i = 0
685
644
        for t in texts:
686
 
            ver = k.add('text%d' % i,
687
 
                        list(parents), t)
 
645
            ver = k.add(list(parents), t)
688
646
            parents.add(ver)
689
 
            i += 1
690
647
 
691
648
        self.log("k._weave=" + pformat(k._weave))
692
649
 
706
663
            return x + '\n'
707
664
        
708
665
        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))
 
666
        w.add([], map(addcrlf, base))
 
667
        w.add([0], map(addcrlf, a))
 
668
        w.add([0], map(addcrlf, b))
712
669
 
713
670
        self.log('weave is:')
714
671
        tmpf = StringIO()
792
749
                     ['aaa', 'ddd', 'ccc'],
793
750
                     ['aaa', 'ccc'],
794
751
                     ['<<<<', '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)
 
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
915
765
 
916
766
 
917
767
if __name__ == '__main__':
918
768
    import sys
919
 
    import unittest
920
 
    sys.exit(unittest.main())
 
769
    sys.exit(testweave())
921
770