~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

  • Committer: Martin Pool
  • Date: 2007-09-04 09:10:35 UTC
  • mto: This revision was merged to the branch mainline in revision 2798.
  • Revision ID: mbp@sourcefrog.net-20070904091035-d11e7tfk55hy0a2z
merge cpatiencediff from Lukas

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
from bzrlib.errors import BinaryFile, NoDiff
25
25
import bzrlib.osutils as osutils
26
26
import bzrlib.patiencediff
 
27
import bzrlib._patiencediff_py
27
28
from bzrlib.tests import (Feature, TestCase, TestCaseWithTransport,
28
29
                          TestCaseInTempDir, TestSkipped)
29
30
 
30
31
 
 
32
class _CompiledPatienceDiffFeature(Feature):
 
33
 
 
34
    def _probe(self):
 
35
        try:
 
36
            import bzrlib._patiencediff_c
 
37
        except ImportError:
 
38
            return False
 
39
        return True
 
40
 
 
41
    def feature_name(self):
 
42
        return 'bzrlib._patiencediff_c'
 
43
 
 
44
CompiledPatienceDiffFeature = _CompiledPatienceDiffFeature()
 
45
 
 
46
 
31
47
class _UnicodeFilename(Feature):
32
48
    """Does the filesystem support Unicode filenames?"""
33
49
 
530
546
 
531
547
class TestPatienceDiffLib(TestCase):
532
548
 
 
549
    def setUp(self):
 
550
        super(TestPatienceDiffLib, self).setUp()
 
551
        self._unique_lcs = bzrlib._patiencediff_py.unique_lcs_py
 
552
        self._recurse_matches = bzrlib._patiencediff_py.recurse_matches_py
 
553
        self._PatienceSequenceMatcher = \
 
554
            bzrlib._patiencediff_py.PatienceSequenceMatcher_py
 
555
 
533
556
    def test_unique_lcs(self):
534
 
        unique_lcs = bzrlib.patiencediff.unique_lcs
 
557
        unique_lcs = self._unique_lcs
535
558
        self.assertEquals(unique_lcs('', ''), [])
 
559
        self.assertEquals(unique_lcs('', 'a'), [])
 
560
        self.assertEquals(unique_lcs('a', ''), [])
536
561
        self.assertEquals(unique_lcs('a', 'a'), [(0,0)])
537
562
        self.assertEquals(unique_lcs('a', 'b'), [])
538
563
        self.assertEquals(unique_lcs('ab', 'ab'), [(0,0), (1,1)])
545
570
    def test_recurse_matches(self):
546
571
        def test_one(a, b, matches):
547
572
            test_matches = []
548
 
            bzrlib.patiencediff.recurse_matches(a, b, 0, 0, len(a), len(b),
549
 
                test_matches, 10)
 
573
            self._recurse_matches(
 
574
                a, b, 0, 0, len(a), len(b), test_matches, 10)
550
575
            self.assertEquals(test_matches, matches)
551
576
 
552
577
        test_one(['a', '', 'b', '', 'c'], ['a', 'a', 'b', 'c', 'c'],
553
578
                 [(0, 0), (2, 2), (4, 4)])
554
579
        test_one(['a', 'c', 'b', 'a', 'c'], ['a', 'b', 'c'],
555
580
                 [(0, 0), (2, 1), (4, 2)])
 
581
        # Even though 'bc' is not unique globally, and is surrounded by
 
582
        # non-matching lines, we should still match, because they are locally
 
583
        # unique
 
584
        test_one('abcdbce', 'afbcgdbce', [(0,0), (1, 2), (2, 3), (3, 5),
 
585
                                          (4, 6), (5, 7), (6, 8)])
556
586
 
557
587
        # recurse_matches doesn't match non-unique 
558
588
        # lines surrounded by bogus text.
568
598
        def chk_blocks(a, b, expected_blocks):
569
599
            # difflib always adds a signature of the total
570
600
            # length, with no matching entries at the end
571
 
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
 
601
            s = self._PatienceSequenceMatcher(None, a, b)
572
602
            blocks = s.get_matching_blocks()
573
603
            self.assertEquals((len(a), len(b), 0), blocks[-1])
574
604
            self.assertEquals(expected_blocks, blocks[:-1])
576
606
        # Some basic matching tests
577
607
        chk_blocks('', '', [])
578
608
        chk_blocks([], [], [])
 
609
        chk_blocks('abc', '', [])
 
610
        chk_blocks('', 'abc', [])
579
611
        chk_blocks('abcd', 'abcd', [(0, 0, 4)])
580
612
        chk_blocks('abcd', 'abce', [(0, 0, 3)])
581
613
        chk_blocks('eabc', 'abce', [(1, 0, 3)])
620
652
 
621
653
    def test_opcodes(self):
622
654
        def chk_ops(a, b, expected_codes):
623
 
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
 
655
            s = self._PatienceSequenceMatcher(None, a, b)
624
656
            self.assertEquals(expected_codes, s.get_opcodes())
625
657
 
626
658
        chk_ops('', '', [])
627
659
        chk_ops([], [], [])
 
660
        chk_ops('abc', '', [('delete', 0,3, 0,0)])
 
661
        chk_ops('', 'abc', [('insert', 0,0, 0,3)])
628
662
        chk_ops('abcd', 'abcd', [('equal',    0,4, 0,4)])
629
663
        chk_ops('abcd', 'abce', [('equal',   0,3, 0,3),
630
664
                                 ('replace', 3,4, 3,4)
692
726
                 ('equal',   10,11, 8,9)
693
727
                ])
694
728
 
 
729
    def test_grouped_opcodes(self):
 
730
        def chk_ops(a, b, expected_codes, n=3):
 
731
            s = self._PatienceSequenceMatcher(None, a, b)
 
732
            self.assertEquals(expected_codes, list(s.get_grouped_opcodes(n)))
 
733
 
 
734
        chk_ops('', '', [])
 
735
        chk_ops([], [], [])
 
736
        chk_ops('abc', '', [[('delete', 0,3, 0,0)]])
 
737
        chk_ops('', 'abc', [[('insert', 0,0, 0,3)]])
 
738
        chk_ops('abcd', 'abcd', [])
 
739
        chk_ops('abcd', 'abce', [[('equal',   0,3, 0,3),
 
740
                                  ('replace', 3,4, 3,4)
 
741
                                 ]])
 
742
        chk_ops('eabc', 'abce', [[('delete', 0,1, 0,0),
 
743
                                 ('equal',  1,4, 0,3),
 
744
                                 ('insert', 4,4, 3,4)
 
745
                                ]])
 
746
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
 
747
                [[('equal',  3,6, 3,6),
 
748
                  ('insert', 6,6, 6,11),
 
749
                  ('equal',  6,9, 11,14)
 
750
                  ]])
 
751
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
 
752
                [[('equal',  2,6, 2,6),
 
753
                  ('insert', 6,6, 6,11),
 
754
                  ('equal',  6,10, 11,15)
 
755
                  ]], 4)
 
756
        chk_ops('Xabcdef', 'abcdef',
 
757
                [[('delete', 0,1, 0,0),
 
758
                  ('equal',  1,4, 0,3)
 
759
                  ]])
 
760
        chk_ops('abcdef', 'abcdefX',
 
761
                [[('equal',  3,6, 3,6),
 
762
                  ('insert', 6,6, 6,7)
 
763
                  ]])
 
764
 
 
765
 
695
766
    def test_multiple_ranges(self):
696
767
        # There was an earlier bug where we used a bad set of ranges,
697
768
        # this triggers that specific bug, to make sure it doesn't regress
698
769
        def chk_blocks(a, b, expected_blocks):
699
770
            # difflib always adds a signature of the total
700
771
            # length, with no matching entries at the end
701
 
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
 
772
            s = self._PatienceSequenceMatcher(None, a, b)
702
773
            blocks = s.get_matching_blocks()
703
774
            x = blocks.pop()
704
775
            self.assertEquals(x, (len(a), len(b), 0))
766
837
        txt_b = ['hello there\n',
767
838
                 'how are you today?\n']
768
839
        unified_diff = bzrlib.patiencediff.unified_diff
769
 
        psm = bzrlib.patiencediff.PatienceSequenceMatcher
 
840
        psm = self._PatienceSequenceMatcher
770
841
        self.assertEquals([ '---  \n',
771
842
                           '+++  \n',
772
843
                           '@@ -1,3 +1,2 @@\n',
814
885
                                 sequencematcher=psm)))
815
886
 
816
887
 
 
888
class TestPatienceDiffLib_c(TestPatienceDiffLib):
 
889
 
 
890
    _test_needs_features = [CompiledPatienceDiffFeature]
 
891
 
 
892
    def setUp(self):
 
893
        super(TestPatienceDiffLib_c, self).setUp()
 
894
        import bzrlib._patiencediff_c
 
895
        self._unique_lcs = bzrlib._patiencediff_c.unique_lcs_c
 
896
        self._recurse_matches = bzrlib._patiencediff_c.recurse_matches_c
 
897
        self._PatienceSequenceMatcher = \
 
898
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
 
899
 
 
900
 
817
901
class TestPatienceDiffLibFiles(TestCaseInTempDir):
818
902
 
 
903
    def setUp(self):
 
904
        super(TestPatienceDiffLibFiles, self).setUp()
 
905
        self._PatienceSequenceMatcher = \
 
906
            bzrlib._patiencediff_py.PatienceSequenceMatcher_py
 
907
 
819
908
    def test_patience_unified_diff_files(self):
820
909
        txt_a = ['hello there\n',
821
910
                 'world\n',
826
915
        open('b1', 'wb').writelines(txt_b)
827
916
 
828
917
        unified_diff_files = bzrlib.patiencediff.unified_diff_files
829
 
        psm = bzrlib.patiencediff.PatienceSequenceMatcher
 
918
        psm = self._PatienceSequenceMatcher
830
919
        self.assertEquals(['--- a1 \n',
831
920
                           '+++ b1 \n',
832
921
                           '@@ -1,3 +1,2 @@\n',
877
966
                          ]
878
967
                          , list(unified_diff_files('a2', 'b2',
879
968
                                 sequencematcher=psm)))
 
969
 
 
970
 
 
971
class TestPatienceDiffLibFiles_c(TestPatienceDiffLibFiles):
 
972
 
 
973
    _test_needs_features = [CompiledPatienceDiffFeature]
 
974
 
 
975
    def setUp(self):
 
976
        super(TestPatienceDiffLibFiles_c, self).setUp()
 
977
        import bzrlib._patiencediff_c
 
978
        self._PatienceSequenceMatcher = \
 
979
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
 
980
 
 
981
 
 
982
class TestUsingCompiledIfAvailable(TestCase):
 
983
 
 
984
    def test_PatienceSequenceMatcher(self):
 
985
        if CompiledPatienceDiffFeature.available():
 
986
            from bzrlib._patiencediff_c import PatienceSequenceMatcher_c
 
987
            self.assertIs(PatienceSequenceMatcher_c,
 
988
                          bzrlib.patiencediff.PatienceSequenceMatcher)
 
989
        else:
 
990
            from bzrlib._patiencediff_py import PatienceSequenceMatcher_py
 
991
            self.assertIs(PatienceSequenceMatcher_py,
 
992
                          bzrlib.patiencediff.PatienceSequenceMatcher)
 
993
 
 
994
    def test_unique_lcs(self):
 
995
        if CompiledPatienceDiffFeature.available():
 
996
            from bzrlib._patiencediff_c import unique_lcs_c
 
997
            self.assertIs(unique_lcs_c,
 
998
                          bzrlib.patiencediff.unique_lcs)
 
999
        else:
 
1000
            from bzrlib._patiencediff_py import unique_lcs_py
 
1001
            self.assertIs(unique_lcs_py,
 
1002
                          bzrlib.patiencediff.unique_lcs)
 
1003
 
 
1004
    def test_recurse_matches(self):
 
1005
        if CompiledPatienceDiffFeature.available():
 
1006
            from bzrlib._patiencediff_c import recurse_matches_c
 
1007
            self.assertIs(recurse_matches_c,
 
1008
                          bzrlib.patiencediff.recurse_matches)
 
1009
        else:
 
1010
            from bzrlib._patiencediff_py import recurse_matches_py
 
1011
            self.assertIs(recurse_matches_py,
 
1012
                          bzrlib.patiencediff.recurse_matches)