/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_diff.py

  • Committer: Jelmer Vernooij
  • Date: 2019-06-03 23:48:08 UTC
  • mfrom: (7316 work)
  • mto: This revision was merged to the branch mainline in revision 7328.
  • Revision ID: jelmer@jelmer.uk-20190603234808-15yk5c7054tj8e2b
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
    diff,
25
25
    errors,
26
26
    osutils,
27
 
    patiencediff,
28
 
    _patiencediff_py,
29
27
    revision as _mod_revision,
30
28
    revisionspec,
31
29
    revisiontree,
867
865
                              b'.*a-file(.|\n)*b-file')
868
866
 
869
867
 
870
 
class TestPatienceDiffLib(tests.TestCase):
871
 
 
872
 
    def setUp(self):
873
 
        super(TestPatienceDiffLib, self).setUp()
874
 
        self._unique_lcs = _patiencediff_py.unique_lcs_py
875
 
        self._recurse_matches = _patiencediff_py.recurse_matches_py
876
 
        self._PatienceSequenceMatcher = \
877
 
            _patiencediff_py.PatienceSequenceMatcher_py
878
 
 
879
 
    def test_diff_unicode_string(self):
880
 
        a = ''.join([unichr(i) for i in range(4000, 4500, 3)])
881
 
        b = ''.join([unichr(i) for i in range(4300, 4800, 2)])
882
 
        sm = self._PatienceSequenceMatcher(None, a, b)
883
 
        mb = sm.get_matching_blocks()
884
 
        self.assertEqual(35, len(mb))
885
 
 
886
 
    def test_unique_lcs(self):
887
 
        unique_lcs = self._unique_lcs
888
 
        self.assertEqual(unique_lcs('', ''), [])
889
 
        self.assertEqual(unique_lcs('', 'a'), [])
890
 
        self.assertEqual(unique_lcs('a', ''), [])
891
 
        self.assertEqual(unique_lcs('a', 'a'), [(0, 0)])
892
 
        self.assertEqual(unique_lcs('a', 'b'), [])
893
 
        self.assertEqual(unique_lcs('ab', 'ab'), [(0, 0), (1, 1)])
894
 
        self.assertEqual(unique_lcs('abcde', 'cdeab'),
895
 
                         [(2, 0), (3, 1), (4, 2)])
896
 
        self.assertEqual(unique_lcs('cdeab', 'abcde'),
897
 
                         [(0, 2), (1, 3), (2, 4)])
898
 
        self.assertEqual(unique_lcs('abXde', 'abYde'), [(0, 0), (1, 1),
899
 
                                                        (3, 3), (4, 4)])
900
 
        self.assertEqual(unique_lcs('acbac', 'abc'), [(2, 1)])
901
 
 
902
 
    def test_recurse_matches(self):
903
 
        def test_one(a, b, matches):
904
 
            test_matches = []
905
 
            self._recurse_matches(
906
 
                a, b, 0, 0, len(a), len(b), test_matches, 10)
907
 
            self.assertEqual(test_matches, matches)
908
 
 
909
 
        test_one(['a', '', 'b', '', 'c'], ['a', 'a', 'b', 'c', 'c'],
910
 
                 [(0, 0), (2, 2), (4, 4)])
911
 
        test_one(['a', 'c', 'b', 'a', 'c'], ['a', 'b', 'c'],
912
 
                 [(0, 0), (2, 1), (4, 2)])
913
 
        # Even though 'bc' is not unique globally, and is surrounded by
914
 
        # non-matching lines, we should still match, because they are locally
915
 
        # unique
916
 
        test_one('abcdbce', 'afbcgdbce', [(0, 0), (1, 2), (2, 3), (3, 5),
917
 
                                          (4, 6), (5, 7), (6, 8)])
918
 
 
919
 
        # recurse_matches doesn't match non-unique
920
 
        # lines surrounded by bogus text.
921
 
        # The update has been done in patiencediff.SequenceMatcher instead
922
 
 
923
 
        # This is what it could be
924
 
        #test_one('aBccDe', 'abccde', [(0,0), (2,2), (3,3), (5,5)])
925
 
 
926
 
        # This is what it currently gives:
927
 
        test_one('aBccDe', 'abccde', [(0, 0), (5, 5)])
928
 
 
929
 
    def assertDiffBlocks(self, a, b, expected_blocks):
930
 
        """Check that the sequence matcher returns the correct blocks.
931
 
 
932
 
        :param a: A sequence to match
933
 
        :param b: Another sequence to match
934
 
        :param expected_blocks: The expected output, not including the final
935
 
            matching block (len(a), len(b), 0)
936
 
        """
937
 
        matcher = self._PatienceSequenceMatcher(None, a, b)
938
 
        blocks = matcher.get_matching_blocks()
939
 
        last = blocks.pop()
940
 
        self.assertEqual((len(a), len(b), 0), last)
941
 
        self.assertEqual(expected_blocks, blocks)
942
 
 
943
 
    def test_matching_blocks(self):
944
 
        # Some basic matching tests
945
 
        self.assertDiffBlocks('', '', [])
946
 
        self.assertDiffBlocks([], [], [])
947
 
        self.assertDiffBlocks('abc', '', [])
948
 
        self.assertDiffBlocks('', 'abc', [])
949
 
        self.assertDiffBlocks('abcd', 'abcd', [(0, 0, 4)])
950
 
        self.assertDiffBlocks('abcd', 'abce', [(0, 0, 3)])
951
 
        self.assertDiffBlocks('eabc', 'abce', [(1, 0, 3)])
952
 
        self.assertDiffBlocks('eabce', 'abce', [(1, 0, 4)])
953
 
        self.assertDiffBlocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
954
 
        self.assertDiffBlocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
955
 
        self.assertDiffBlocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
956
 
        # This may check too much, but it checks to see that
957
 
        # a copied block stays attached to the previous section,
958
 
        # not the later one.
959
 
        # difflib would tend to grab the trailing longest match
960
 
        # which would make the diff not look right
961
 
        self.assertDiffBlocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
962
 
                              [(0, 0, 6), (6, 11, 10)])
963
 
 
964
 
        # make sure it supports passing in lists
965
 
        self.assertDiffBlocks(
966
 
            ['hello there\n',
967
 
             'world\n',
968
 
             'how are you today?\n'],
969
 
            ['hello there\n',
970
 
             'how are you today?\n'],
971
 
            [(0, 0, 1), (2, 1, 1)])
972
 
 
973
 
        # non unique lines surrounded by non-matching lines
974
 
        # won't be found
975
 
        self.assertDiffBlocks('aBccDe', 'abccde', [(0, 0, 1), (5, 5, 1)])
976
 
 
977
 
        # But they only need to be locally unique
978
 
        self.assertDiffBlocks('aBcDec', 'abcdec', [
979
 
                              (0, 0, 1), (2, 2, 1), (4, 4, 2)])
980
 
 
981
 
        # non unique blocks won't be matched
982
 
        self.assertDiffBlocks('aBcdEcdFg', 'abcdecdfg', [(0, 0, 1), (8, 8, 1)])
983
 
 
984
 
        # but locally unique ones will
985
 
        self.assertDiffBlocks('aBcdEeXcdFg', 'abcdecdfg', [(0, 0, 1), (2, 2, 2),
986
 
                                                           (5, 4, 1), (7, 5, 2), (10, 8, 1)])
987
 
 
988
 
        self.assertDiffBlocks('abbabbXd', 'cabbabxd', [(7, 7, 1)])
989
 
        self.assertDiffBlocks('abbabbbb', 'cabbabbc', [])
990
 
        self.assertDiffBlocks('bbbbbbbb', 'cbbbbbbc', [])
991
 
 
992
 
    def test_matching_blocks_tuples(self):
993
 
        # Some basic matching tests
994
 
        self.assertDiffBlocks([], [], [])
995
 
        self.assertDiffBlocks([('a',), ('b',), ('c,')], [], [])
996
 
        self.assertDiffBlocks([], [('a',), ('b',), ('c,')], [])
997
 
        self.assertDiffBlocks([('a',), ('b',), ('c,')],
998
 
                              [('a',), ('b',), ('c,')],
999
 
                              [(0, 0, 3)])
1000
 
        self.assertDiffBlocks([('a',), ('b',), ('c,')],
1001
 
                              [('a',), ('b',), ('d,')],
1002
 
                              [(0, 0, 2)])
1003
 
        self.assertDiffBlocks([('d',), ('b',), ('c,')],
1004
 
                              [('a',), ('b',), ('c,')],
1005
 
                              [(1, 1, 2)])
1006
 
        self.assertDiffBlocks([('d',), ('a',), ('b',), ('c,')],
1007
 
                              [('a',), ('b',), ('c,')],
1008
 
                              [(1, 0, 3)])
1009
 
        self.assertDiffBlocks([('a', 'b'), ('c', 'd'), ('e', 'f')],
1010
 
                              [('a', 'b'), ('c', 'X'), ('e', 'f')],
1011
 
                              [(0, 0, 1), (2, 2, 1)])
1012
 
        self.assertDiffBlocks([('a', 'b'), ('c', 'd'), ('e', 'f')],
1013
 
                              [('a', 'b'), ('c', 'dX'), ('e', 'f')],
1014
 
                              [(0, 0, 1), (2, 2, 1)])
1015
 
 
1016
 
    def test_opcodes(self):
1017
 
        def chk_ops(a, b, expected_codes):
1018
 
            s = self._PatienceSequenceMatcher(None, a, b)
1019
 
            self.assertEqual(expected_codes, s.get_opcodes())
1020
 
 
1021
 
        chk_ops('', '', [])
1022
 
        chk_ops([], [], [])
1023
 
        chk_ops('abc', '', [('delete', 0, 3, 0, 0)])
1024
 
        chk_ops('', 'abc', [('insert', 0, 0, 0, 3)])
1025
 
        chk_ops('abcd', 'abcd', [('equal', 0, 4, 0, 4)])
1026
 
        chk_ops('abcd', 'abce', [('equal', 0, 3, 0, 3),
1027
 
                                 ('replace', 3, 4, 3, 4)
1028
 
                                 ])
1029
 
        chk_ops('eabc', 'abce', [('delete', 0, 1, 0, 0),
1030
 
                                 ('equal', 1, 4, 0, 3),
1031
 
                                 ('insert', 4, 4, 3, 4)
1032
 
                                 ])
1033
 
        chk_ops('eabce', 'abce', [('delete', 0, 1, 0, 0),
1034
 
                                  ('equal', 1, 5, 0, 4)
1035
 
                                  ])
1036
 
        chk_ops('abcde', 'abXde', [('equal', 0, 2, 0, 2),
1037
 
                                   ('replace', 2, 3, 2, 3),
1038
 
                                   ('equal', 3, 5, 3, 5)
1039
 
                                   ])
1040
 
        chk_ops('abcde', 'abXYZde', [('equal', 0, 2, 0, 2),
1041
 
                                     ('replace', 2, 3, 2, 5),
1042
 
                                     ('equal', 3, 5, 5, 7)
1043
 
                                     ])
1044
 
        chk_ops('abde', 'abXYZde', [('equal', 0, 2, 0, 2),
1045
 
                                    ('insert', 2, 2, 2, 5),
1046
 
                                    ('equal', 2, 4, 5, 7)
1047
 
                                    ])
1048
 
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1049
 
                [('equal', 0, 6, 0, 6),
1050
 
                 ('insert', 6, 6, 6, 11),
1051
 
                 ('equal', 6, 16, 11, 21)
1052
 
                 ])
1053
 
        chk_ops(
1054
 
            ['hello there\n', 'world\n', 'how are you today?\n'],
1055
 
            ['hello there\n', 'how are you today?\n'],
1056
 
            [('equal', 0, 1, 0, 1),
1057
 
             ('delete', 1, 2, 1, 1),
1058
 
             ('equal', 2, 3, 1, 2),
1059
 
             ])
1060
 
        chk_ops('aBccDe', 'abccde',
1061
 
                [('equal', 0, 1, 0, 1),
1062
 
                 ('replace', 1, 5, 1, 5),
1063
 
                 ('equal', 5, 6, 5, 6),
1064
 
                 ])
1065
 
        chk_ops('aBcDec', 'abcdec',
1066
 
                [('equal', 0, 1, 0, 1),
1067
 
                 ('replace', 1, 2, 1, 2),
1068
 
                 ('equal', 2, 3, 2, 3),
1069
 
                 ('replace', 3, 4, 3, 4),
1070
 
                 ('equal', 4, 6, 4, 6),
1071
 
                 ])
1072
 
        chk_ops('aBcdEcdFg', 'abcdecdfg',
1073
 
                [('equal', 0, 1, 0, 1),
1074
 
                 ('replace', 1, 8, 1, 8),
1075
 
                 ('equal', 8, 9, 8, 9)
1076
 
                 ])
1077
 
        chk_ops('aBcdEeXcdFg', 'abcdecdfg',
1078
 
                [('equal', 0, 1, 0, 1),
1079
 
                 ('replace', 1, 2, 1, 2),
1080
 
                 ('equal', 2, 4, 2, 4),
1081
 
                 ('delete', 4, 5, 4, 4),
1082
 
                 ('equal', 5, 6, 4, 5),
1083
 
                 ('delete', 6, 7, 5, 5),
1084
 
                 ('equal', 7, 9, 5, 7),
1085
 
                 ('replace', 9, 10, 7, 8),
1086
 
                 ('equal', 10, 11, 8, 9)
1087
 
                 ])
1088
 
 
1089
 
    def test_grouped_opcodes(self):
1090
 
        def chk_ops(a, b, expected_codes, n=3):
1091
 
            s = self._PatienceSequenceMatcher(None, a, b)
1092
 
            self.assertEqual(expected_codes, list(s.get_grouped_opcodes(n)))
1093
 
 
1094
 
        chk_ops('', '', [])
1095
 
        chk_ops([], [], [])
1096
 
        chk_ops('abc', '', [[('delete', 0, 3, 0, 0)]])
1097
 
        chk_ops('', 'abc', [[('insert', 0, 0, 0, 3)]])
1098
 
        chk_ops('abcd', 'abcd', [])
1099
 
        chk_ops('abcd', 'abce', [[('equal', 0, 3, 0, 3),
1100
 
                                  ('replace', 3, 4, 3, 4)
1101
 
                                  ]])
1102
 
        chk_ops('eabc', 'abce', [[('delete', 0, 1, 0, 0),
1103
 
                                  ('equal', 1, 4, 0, 3),
1104
 
                                  ('insert', 4, 4, 3, 4)
1105
 
                                  ]])
1106
 
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1107
 
                [[('equal', 3, 6, 3, 6),
1108
 
                  ('insert', 6, 6, 6, 11),
1109
 
                  ('equal', 6, 9, 11, 14)
1110
 
                  ]])
1111
 
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1112
 
                [[('equal', 2, 6, 2, 6),
1113
 
                  ('insert', 6, 6, 6, 11),
1114
 
                  ('equal', 6, 10, 11, 15)
1115
 
                  ]], 4)
1116
 
        chk_ops('Xabcdef', 'abcdef',
1117
 
                [[('delete', 0, 1, 0, 0),
1118
 
                  ('equal', 1, 4, 0, 3)
1119
 
                  ]])
1120
 
        chk_ops('abcdef', 'abcdefX',
1121
 
                [[('equal', 3, 6, 3, 6),
1122
 
                  ('insert', 6, 6, 6, 7)
1123
 
                  ]])
1124
 
 
1125
 
    def test_multiple_ranges(self):
1126
 
        # There was an earlier bug where we used a bad set of ranges,
1127
 
        # this triggers that specific bug, to make sure it doesn't regress
1128
 
        self.assertDiffBlocks('abcdefghijklmnop',
1129
 
                              'abcXghiYZQRSTUVWXYZijklmnop',
1130
 
                              [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
1131
 
 
1132
 
        self.assertDiffBlocks('ABCd efghIjk  L',
1133
 
                              'AxyzBCn mo pqrstuvwI1 2  L',
1134
 
                              [(0, 0, 1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1135
 
 
1136
 
        # These are rot13 code snippets.
1137
 
        self.assertDiffBlocks('''\
1138
 
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
1139
 
    """
1140
 
    gnxrf_netf = ['svyr*']
1141
 
    gnxrf_bcgvbaf = ['ab-erphefr']
1142
 
 
1143
 
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr):
1144
 
        sebz omeyvo.nqq vzcbeg fzneg_nqq, nqq_ercbegre_cevag, nqq_ercbegre_ahyy
1145
 
        vs vf_dhvrg():
1146
 
            ercbegre = nqq_ercbegre_ahyy
1147
 
        ryfr:
1148
 
            ercbegre = nqq_ercbegre_cevag
1149
 
        fzneg_nqq(svyr_yvfg, abg ab_erphefr, ercbegre)
1150
 
 
1151
 
 
1152
 
pynff pzq_zxqve(Pbzznaq):
1153
 
'''.splitlines(True), '''\
1154
 
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
1155
 
 
1156
 
    --qel-eha jvyy fubj juvpu svyrf jbhyq or nqqrq, ohg abg npghnyyl
1157
 
    nqq gurz.
1158
 
    """
1159
 
    gnxrf_netf = ['svyr*']
1160
 
    gnxrf_bcgvbaf = ['ab-erphefr', 'qel-eha']
1161
 
 
1162
 
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr, qel_eha=Snyfr):
1163
 
        vzcbeg omeyvo.nqq
1164
 
 
1165
 
        vs qel_eha:
1166
 
            vs vf_dhvrg():
1167
 
                # Guvf vf cbvagyrff, ohg V'q engure abg envfr na reebe
1168
 
                npgvba = omeyvo.nqq.nqq_npgvba_ahyy
1169
 
            ryfr:
1170
 
  npgvba = omeyvo.nqq.nqq_npgvba_cevag
1171
 
        ryvs vf_dhvrg():
1172
 
            npgvba = omeyvo.nqq.nqq_npgvba_nqq
1173
 
        ryfr:
1174
 
       npgvba = omeyvo.nqq.nqq_npgvba_nqq_naq_cevag
1175
 
 
1176
 
        omeyvo.nqq.fzneg_nqq(svyr_yvfg, abg ab_erphefr, npgvba)
1177
 
 
1178
 
 
1179
 
pynff pzq_zxqve(Pbzznaq):
1180
 
'''.splitlines(True), [(0, 0, 1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1181
 
 
1182
 
    def test_patience_unified_diff(self):
1183
 
        txt_a = ['hello there\n',
1184
 
                 'world\n',
1185
 
                 'how are you today?\n']
1186
 
        txt_b = ['hello there\n',
1187
 
                 'how are you today?\n']
1188
 
        unified_diff = patiencediff.unified_diff
1189
 
        psm = self._PatienceSequenceMatcher
1190
 
        self.assertEqual(['--- \n',
1191
 
                          '+++ \n',
1192
 
                          '@@ -1,3 +1,2 @@\n',
1193
 
                          ' hello there\n',
1194
 
                          '-world\n',
1195
 
                          ' how are you today?\n'
1196
 
                          ], list(unified_diff(txt_a, txt_b,
1197
 
                                               sequencematcher=psm)))
1198
 
        txt_a = [x + '\n' for x in 'abcdefghijklmnop']
1199
 
        txt_b = [x + '\n' for x in 'abcdefxydefghijklmnop']
1200
 
        # This is the result with LongestCommonSubstring matching
1201
 
        self.assertEqual(['--- \n',
1202
 
                          '+++ \n',
1203
 
                          '@@ -1,6 +1,11 @@\n',
1204
 
                          ' a\n',
1205
 
                          ' b\n',
1206
 
                          ' c\n',
1207
 
                          '+d\n',
1208
 
                          '+e\n',
1209
 
                          '+f\n',
1210
 
                          '+x\n',
1211
 
                          '+y\n',
1212
 
                          ' d\n',
1213
 
                          ' e\n',
1214
 
                          ' f\n'], list(unified_diff(txt_a, txt_b)))
1215
 
        # And the patience diff
1216
 
        self.assertEqual(['--- \n',
1217
 
                          '+++ \n',
1218
 
                          '@@ -4,6 +4,11 @@\n',
1219
 
                          ' d\n',
1220
 
                          ' e\n',
1221
 
                          ' f\n',
1222
 
                          '+x\n',
1223
 
                          '+y\n',
1224
 
                          '+d\n',
1225
 
                          '+e\n',
1226
 
                          '+f\n',
1227
 
                          ' g\n',
1228
 
                          ' h\n',
1229
 
                          ' i\n',
1230
 
                          ], list(unified_diff(txt_a, txt_b,
1231
 
                                               sequencematcher=psm)))
1232
 
 
1233
 
    def test_patience_unified_diff_with_dates(self):
1234
 
        txt_a = ['hello there\n',
1235
 
                 'world\n',
1236
 
                 'how are you today?\n']
1237
 
        txt_b = ['hello there\n',
1238
 
                 'how are you today?\n']
1239
 
        unified_diff = patiencediff.unified_diff
1240
 
        psm = self._PatienceSequenceMatcher
1241
 
        self.assertEqual(['--- a\t2008-08-08\n',
1242
 
                          '+++ b\t2008-09-09\n',
1243
 
                          '@@ -1,3 +1,2 @@\n',
1244
 
                          ' hello there\n',
1245
 
                          '-world\n',
1246
 
                          ' how are you today?\n'
1247
 
                          ], list(unified_diff(txt_a, txt_b,
1248
 
                                               fromfile='a', tofile='b',
1249
 
                                               fromfiledate='2008-08-08',
1250
 
                                               tofiledate='2008-09-09',
1251
 
                                               sequencematcher=psm)))
1252
 
 
1253
 
 
1254
 
class TestPatienceDiffLib_c(TestPatienceDiffLib):
1255
 
 
1256
 
    _test_needs_features = [features.compiled_patiencediff_feature]
1257
 
 
1258
 
    def setUp(self):
1259
 
        super(TestPatienceDiffLib_c, self).setUp()
1260
 
        from breezy import _patiencediff_c
1261
 
        self._unique_lcs = _patiencediff_c.unique_lcs_c
1262
 
        self._recurse_matches = _patiencediff_c.recurse_matches_c
1263
 
        self._PatienceSequenceMatcher = \
1264
 
            _patiencediff_c.PatienceSequenceMatcher_c
1265
 
 
1266
 
    def test_unhashable(self):
1267
 
        """We should get a proper exception here."""
1268
 
        # We need to be able to hash items in the sequence, lists are
1269
 
        # unhashable, and thus cannot be diffed
1270
 
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1271
 
                              None, [[]], [])
1272
 
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1273
 
                              None, ['valid', []], [])
1274
 
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1275
 
                              None, ['valid'], [[]])
1276
 
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1277
 
                              None, ['valid'], ['valid', []])
1278
 
 
1279
 
 
1280
 
class TestPatienceDiffLibFiles(tests.TestCaseInTempDir):
1281
 
 
1282
 
    def setUp(self):
1283
 
        super(TestPatienceDiffLibFiles, self).setUp()
1284
 
        self._PatienceSequenceMatcher = \
1285
 
            _patiencediff_py.PatienceSequenceMatcher_py
1286
 
 
1287
 
    def test_patience_unified_diff_files(self):
1288
 
        txt_a = [b'hello there\n',
1289
 
                 b'world\n',
1290
 
                 b'how are you today?\n']
1291
 
        txt_b = [b'hello there\n',
1292
 
                 b'how are you today?\n']
1293
 
        with open('a1', 'wb') as f:
1294
 
            f.writelines(txt_a)
1295
 
        with open('b1', 'wb') as f:
1296
 
            f.writelines(txt_b)
1297
 
 
1298
 
        unified_diff_files = patiencediff.unified_diff_files
1299
 
        psm = self._PatienceSequenceMatcher
1300
 
        self.assertEqual([b'--- a1\n',
1301
 
                          b'+++ b1\n',
1302
 
                          b'@@ -1,3 +1,2 @@\n',
1303
 
                          b' hello there\n',
1304
 
                          b'-world\n',
1305
 
                          b' how are you today?\n',
1306
 
                          ], list(unified_diff_files(b'a1', b'b1',
1307
 
                                                     sequencematcher=psm)))
1308
 
 
1309
 
        txt_a = [x + '\n' for x in 'abcdefghijklmnop']
1310
 
        txt_b = [x + '\n' for x in 'abcdefxydefghijklmnop']
1311
 
        with open('a2', 'wt') as f:
1312
 
            f.writelines(txt_a)
1313
 
        with open('b2', 'wt') as f:
1314
 
            f.writelines(txt_b)
1315
 
 
1316
 
        # This is the result with LongestCommonSubstring matching
1317
 
        self.assertEqual([b'--- a2\n',
1318
 
                          b'+++ b2\n',
1319
 
                          b'@@ -1,6 +1,11 @@\n',
1320
 
                          b' a\n',
1321
 
                          b' b\n',
1322
 
                          b' c\n',
1323
 
                          b'+d\n',
1324
 
                          b'+e\n',
1325
 
                          b'+f\n',
1326
 
                          b'+x\n',
1327
 
                          b'+y\n',
1328
 
                          b' d\n',
1329
 
                          b' e\n',
1330
 
                          b' f\n'], list(unified_diff_files(b'a2', b'b2')))
1331
 
 
1332
 
        # And the patience diff
1333
 
        self.assertEqual([b'--- a2\n',
1334
 
                          b'+++ b2\n',
1335
 
                          b'@@ -4,6 +4,11 @@\n',
1336
 
                          b' d\n',
1337
 
                          b' e\n',
1338
 
                          b' f\n',
1339
 
                          b'+x\n',
1340
 
                          b'+y\n',
1341
 
                          b'+d\n',
1342
 
                          b'+e\n',
1343
 
                          b'+f\n',
1344
 
                          b' g\n',
1345
 
                          b' h\n',
1346
 
                          b' i\n'],
1347
 
                         list(unified_diff_files(b'a2', b'b2',
1348
 
                                                 sequencematcher=psm)))
1349
 
 
1350
 
 
1351
 
class TestPatienceDiffLibFiles_c(TestPatienceDiffLibFiles):
1352
 
 
1353
 
    _test_needs_features = [features.compiled_patiencediff_feature]
1354
 
 
1355
 
    def setUp(self):
1356
 
        super(TestPatienceDiffLibFiles_c, self).setUp()
1357
 
        from breezy import _patiencediff_c
1358
 
        self._PatienceSequenceMatcher = \
1359
 
            _patiencediff_c.PatienceSequenceMatcher_c
1360
 
 
1361
 
 
1362
 
class TestUsingCompiledIfAvailable(tests.TestCase):
1363
 
 
1364
 
    def test_PatienceSequenceMatcher(self):
1365
 
        if features.compiled_patiencediff_feature.available():
1366
 
            from breezy._patiencediff_c import PatienceSequenceMatcher_c
1367
 
            self.assertIs(PatienceSequenceMatcher_c,
1368
 
                          patiencediff.PatienceSequenceMatcher)
1369
 
        else:
1370
 
            from breezy._patiencediff_py import PatienceSequenceMatcher_py
1371
 
            self.assertIs(PatienceSequenceMatcher_py,
1372
 
                          patiencediff.PatienceSequenceMatcher)
1373
 
 
1374
 
    def test_unique_lcs(self):
1375
 
        if features.compiled_patiencediff_feature.available():
1376
 
            from breezy._patiencediff_c import unique_lcs_c
1377
 
            self.assertIs(unique_lcs_c,
1378
 
                          patiencediff.unique_lcs)
1379
 
        else:
1380
 
            from breezy._patiencediff_py import unique_lcs_py
1381
 
            self.assertIs(unique_lcs_py,
1382
 
                          patiencediff.unique_lcs)
1383
 
 
1384
 
    def test_recurse_matches(self):
1385
 
        if features.compiled_patiencediff_feature.available():
1386
 
            from breezy._patiencediff_c import recurse_matches_c
1387
 
            self.assertIs(recurse_matches_c,
1388
 
                          patiencediff.recurse_matches)
1389
 
        else:
1390
 
            from breezy._patiencediff_py import recurse_matches_py
1391
 
            self.assertIs(recurse_matches_py,
1392
 
                          patiencediff.recurse_matches)
1393
 
 
1394
 
 
1395
868
class TestDiffFromTool(tests.TestCaseWithTransport):
1396
869
 
1397
870
    def test_from_string(self):