695
674
self.check_read_write(k)
699
class MergeCases(TestBase):
700
def doMerge(self, base, a, b, mp):
701
from cStringIO import StringIO
702
from textwrap import dedent
708
w.add('text0', [], map(addcrlf, base))
709
w.add('text1', [0], map(addcrlf, a))
710
w.add('text2', [0], map(addcrlf, b))
712
self.log('weave is:')
715
self.log(tmpf.getvalue())
717
self.log('merge plan:')
718
p = list(w.plan_merge(1, 2))
719
for state, line in p:
721
self.log('%12s | %s' % (state, line[:-1]))
725
mt.writelines(w.weave_merge(p))
727
self.log(mt.getvalue())
729
mp = map(addcrlf, mp)
730
self.assertEqual(mt.readlines(), mp)
733
def testOneInsert(self):
739
def testSeparateInserts(self):
740
self.doMerge(['aaa', 'bbb', 'ccc'],
741
['aaa', 'xxx', 'bbb', 'ccc'],
742
['aaa', 'bbb', 'yyy', 'ccc'],
743
['aaa', 'xxx', 'bbb', 'yyy', 'ccc'])
745
def testSameInsert(self):
746
self.doMerge(['aaa', 'bbb', 'ccc'],
747
['aaa', 'xxx', 'bbb', 'ccc'],
748
['aaa', 'xxx', 'bbb', 'yyy', 'ccc'],
749
['aaa', 'xxx', 'bbb', 'yyy', 'ccc'])
751
def testOverlappedInsert(self):
752
self.doMerge(['aaa', 'bbb'],
753
['aaa', 'xxx', 'yyy', 'bbb'],
754
['aaa', 'xxx', 'bbb'],
755
['aaa', '<<<<', 'xxx', 'yyy', '====', 'xxx', '>>>>', 'bbb'])
757
# really it ought to reduce this to
758
# ['aaa', 'xxx', 'yyy', 'bbb']
761
def testClashReplace(self):
762
self.doMerge(['aaa'],
765
['<<<<', 'xxx', '====', 'yyy', 'zzz', '>>>>'])
767
def testNonClashInsert(self):
768
self.doMerge(['aaa'],
771
['<<<<', 'xxx', 'aaa', '====', 'yyy', 'zzz', '>>>>'])
773
self.doMerge(['aaa'],
779
def testDeleteAndModify(self):
780
"""Clashing delete and modification.
782
If one side modifies a region and the other deletes it then
783
there should be a conflict with one side blank.
786
#######################################
787
# skippd, not working yet
790
self.doMerge(['aaa', 'bbb', 'ccc'],
791
['aaa', 'ddd', 'ccc'],
793
['<<<<', 'aaa', '====', '>>>>', 'ccc'])
796
class JoinWeavesTests(TestBase):
798
super(JoinWeavesTests, self).setUp()
799
self.weave1 = Weave()
800
self.lines1 = ['hello\n']
801
self.lines3 = ['hello\n', 'cruel\n', 'world\n']
802
self.weave1.add('v1', [], self.lines1)
803
self.weave1.add('v2', [0], ['hello\n', 'world\n'])
804
self.weave1.add('v3', [1], self.lines3)
806
def test_join_empty(self):
807
"""Join two empty weaves."""
808
eq = self.assertEqual
812
eq(w1.numversions(), 0)
814
def test_join_empty_to_nonempty(self):
815
"""Join empty weave onto nonempty."""
816
self.weave1.join(Weave())
817
self.assertEqual(len(self.weave1), 3)
819
def test_join_unrelated(self):
820
"""Join two weaves with no history in common."""
822
wb.add('b1', [], ['line from b\n'])
825
eq = self.assertEqual
827
eq(sorted(list(w1.iter_names())),
828
['b1', 'v1', 'v2', 'v3'])
830
def test_join_related(self):
831
wa = self.weave1.copy()
832
wb = self.weave1.copy()
833
wa.add('a1', ['v3'], ['hello\n', 'sweet\n', 'world\n'])
834
wb.add('b1', ['v3'], ['hello\n', 'pale blue\n', 'world\n'])
835
eq = self.assertEquals
840
eq(wa.get_lines('b1'),
841
['hello\n', 'pale blue\n', 'world\n'])
843
def test_join_parent_disagreement(self):
844
"""Cannot join weaves with different parents for a version."""
847
wa.add('v1', [], ['hello\n'])
849
wb.add('v1', ['v0'], ['hello\n'])
850
self.assertRaises(WeaveError,
853
def test_join_text_disagreement(self):
854
"""Cannot join weaves with different texts for a version."""
857
wa.add('v1', [], ['hello\n'])
858
wb.add('v1', [], ['not\n', 'hello\n'])
859
self.assertRaises(WeaveError,
862
def test_join_unordered(self):
863
"""Join weaves where indexes differ.
865
The source weave contains a different version at index 0."""
866
wa = self.weave1.copy()
868
wb.add('x1', [], ['line from x1\n'])
869
wb.add('v1', [], ['hello\n'])
870
wb.add('v2', ['v1'], ['hello\n', 'world\n'])
872
eq = self.assertEquals
873
eq(sorted(wa.iter_names()), ['v1', 'v2', 'v3', 'x1',])
874
eq(wa.get_text('x1'), 'line from x1\n')
876
def test_join_with_ghosts(self):
877
"""Join that inserts parents of an existing revision.
879
This can happen when merging from another branch who
880
knows about revisions the destination does not. In
881
this test the second weave knows of an additional parent of
882
v2. Any revisions which are in common still have to have the
884
return ###############################
885
wa = self.weave1.copy()
887
wb.add('x1', [], ['line from x1\n'])
888
wb.add('v1', [], ['hello\n'])
889
wb.add('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
891
eq = self.assertEquals
892
eq(sorted(wa.iter_names()), ['v1', 'v2', 'v3', 'x1',])
893
eq(wa.get_text('x1'), 'line from x1\n')
679
from unittest import TestSuite, TestLoader
684
suite.addTest(tl.loadTestsFromModule(testweave))
686
return int(not testsweet.run_suite(suite)) # for shell 0=true
896
689
if __name__ == '__main__':
899
sys.exit(unittest.main())
691
sys.exit(testweave())