774
783
# This is what it currently gives:
775
784
test_one('aBccDe', 'abccde', [(0,0), (5,5)])
786
def assertDiffBlocks(self, a, b, expected_blocks):
787
"""Check that the sequence matcher returns the correct blocks.
789
:param a: A sequence to match
790
:param b: Another sequence to match
791
:param expected_blocks: The expected output, not including the final
792
matching block (len(a), len(b), 0)
794
matcher = self._PatienceSequenceMatcher(None, a, b)
795
blocks = matcher.get_matching_blocks()
797
self.assertEqual((len(a), len(b), 0), last)
798
self.assertEqual(expected_blocks, blocks)
777
800
def test_matching_blocks(self):
778
def chk_blocks(a, b, expected_blocks):
779
# difflib always adds a signature of the total
780
# length, with no matching entries at the end
781
s = self._PatienceSequenceMatcher(None, a, b)
782
blocks = s.get_matching_blocks()
783
self.assertEquals((len(a), len(b), 0), blocks[-1])
784
self.assertEquals(expected_blocks, blocks[:-1])
786
801
# Some basic matching tests
787
chk_blocks('', '', [])
788
chk_blocks([], [], [])
789
chk_blocks('abc', '', [])
790
chk_blocks('', 'abc', [])
791
chk_blocks('abcd', 'abcd', [(0, 0, 4)])
792
chk_blocks('abcd', 'abce', [(0, 0, 3)])
793
chk_blocks('eabc', 'abce', [(1, 0, 3)])
794
chk_blocks('eabce', 'abce', [(1, 0, 4)])
795
chk_blocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
796
chk_blocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
797
chk_blocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
798
# This may check too much, but it checks to see that
802
self.assertDiffBlocks('', '', [])
803
self.assertDiffBlocks([], [], [])
804
self.assertDiffBlocks('abc', '', [])
805
self.assertDiffBlocks('', 'abc', [])
806
self.assertDiffBlocks('abcd', 'abcd', [(0, 0, 4)])
807
self.assertDiffBlocks('abcd', 'abce', [(0, 0, 3)])
808
self.assertDiffBlocks('eabc', 'abce', [(1, 0, 3)])
809
self.assertDiffBlocks('eabce', 'abce', [(1, 0, 4)])
810
self.assertDiffBlocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
811
self.assertDiffBlocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
812
self.assertDiffBlocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
813
# This may check too much, but it checks to see that
799
814
# a copied block stays attached to the previous section,
800
815
# not the later one.
801
816
# difflib would tend to grab the trailing longest match
802
817
# which would make the diff not look right
803
chk_blocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
804
[(0, 0, 6), (6, 11, 10)])
818
self.assertDiffBlocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
819
[(0, 0, 6), (6, 11, 10)])
806
821
# make sure it supports passing in lists
822
self.assertDiffBlocks(
808
823
['hello there\n',
810
825
'how are you today?\n'],
815
830
# non unique lines surrounded by non-matching lines
817
chk_blocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
832
self.assertDiffBlocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
819
834
# But they only need to be locally unique
820
chk_blocks('aBcDec', 'abcdec', [(0,0,1), (2,2,1), (4,4,2)])
835
self.assertDiffBlocks('aBcDec', 'abcdec', [(0,0,1), (2,2,1), (4,4,2)])
822
837
# non unique blocks won't be matched
823
chk_blocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
838
self.assertDiffBlocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
825
840
# but locally unique ones will
826
chk_blocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
841
self.assertDiffBlocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
827
842
(5,4,1), (7,5,2), (10,8,1)])
829
chk_blocks('abbabbXd', 'cabbabxd', [(7,7,1)])
830
chk_blocks('abbabbbb', 'cabbabbc', [])
831
chk_blocks('bbbbbbbb', 'cbbbbbbc', [])
844
self.assertDiffBlocks('abbabbXd', 'cabbabxd', [(7,7,1)])
845
self.assertDiffBlocks('abbabbbb', 'cabbabbc', [])
846
self.assertDiffBlocks('bbbbbbbb', 'cbbbbbbc', [])
848
def test_matching_blocks_tuples(self):
849
# Some basic matching tests
850
self.assertDiffBlocks([], [], [])
851
self.assertDiffBlocks([('a',), ('b',), ('c,')], [], [])
852
self.assertDiffBlocks([], [('a',), ('b',), ('c,')], [])
853
self.assertDiffBlocks([('a',), ('b',), ('c,')],
854
[('a',), ('b',), ('c,')],
856
self.assertDiffBlocks([('a',), ('b',), ('c,')],
857
[('a',), ('b',), ('d,')],
859
self.assertDiffBlocks([('d',), ('b',), ('c,')],
860
[('a',), ('b',), ('c,')],
862
self.assertDiffBlocks([('d',), ('a',), ('b',), ('c,')],
863
[('a',), ('b',), ('c,')],
865
self.assertDiffBlocks([('a', 'b'), ('c', 'd'), ('e', 'f')],
866
[('a', 'b'), ('c', 'X'), ('e', 'f')],
867
[(0, 0, 1), (2, 2, 1)])
868
self.assertDiffBlocks([('a', 'b'), ('c', 'd'), ('e', 'f')],
869
[('a', 'b'), ('c', 'dX'), ('e', 'f')],
870
[(0, 0, 1), (2, 2, 1)])
833
872
def test_opcodes(self):
834
873
def chk_ops(a, b, expected_codes):
946
985
def test_multiple_ranges(self):
947
986
# There was an earlier bug where we used a bad set of ranges,
948
987
# this triggers that specific bug, to make sure it doesn't regress
949
def chk_blocks(a, b, expected_blocks):
950
# difflib always adds a signature of the total
951
# length, with no matching entries at the end
952
s = self._PatienceSequenceMatcher(None, a, b)
953
blocks = s.get_matching_blocks()
955
self.assertEquals(x, (len(a), len(b), 0))
956
self.assertEquals(expected_blocks, blocks)
958
chk_blocks('abcdefghijklmnop'
959
, 'abcXghiYZQRSTUVWXYZijklmnop'
960
, [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
962
chk_blocks('ABCd efghIjk L'
963
, 'AxyzBCn mo pqrstuvwI1 2 L'
964
, [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
988
self.assertDiffBlocks('abcdefghijklmnop',
989
'abcXghiYZQRSTUVWXYZijklmnop',
990
[(0, 0, 3), (6, 4, 3), (9, 20, 7)])
992
self.assertDiffBlocks('ABCd efghIjk L',
993
'AxyzBCn mo pqrstuvwI1 2 L',
994
[(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
966
996
# These are rot13 code snippets.
997
self.assertDiffBlocks('''\
968
998
trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
970
1000
gnxrf_netf = ['svyr*']