~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_weave.py

  • Committer: Aaron Bentley
  • Date: 2005-11-26 01:23:17 UTC
  • mto: (1185.72.2 bzr.dev)
  • mto: This revision was merged to the branch mainline in revision 1518.
  • Revision ID: aaron.bentley@utoronto.ca-20051126012317-0af7f775be52b3ab
Test case when file to be renamed is also deleted

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
 
 
 
20
# TODO: tests regarding version names
 
21
# TODO: rbc 20050108 test that join does not leave an inconsistent weave 
 
22
#       if it fails.
21
23
 
22
24
"""test suite for weave algorithm"""
23
25
 
 
26
from pprint import pformat
24
27
 
25
 
import testsweet
26
 
from bzrlib.weave import Weave, WeaveFormatError
 
28
import bzrlib.errors as errors
 
29
from bzrlib.weave import Weave, WeaveFormatError, WeaveError, reweave
27
30
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
 
 
 
31
from bzrlib.tests import TestCase
 
32
from bzrlib.osutils import sha_string
40
33
 
41
34
 
42
35
# texts for use in testing
46
39
 
47
40
 
48
41
 
49
 
class TestBase(testsweet.TestBase):
 
42
class TestBase(TestCase):
50
43
    def check_read_write(self, k):
51
44
        """Check the weave k can be written & re-read."""
52
45
        from tempfile import TemporaryFile
60
53
            tf.seek(0)
61
54
            self.log('serialized weave:')
62
55
            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('')
63
62
            self.fail('read/write check failed')
64
 
        
65
 
        
 
63
 
 
64
 
 
65
class WeaveContains(TestBase):
 
66
    """Weave __contains__ operator"""
 
67
    def runTest(self):
 
68
        k = Weave()
 
69
        self.assertFalse('foo' in k)
 
70
        k.add('foo', [], TEXT_1)
 
71
        self.assertTrue('foo' in k)
66
72
 
67
73
 
68
74
class Easy(TestBase):
74
80
    """Store and retrieve a simple text."""
75
81
    def runTest(self):
76
82
        k = Weave()
77
 
        idx = k.add([], TEXT_0)
 
83
        idx = k.add('text0', [], TEXT_0)
78
84
        self.assertEqual(k.get(idx), TEXT_0)
79
85
        self.assertEqual(idx, 0)
80
86
 
83
89
class AnnotateOne(TestBase):
84
90
    def runTest(self):
85
91
        k = Weave()
86
 
        k.add([], TEXT_0)
 
92
        k.add('text0', [], TEXT_0)
87
93
        self.assertEqual(k.annotate(0),
88
94
                         [(0, TEXT_0[0])])
89
95
 
92
98
    def runTest(self):
93
99
        k = Weave()
94
100
 
95
 
        idx = k.add([], TEXT_0)
 
101
        idx = k.add('text0', [], TEXT_0)
96
102
        self.assertEqual(idx, 0)
97
103
 
98
 
        idx = k.add([], TEXT_1)
 
104
        idx = k.add('text1', [], TEXT_1)
99
105
        self.assertEqual(idx, 1)
100
106
 
101
107
        self.assertEqual(k.get(0), TEXT_0)
102
108
        self.assertEqual(k.get(1), TEXT_1)
103
109
 
104
 
        k.dump(self.TEST_LOG)
 
110
 
 
111
 
 
112
class AddWithGivenSha(TestBase):
 
113
    def runTest(self):
 
114
        """Add with caller-supplied SHA-1"""
 
115
        k = Weave()
 
116
 
 
117
        t = 'text0'
 
118
        k.add('text0', [], [t], sha1=sha_string(t))
105
119
 
106
120
 
107
121
 
112
126
 
113
127
        self.assertRaises(IndexError,
114
128
                          k.add,
 
129
                          'text0',
115
130
                          [69],
116
131
                          ['new text!'])
117
132
 
118
133
 
 
134
class RepeatedAdd(TestBase):
 
135
    """Add the same version twice; harmless."""
 
136
    def runTest(self):
 
137
        k = Weave()
 
138
        idx = k.add('text0', [], TEXT_0)
 
139
        idx2 = k.add('text0', [], TEXT_0)
 
140
        self.assertEqual(idx, idx2)
 
141
 
 
142
 
 
143
 
 
144
class InvalidRepeatedAdd(TestBase):
 
145
    def runTest(self):
 
146
        k = Weave()
 
147
        idx = k.add('text0', [], TEXT_0)
 
148
        self.assertRaises(WeaveError,
 
149
                          k.add,
 
150
                          'text0',
 
151
                          [],
 
152
                          ['not the same text'])
 
153
        self.assertRaises(WeaveError,
 
154
                          k.add,
 
155
                          'text0',
 
156
                          [12],         # not the right parents
 
157
                          TEXT_0)
 
158
        
 
159
 
 
160
 
119
161
class InsertLines(TestBase):
120
162
    """Store a revision that adds one line to the original.
121
163
 
124
166
    def runTest(self):
125
167
        k = Weave()
126
168
 
127
 
        k.add([], ['line 1'])
128
 
        k.add([0], ['line 1', 'line 2'])
 
169
        k.add('text0', [], ['line 1'])
 
170
        k.add('text1', [0], ['line 1', 'line 2'])
129
171
 
130
172
        self.assertEqual(k.annotate(0),
131
173
                         [(0, 'line 1')])
138
180
                         [(0, 'line 1'),
139
181
                          (1, 'line 2')])
140
182
 
141
 
        k.add([0], ['line 1', 'diverged line'])
 
183
        k.add('text2', [0], ['line 1', 'diverged line'])
142
184
 
143
185
        self.assertEqual(k.annotate(2),
144
186
                         [(0, 'line 1'),
145
187
                          (2, 'diverged line')])
146
188
 
147
189
        text3 = ['line 1', 'middle line', 'line 2']
148
 
        k.add([0, 1],
 
190
        k.add('text3',
 
191
              [0, 1],
149
192
              text3)
150
193
 
151
194
        # self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]), text3))))
158
201
                          (1, 'line 2')])
159
202
 
160
203
        # now multiple insertions at different places
161
 
        k.add([0, 1, 3],
 
204
        k.add('text4',
 
205
              [0, 1, 3],
162
206
              ['line 1', 'aaa', 'middle line', 'bbb', 'line 2', 'ccc'])
163
207
 
164
208
        self.assertEqual(k.annotate(4), 
180
224
 
181
225
        base_text = ['one', 'two', 'three', 'four']
182
226
 
183
 
        k.add([], base_text)
 
227
        k.add('text0', [], base_text)
184
228
        
185
229
        texts = [['one', 'two', 'three'],
186
230
                 ['two', 'three', 'four'],
188
232
                 ['one', 'two', 'three', 'four'],
189
233
                 ]
190
234
 
 
235
        i = 1
191
236
        for t in texts:
192
 
            ver = k.add([0], t)
 
237
            ver = k.add('text%d' % i,
 
238
                        [0], t)
 
239
            i += 1
193
240
 
194
241
        self.log('final weave:')
195
242
        self.log('k._weave=' + pformat(k._weave))
406
453
    def runTest(self):
407
454
        k = Weave()
408
455
 
409
 
        k.add([], ["line the first",
 
456
        k.add('text0', [], ["line the first",
410
457
                   "line 2",
411
458
                   "line 3",
412
459
                   "fine"])
413
460
 
414
461
        self.assertEqual(len(k.get(0)), 4)
415
462
 
416
 
        k.add([0], ["line the first",
 
463
        k.add('text1', [0], ["line the first",
417
464
                   "fine"])
418
465
 
419
466
        self.assertEqual(k.get(1),
454
501
        self.assertEqual(k.get(0),
455
502
                         ["first line"])
456
503
 
457
 
        k.dump(self.TEST_LOG)
458
 
 
459
504
 
460
505
class DivergedIncludes(TestBase):
461
506
    """Weave with two diverged texts based on version 0.
501
546
        text0 = ['cheddar', 'stilton', 'gruyere']
502
547
        text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
503
548
        
504
 
        k.add([], text0)
505
 
        k.add([0], text1)
 
549
        k.add('text0', [], text0)
 
550
        k.add('text1', [0], text1)
506
551
 
507
552
        self.log('k._weave=' + pformat(k._weave))
508
553
 
522
567
                 ['header', '', 'line from 1', 'fixup line', 'line from 2'],
523
568
                 ]
524
569
 
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])
 
570
        k.add('text0', [], texts[0])
 
571
        k.add('text1', [0], texts[1])
 
572
        k.add('text2', [0], texts[2])
 
573
        k.add('merge', [0, 1, 2], texts[3])
529
574
 
530
575
        for i, t in enumerate(texts):
531
576
            self.assertEqual(k.get(i), t)
593
638
                 ['header', 'aaa', 'bbb', 'line from 2', 'more from 2'],
594
639
                 ]
595
640
 
596
 
        k.add([], texts[0])
597
 
        k.add([0], texts[1])
598
 
        k.add([0], texts[2])
 
641
        k.add('text0', [], texts[0])
 
642
        k.add('text1', [0], texts[1])
 
643
        k.add('text2', [0], texts[2])
599
644
 
600
645
        self.log('k._weave=' + pformat(k._weave))
601
646
 
641
686
 
642
687
        k = Weave()
643
688
        parents = set()
 
689
        i = 0
644
690
        for t in texts:
645
 
            ver = k.add(list(parents), t)
 
691
            ver = k.add('text%d' % i,
 
692
                        list(parents), t)
646
693
            parents.add(ver)
 
694
            i += 1
647
695
 
648
696
        self.log("k._weave=" + pformat(k._weave))
649
697
 
663
711
            return x + '\n'
664
712
        
665
713
        w = Weave()
666
 
        w.add([], map(addcrlf, base))
667
 
        w.add([0], map(addcrlf, a))
668
 
        w.add([0], map(addcrlf, b))
 
714
        w.add('text0', [], map(addcrlf, base))
 
715
        w.add('text1', [0], map(addcrlf, a))
 
716
        w.add('text2', [0], map(addcrlf, b))
669
717
 
670
718
        self.log('weave is:')
671
719
        tmpf = StringIO()
710
758
        self.doMerge(['aaa', 'bbb'],
711
759
                     ['aaa', 'xxx', 'yyy', 'bbb'],
712
760
                     ['aaa', 'xxx', 'bbb'],
713
 
                     ['aaa', '<<<<', 'xxx', 'yyy', '====', 'xxx', '>>>>', 'bbb'])
 
761
                     ['aaa', '<<<<<<<', 'xxx', 'yyy', '=======', 'xxx', 
 
762
                      '>>>>>>>', 'bbb'])
714
763
 
715
764
        # really it ought to reduce this to 
716
765
        # ['aaa', 'xxx', 'yyy', 'bbb']
720
769
        self.doMerge(['aaa'],
721
770
                     ['xxx'],
722
771
                     ['yyy', 'zzz'],
723
 
                     ['<<<<', 'xxx', '====', 'yyy', 'zzz', '>>>>'])
 
772
                     ['<<<<<<<', 'xxx', '=======', 'yyy', 'zzz', 
 
773
                      '>>>>>>>'])
724
774
 
725
775
    def testNonClashInsert(self):
726
776
        self.doMerge(['aaa'],
727
777
                     ['xxx', 'aaa'],
728
778
                     ['yyy', 'zzz'],
729
 
                     ['<<<<', 'xxx', 'aaa', '====', 'yyy', 'zzz', '>>>>'])
 
779
                     ['<<<<<<<', 'xxx', 'aaa', '=======', 'yyy', 'zzz', 
 
780
                      '>>>>>>>'])
730
781
 
731
782
        self.doMerge(['aaa'],
732
783
                     ['aaa'],
748
799
        self.doMerge(['aaa', 'bbb', 'ccc'],
749
800
                     ['aaa', 'ddd', 'ccc'],
750
801
                     ['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
 
    
 
802
                     ['<<<<<<<<', 'aaa', '=======', '>>>>>>>', 'ccc'])
 
803
 
 
804
 
 
805
class JoinWeavesTests(TestBase):
 
806
    def setUp(self):
 
807
        super(JoinWeavesTests, self).setUp()
 
808
        self.weave1 = Weave()
 
809
        self.lines1 = ['hello\n']
 
810
        self.lines3 = ['hello\n', 'cruel\n', 'world\n']
 
811
        self.weave1.add('v1', [], self.lines1)
 
812
        self.weave1.add('v2', [0], ['hello\n', 'world\n'])
 
813
        self.weave1.add('v3', [1], self.lines3)
 
814
        
 
815
    def test_join_empty(self):
 
816
        """Join two empty weaves."""
 
817
        eq = self.assertEqual
 
818
        w1 = Weave()
 
819
        w2 = Weave()
 
820
        w1.join(w2)
 
821
        eq(w1.numversions(), 0)
 
822
        
 
823
    def test_join_empty_to_nonempty(self):
 
824
        """Join empty weave onto nonempty."""
 
825
        self.weave1.join(Weave())
 
826
        self.assertEqual(len(self.weave1), 3)
 
827
 
 
828
    def test_join_unrelated(self):
 
829
        """Join two weaves with no history in common."""
 
830
        wb = Weave()
 
831
        wb.add('b1', [], ['line from b\n'])
 
832
        w1 = self.weave1
 
833
        w1.join(wb)
 
834
        eq = self.assertEqual
 
835
        eq(len(w1), 4)
 
836
        eq(sorted(list(w1.iter_names())),
 
837
           ['b1', 'v1', 'v2', 'v3'])
 
838
 
 
839
    def test_join_related(self):
 
840
        wa = self.weave1.copy()
 
841
        wb = self.weave1.copy()
 
842
        wa.add('a1', ['v3'], ['hello\n', 'sweet\n', 'world\n'])
 
843
        wb.add('b1', ['v3'], ['hello\n', 'pale blue\n', 'world\n'])
 
844
        eq = self.assertEquals
 
845
        eq(len(wa), 4)
 
846
        eq(len(wb), 4)
 
847
        wa.join(wb)
 
848
        eq(len(wa), 5)
 
849
        eq(wa.get_lines('b1'),
 
850
           ['hello\n', 'pale blue\n', 'world\n'])
 
851
 
 
852
    def test_join_parent_disagreement(self):
 
853
        """Cannot join weaves with different parents for a version."""
 
854
        wa = Weave()
 
855
        wb = Weave()
 
856
        wa.add('v1', [], ['hello\n'])
 
857
        wb.add('v0', [], [])
 
858
        wb.add('v1', ['v0'], ['hello\n'])
 
859
        self.assertRaises(WeaveError,
 
860
                          wa.join, wb)
 
861
 
 
862
    def test_join_text_disagreement(self):
 
863
        """Cannot join weaves with different texts for a version."""
 
864
        wa = Weave()
 
865
        wb = Weave()
 
866
        wa.add('v1', [], ['hello\n'])
 
867
        wb.add('v1', [], ['not\n', 'hello\n'])
 
868
        self.assertRaises(WeaveError,
 
869
                          wa.join, wb)
 
870
 
 
871
    def test_join_unordered(self):
 
872
        """Join weaves where indexes differ.
 
873
        
 
874
        The source weave contains a different version at index 0."""
 
875
        wa = self.weave1.copy()
 
876
        wb = Weave()
 
877
        wb.add('x1', [], ['line from x1\n'])
 
878
        wb.add('v1', [], ['hello\n'])
 
879
        wb.add('v2', ['v1'], ['hello\n', 'world\n'])
 
880
        wa.join(wb)
 
881
        eq = self.assertEquals
 
882
        eq(sorted(wa.iter_names()), ['v1', 'v2', 'v3', 'x1',])
 
883
        eq(wa.get_text('x1'), 'line from x1\n')