~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-12-19 23:40:39 UTC
  • mfrom: (3074.2.12 patience_tuples)
  • Revision ID: pqm@pqm.ubuntu.com-20071219234039-462zdjboqfg4lcr1
(jam) allow _patience_diff_c to support any object that supports
        hash()

Show diffs side-by-side

added added

removed removed

Lines of Context:
783
783
        # This is what it currently gives:
784
784
        test_one('aBccDe', 'abccde', [(0,0), (5,5)])
785
785
 
 
786
    def assertDiffBlocks(self, a, b, expected_blocks):
 
787
        """Check that the sequence matcher returns the correct blocks.
 
788
 
 
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)
 
793
        """
 
794
        matcher = self._PatienceSequenceMatcher(None, a, b)
 
795
        blocks = matcher.get_matching_blocks()
 
796
        last = blocks.pop()
 
797
        self.assertEqual((len(a), len(b), 0), last)
 
798
        self.assertEqual(expected_blocks, blocks)
 
799
 
786
800
    def test_matching_blocks(self):
787
 
        def chk_blocks(a, b, expected_blocks):
788
 
            # difflib always adds a signature of the total
789
 
            # length, with no matching entries at the end
790
 
            s = self._PatienceSequenceMatcher(None, a, b)
791
 
            blocks = s.get_matching_blocks()
792
 
            self.assertEquals((len(a), len(b), 0), blocks[-1])
793
 
            self.assertEquals(expected_blocks, blocks[:-1])
794
 
 
795
801
        # Some basic matching tests
796
 
        chk_blocks('', '', [])
797
 
        chk_blocks([], [], [])
798
 
        chk_blocks('abc', '', [])
799
 
        chk_blocks('', 'abc', [])
800
 
        chk_blocks('abcd', 'abcd', [(0, 0, 4)])
801
 
        chk_blocks('abcd', 'abce', [(0, 0, 3)])
802
 
        chk_blocks('eabc', 'abce', [(1, 0, 3)])
803
 
        chk_blocks('eabce', 'abce', [(1, 0, 4)])
804
 
        chk_blocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
805
 
        chk_blocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
806
 
        chk_blocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
807
 
        # 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
808
814
        # a copied block stays attached to the previous section,
809
815
        # not the later one.
810
816
        # difflib would tend to grab the trailing longest match
811
817
        # which would make the diff not look right
812
 
        chk_blocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
813
 
                   [(0, 0, 6), (6, 11, 10)])
 
818
        self.assertDiffBlocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
 
819
                              [(0, 0, 6), (6, 11, 10)])
814
820
 
815
821
        # make sure it supports passing in lists
816
 
        chk_blocks(
 
822
        self.assertDiffBlocks(
817
823
                   ['hello there\n',
818
824
                    'world\n',
819
825
                    'how are you today?\n'],
823
829
 
824
830
        # non unique lines surrounded by non-matching lines
825
831
        # won't be found
826
 
        chk_blocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
 
832
        self.assertDiffBlocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
827
833
 
828
834
        # But they only need to be locally unique
829
 
        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)])
830
836
 
831
837
        # non unique blocks won't be matched
832
 
        chk_blocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
 
838
        self.assertDiffBlocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
833
839
 
834
840
        # but locally unique ones will
835
 
        chk_blocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
 
841
        self.assertDiffBlocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
836
842
                                              (5,4,1), (7,5,2), (10,8,1)])
837
843
 
838
 
        chk_blocks('abbabbXd', 'cabbabxd', [(7,7,1)])
839
 
        chk_blocks('abbabbbb', 'cabbabbc', [])
840
 
        chk_blocks('bbbbbbbb', 'cbbbbbbc', [])
 
844
        self.assertDiffBlocks('abbabbXd', 'cabbabxd', [(7,7,1)])
 
845
        self.assertDiffBlocks('abbabbbb', 'cabbabbc', [])
 
846
        self.assertDiffBlocks('bbbbbbbb', 'cbbbbbbc', [])
 
847
 
 
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,')],
 
855
                              [(0, 0, 3)])
 
856
        self.assertDiffBlocks([('a',), ('b',), ('c,')],
 
857
                              [('a',), ('b',), ('d,')],
 
858
                              [(0, 0, 2)])
 
859
        self.assertDiffBlocks([('d',), ('b',), ('c,')],
 
860
                              [('a',), ('b',), ('c,')],
 
861
                              [(1, 1, 2)])
 
862
        self.assertDiffBlocks([('d',), ('a',), ('b',), ('c,')],
 
863
                              [('a',), ('b',), ('c,')],
 
864
                              [(1, 0, 3)])
 
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)])
841
871
 
842
872
    def test_opcodes(self):
843
873
        def chk_ops(a, b, expected_codes):
955
985
    def test_multiple_ranges(self):
956
986
        # There was an earlier bug where we used a bad set of ranges,
957
987
        # this triggers that specific bug, to make sure it doesn't regress
958
 
        def chk_blocks(a, b, expected_blocks):
959
 
            # difflib always adds a signature of the total
960
 
            # length, with no matching entries at the end
961
 
            s = self._PatienceSequenceMatcher(None, a, b)
962
 
            blocks = s.get_matching_blocks()
963
 
            x = blocks.pop()
964
 
            self.assertEquals(x, (len(a), len(b), 0))
965
 
            self.assertEquals(expected_blocks, blocks)
966
 
 
967
 
        chk_blocks('abcdefghijklmnop'
968
 
                 , 'abcXghiYZQRSTUVWXYZijklmnop'
969
 
                 , [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
970
 
 
971
 
        chk_blocks('ABCd efghIjk  L'
972
 
                 , 'AxyzBCn mo pqrstuvwI1 2  L'
973
 
                 , [(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)])
 
991
 
 
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)])
974
995
 
975
996
        # These are rot13 code snippets.
976
 
        chk_blocks('''\
 
997
        self.assertDiffBlocks('''\
977
998
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
978
999
    """
979
1000
    gnxrf_netf = ['svyr*']
1086
1107
        self._PatienceSequenceMatcher = \
1087
1108
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
1088
1109
 
 
1110
    def test_unhashable(self):
 
1111
        """We should get a proper exception here."""
 
1112
        # We need to be able to hash items in the sequence, lists are
 
1113
        # unhashable, and thus cannot be diffed
 
1114
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1115
                                         None, [[]], [])
 
1116
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1117
                                         None, ['valid', []], [])
 
1118
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1119
                                         None, ['valid'], [[]])
 
1120
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1121
                                         None, ['valid'], ['valid', []])
 
1122
 
1089
1123
 
1090
1124
class TestPatienceDiffLibFiles(TestCaseInTempDir):
1091
1125