103
93
def runTest(self):
106
idx = k.add('text0', [], TEXT_0)
96
idx = k.add([], TEXT_0)
107
97
self.assertEqual(idx, 0)
109
idx = k.add('text1', [], TEXT_1)
99
idx = k.add([], TEXT_1)
110
100
self.assertEqual(idx, 1)
112
102
self.assertEqual(k.get(0), TEXT_0)
113
103
self.assertEqual(k.get(1), TEXT_1)
105
k.dump(self.TEST_LOG)
109
class DeltaAdd(TestBase):
110
"""Detection of changes prior to inserting new revision."""
113
k.add([], ['line 1'])
115
self.assertEqual(k._l,
121
changes = list(k._delta(set([0]),
125
self.log('raw changes: ' + pformat(changes))
127
# currently there are 3 lines in the weave, and we insert after them
128
self.assertEquals(changes,
129
[(3, 3, ['new line'])])
131
changes = k._delta(set([0]),
135
self.assertEquals(list(changes),
136
[(1, 1, ['top line'])])
138
self.check_read_write(k)
117
141
class InvalidAdd(TestBase):
122
146
self.assertRaises(IndexError,
129
class RepeatedAdd(TestBase):
130
"""Add the same version twice; harmless."""
133
idx = k.add('text0', [], TEXT_0)
134
idx2 = k.add('text0', [], TEXT_0)
135
self.assertEqual(idx, idx2)
139
class InvalidRepeatedAdd(TestBase):
142
idx = k.add('text0', [], TEXT_0)
143
self.assertRaises(WeaveError,
147
['not the same text'])
148
self.assertRaises(WeaveError,
151
[12], # not the right parents
156
152
class InsertLines(TestBase):
157
153
"""Store a revision that adds one line to the original.
178
k.add('text2', [0], ['line 1', 'diverged line'])
174
k.add([0], ['line 1', 'diverged line'])
180
176
self.assertEqual(k.annotate(2),
182
178
(2, 'diverged line')])
184
180
text3 = ['line 1', 'middle line', 'line 2']
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))))
191
self.log("k._weave=" + pformat(k._weave))
186
self.log("k._l=" + pformat(k._l))
193
188
self.assertEqual(k.annotate(3),
541
522
text0 = ['cheddar', 'stilton', 'gruyere']
542
523
text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
544
k.add('text0', [], text0)
545
k.add('text1', [0], text1)
547
self.log('k._weave=' + pformat(k._weave))
528
self.log('k._l=' + pformat(k._l))
549
530
self.assertEqual(k.get(0), text0)
550
531
self.assertEqual(k.get(1), text1)
562
543
['header', '', 'line from 1', 'fixup line', 'line from 2'],
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])
549
k.add([0, 1, 2], texts[3])
570
551
for i, t in enumerate(texts):
571
552
self.assertEqual(k.get(i), t)
578
559
(2, 'line from 2'),
581
self.assertEqual(list(k.inclusions([3])),
562
self.assertEqual(k.inclusions([3]),
584
self.log('k._weave=' + pformat(k._weave))
565
self.log('k._l=' + pformat(k._l))
586
567
self.check_read_write(k)
589
class Conflicts(TestBase):
590
"""Test detection of conflicting regions during a merge.
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."""
599
k.add([], ['aaa', 'bbb'])
600
k.add([0], ['aaa', '111', 'bbb'])
601
k.add([1], ['aaa', '222', 'bbb'])
603
merged = k.merge([1, 2])
605
self.assertEquals([[['aaa']],
611
class NonConflict(TestBase):
612
"""Two descendants insert compatible changes.
614
No conflict should be reported."""
619
k.add([], ['aaa', 'bbb'])
620
k.add([0], ['111', 'aaa', 'ccc', 'bbb'])
621
k.add([1], ['aaa', 'ccc', 'bbb', '222'])
627
570
class AutoMerge(TestBase):
628
571
def runTest(self):
633
576
['header', 'aaa', 'bbb', 'line from 2', 'more from 2'],
636
k.add('text0', [], texts[0])
637
k.add('text1', [0], texts[1])
638
k.add('text2', [0], texts[2])
640
self.log('k._weave=' + pformat(k._weave))
642
m = list(k.mash_iter([0, 1, 2]))
583
self.log('k._l=' + pformat(k._l))
585
m = list(k.merge_iter([0, 1, 2]))
644
587
self.assertEqual(m,
645
588
['header', 'aaa',
696
636
self.check_read_write(k)
700
class MergeCases(TestBase):
701
def doMerge(self, base, a, b, mp):
702
from cStringIO import StringIO
703
from textwrap import dedent
709
w.add('text0', [], map(addcrlf, base))
710
w.add('text1', [0], map(addcrlf, a))
711
w.add('text2', [0], map(addcrlf, b))
713
self.log('weave is:')
716
self.log(tmpf.getvalue())
718
self.log('merge plan:')
719
p = list(w.plan_merge(1, 2))
720
for state, line in p:
722
self.log('%12s | %s' % (state, line[:-1]))
726
mt.writelines(w.weave_merge(p))
728
self.log(mt.getvalue())
730
mp = map(addcrlf, mp)
731
self.assertEqual(mt.readlines(), mp)
734
def testOneInsert(self):
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'])
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'])
752
def testOverlappedInsert(self):
753
self.doMerge(['aaa', 'bbb'],
754
['aaa', 'xxx', 'yyy', 'bbb'],
755
['aaa', 'xxx', 'bbb'],
756
['aaa', '<<<<', 'xxx', 'yyy', '====', 'xxx', '>>>>', 'bbb'])
758
# really it ought to reduce this to
759
# ['aaa', 'xxx', 'yyy', 'bbb']
762
def testClashReplace(self):
763
self.doMerge(['aaa'],
766
['<<<<', 'xxx', '====', 'yyy', 'zzz', '>>>>'])
768
def testNonClashInsert(self):
769
self.doMerge(['aaa'],
772
['<<<<', 'xxx', 'aaa', '====', 'yyy', 'zzz', '>>>>'])
774
self.doMerge(['aaa'],
780
def testDeleteAndModify(self):
781
"""Clashing delete and modification.
783
If one side modifies a region and the other deletes it then
784
there should be a conflict with one side blank.
787
#######################################
788
# skippd, not working yet
791
self.doMerge(['aaa', 'bbb', 'ccc'],
792
['aaa', 'ddd', 'ccc'],
794
['<<<<', 'aaa', '====', '>>>>', 'ccc'])
641
from unittest import TestSuite, TestLoader
646
suite.addTest(tl.loadTestsFromModule(testweave))
648
return int(not testsweet.run_suite(suite)) # for shell 0=true
798
651
if __name__ == '__main__':
801
sys.exit(unittest.main())
653
sys.exit(testweave())