~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

merge fix for bug #177643

Show diffs side-by-side

added added

removed removed

Lines of Context:
723
723
        self.assertContainsRe(differ.to_file.getvalue(),
724
724
                              'was: old\nis: new\n')
725
725
 
 
726
    def test_alphabetical_order(self):
 
727
        self.build_tree(['new-tree/a-file'])
 
728
        self.new_tree.add('a-file')
 
729
        self.build_tree(['old-tree/b-file'])
 
730
        self.old_tree.add('b-file')
 
731
        self.differ.show_diff(None)
 
732
        self.assertContainsRe(self.differ.to_file.getvalue(),
 
733
            '.*a-file(.|\n)*b-file')
 
734
 
726
735
 
727
736
class TestPatienceDiffLib(TestCase):
728
737
 
774
783
        # This is what it currently gives:
775
784
        test_one('aBccDe', 'abccde', [(0,0), (5,5)])
776
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
 
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])
785
 
 
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)])
805
820
 
806
821
        # make sure it supports passing in lists
807
 
        chk_blocks(
 
822
        self.assertDiffBlocks(
808
823
                   ['hello there\n',
809
824
                    'world\n',
810
825
                    'how are you today?\n'],
814
829
 
815
830
        # non unique lines surrounded by non-matching lines
816
831
        # won't be found
817
 
        chk_blocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
 
832
        self.assertDiffBlocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
818
833
 
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)])
821
836
 
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)])
824
839
 
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)])
828
843
 
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', [])
 
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)])
832
871
 
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()
954
 
            x = blocks.pop()
955
 
            self.assertEquals(x, (len(a), len(b), 0))
956
 
            self.assertEquals(expected_blocks, blocks)
957
 
 
958
 
        chk_blocks('abcdefghijklmnop'
959
 
                 , 'abcXghiYZQRSTUVWXYZijklmnop'
960
 
                 , [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
961
 
 
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)])
 
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)])
965
995
 
966
996
        # These are rot13 code snippets.
967
 
        chk_blocks('''\
 
997
        self.assertDiffBlocks('''\
968
998
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
969
999
    """
970
1000
    gnxrf_netf = ['svyr*']
1077
1107
        self._PatienceSequenceMatcher = \
1078
1108
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
1079
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
 
1080
1123
 
1081
1124
class TestPatienceDiffLibFiles(TestCaseInTempDir):
1082
1125