150
150
def test_binary_lines(self):
152
152
uni_lines = [1023 * 'a' + '\x00']
153
self.assertRaises(errors.BinaryFile, udiff_lines, uni_lines , empty)
153
self.assertRaises(errors.BinaryFile, udiff_lines, uni_lines, empty)
154
154
self.assertRaises(errors.BinaryFile, udiff_lines, empty, uni_lines)
155
udiff_lines(uni_lines , empty, allow_binary=True)
155
udiff_lines(uni_lines, empty, allow_binary=True)
156
156
udiff_lines(empty, uni_lines, allow_binary=True)
158
158
def test_external_diff(self):
255
255
def test_internal_diff_default_context(self):
256
256
output = BytesIO()
257
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
258
'same_text\n','same_text\n','old_text\n'],
259
'new', ['same_text\n','same_text\n','same_text\n',
260
'same_text\n','same_text\n','new_text\n'], output)
257
diff.internal_diff('old', ['same_text\n', 'same_text\n', 'same_text\n',
258
'same_text\n', 'same_text\n', 'old_text\n'],
259
'new', ['same_text\n', 'same_text\n', 'same_text\n',
260
'same_text\n', 'same_text\n', 'new_text\n'], output)
261
261
lines = output.getvalue().splitlines(True)
262
262
self.check_patch(lines)
263
263
self.assertEqual(['--- old\n',
275
275
def test_internal_diff_no_context(self):
276
276
output = BytesIO()
277
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
278
'same_text\n','same_text\n','old_text\n'],
279
'new', ['same_text\n','same_text\n','same_text\n',
280
'same_text\n','same_text\n','new_text\n'], output,
277
diff.internal_diff('old', ['same_text\n', 'same_text\n', 'same_text\n',
278
'same_text\n', 'same_text\n', 'old_text\n'],
279
'new', ['same_text\n', 'same_text\n', 'same_text\n',
280
'same_text\n', 'same_text\n', 'new_text\n'], output,
282
282
lines = output.getvalue().splitlines(True)
283
283
self.check_patch(lines)
293
293
def test_internal_diff_more_context(self):
294
294
output = BytesIO()
295
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
296
'same_text\n','same_text\n','old_text\n'],
297
'new', ['same_text\n','same_text\n','same_text\n',
298
'same_text\n','same_text\n','new_text\n'], output,
295
diff.internal_diff('old', ['same_text\n', 'same_text\n', 'same_text\n',
296
'same_text\n', 'same_text\n', 'old_text\n'],
297
'new', ['same_text\n', 'same_text\n', 'same_text\n',
298
'same_text\n', 'same_text\n', 'new_text\n'], output,
300
300
lines = output.getvalue().splitlines(True)
301
301
self.check_patch(lines)
886
886
self.assertEqual(unique_lcs('', ''), [])
887
887
self.assertEqual(unique_lcs('', 'a'), [])
888
888
self.assertEqual(unique_lcs('a', ''), [])
889
self.assertEqual(unique_lcs('a', 'a'), [(0,0)])
889
self.assertEqual(unique_lcs('a', 'a'), [(0, 0)])
890
890
self.assertEqual(unique_lcs('a', 'b'), [])
891
self.assertEqual(unique_lcs('ab', 'ab'), [(0,0), (1,1)])
892
self.assertEqual(unique_lcs('abcde', 'cdeab'), [(2,0), (3,1), (4,2)])
893
self.assertEqual(unique_lcs('cdeab', 'abcde'), [(0,2), (1,3), (2,4)])
894
self.assertEqual(unique_lcs('abXde', 'abYde'), [(0,0), (1,1),
896
self.assertEqual(unique_lcs('acbac', 'abc'), [(2,1)])
891
self.assertEqual(unique_lcs('ab', 'ab'), [(0, 0), (1, 1)])
892
self.assertEqual(unique_lcs('abcde', 'cdeab'), [(2, 0), (3, 1), (4, 2)])
893
self.assertEqual(unique_lcs('cdeab', 'abcde'), [(0, 2), (1, 3), (2, 4)])
894
self.assertEqual(unique_lcs('abXde', 'abYde'), [(0, 0), (1, 1),
896
self.assertEqual(unique_lcs('acbac', 'abc'), [(2, 1)])
898
898
def test_recurse_matches(self):
899
899
def test_one(a, b, matches):
909
909
# Even though 'bc' is not unique globally, and is surrounded by
910
910
# non-matching lines, we should still match, because they are locally
912
test_one('abcdbce', 'afbcgdbce', [(0,0), (1, 2), (2, 3), (3, 5),
912
test_one('abcdbce', 'afbcgdbce', [(0, 0), (1, 2), (2, 3), (3, 5),
913
913
(4, 6), (5, 7), (6, 8)])
915
915
# recurse_matches doesn't match non-unique
920
920
#test_one('aBccDe', 'abccde', [(0,0), (2,2), (3,3), (5,5)])
922
922
# This is what it currently gives:
923
test_one('aBccDe', 'abccde', [(0,0), (5,5)])
923
test_one('aBccDe', 'abccde', [(0, 0), (5, 5)])
925
925
def assertDiffBlocks(self, a, b, expected_blocks):
926
926
"""Check that the sequence matcher returns the correct blocks.
969
969
# non unique lines surrounded by non-matching lines
971
self.assertDiffBlocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
971
self.assertDiffBlocks('aBccDe', 'abccde', [(0, 0, 1), (5, 5, 1)])
973
973
# But they only need to be locally unique
974
self.assertDiffBlocks('aBcDec', 'abcdec', [(0,0,1), (2,2,1), (4,4,2)])
974
self.assertDiffBlocks('aBcDec', 'abcdec', [(0, 0, 1), (2, 2, 1), (4, 4, 2)])
976
976
# non unique blocks won't be matched
977
self.assertDiffBlocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
977
self.assertDiffBlocks('aBcdEcdFg', 'abcdecdfg', [(0, 0, 1), (8, 8, 1)])
979
979
# but locally unique ones will
980
self.assertDiffBlocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
981
(5,4,1), (7,5,2), (10,8,1)])
980
self.assertDiffBlocks('aBcdEeXcdFg', 'abcdecdfg', [(0, 0, 1), (2, 2, 2),
981
(5, 4, 1), (7, 5, 2), (10, 8, 1)])
983
self.assertDiffBlocks('abbabbXd', 'cabbabxd', [(7,7,1)])
983
self.assertDiffBlocks('abbabbXd', 'cabbabxd', [(7, 7, 1)])
984
984
self.assertDiffBlocks('abbabbbb', 'cabbabbc', [])
985
985
self.assertDiffBlocks('bbbbbbbb', 'cbbbbbbc', [])
1016
1016
chk_ops('', '', [])
1017
1017
chk_ops([], [], [])
1018
chk_ops('abc', '', [('delete', 0,3, 0,0)])
1019
chk_ops('', 'abc', [('insert', 0,0, 0,3)])
1020
chk_ops('abcd', 'abcd', [('equal', 0,4, 0,4)])
1021
chk_ops('abcd', 'abce', [('equal', 0,3, 0,3),
1022
('replace', 3,4, 3,4)
1024
chk_ops('eabc', 'abce', [('delete', 0,1, 0,0),
1025
('equal', 1,4, 0,3),
1026
('insert', 4,4, 3,4)
1028
chk_ops('eabce', 'abce', [('delete', 0,1, 0,0),
1018
chk_ops('abc', '', [('delete', 0, 3, 0, 0)])
1019
chk_ops('', 'abc', [('insert', 0, 0, 0, 3)])
1020
chk_ops('abcd', 'abcd', [('equal', 0, 4, 0, 4)])
1021
chk_ops('abcd', 'abce', [('equal', 0, 3, 0, 3),
1022
('replace', 3, 4, 3, 4)
1024
chk_ops('eabc', 'abce', [('delete', 0, 1, 0, 0),
1025
('equal', 1, 4, 0, 3),
1026
('insert', 4, 4, 3, 4)
1028
chk_ops('eabce', 'abce', [('delete', 0, 1, 0, 0),
1029
('equal', 1, 5, 0, 4)
1031
chk_ops('abcde', 'abXde', [('equal', 0,2, 0,2),
1032
('replace', 2,3, 2,3),
1031
chk_ops('abcde', 'abXde', [('equal', 0, 2, 0, 2),
1032
('replace', 2, 3, 2, 3),
1033
('equal', 3, 5, 3, 5)
1035
chk_ops('abcde', 'abXYZde', [('equal', 0,2, 0,2),
1036
('replace', 2,3, 2,5),
1035
chk_ops('abcde', 'abXYZde', [('equal', 0, 2, 0, 2),
1036
('replace', 2, 3, 2, 5),
1037
('equal', 3, 5, 5, 7)
1039
chk_ops('abde', 'abXYZde', [('equal', 0,2, 0,2),
1040
('insert', 2,2, 2,5),
1039
chk_ops('abde', 'abXYZde', [('equal', 0, 2, 0, 2),
1040
('insert', 2, 2, 2, 5),
1041
('equal', 2, 4, 5, 7)
1043
1043
chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1044
[('equal', 0,6, 0,6),
1045
('insert', 6,6, 6,11),
1046
('equal', 6,16, 11,21)
1044
[('equal', 0, 6, 0, 6),
1045
('insert', 6, 6, 6, 11),
1046
('equal', 6, 16, 11, 21)
1049
1049
[ 'hello there\n'
1051
1051
, 'how are you today?\n'],
1052
1052
[ 'hello there\n'
1053
1053
, 'how are you today?\n'],
1054
[('equal', 0,1, 0,1),
1055
('delete', 1,2, 1,1),
1056
('equal', 2,3, 1,2),
1054
[('equal', 0, 1, 0, 1),
1055
('delete', 1, 2, 1, 1),
1056
('equal', 2, 3, 1, 2),
1058
1058
chk_ops('aBccDe', 'abccde',
1059
[('equal', 0,1, 0,1),
1060
('replace', 1,5, 1,5),
1061
('equal', 5,6, 5,6),
1059
[('equal', 0, 1, 0, 1),
1060
('replace', 1, 5, 1, 5),
1061
('equal', 5, 6, 5, 6),
1063
1063
chk_ops('aBcDec', 'abcdec',
1064
[('equal', 0,1, 0,1),
1065
('replace', 1,2, 1,2),
1066
('equal', 2,3, 2,3),
1067
('replace', 3,4, 3,4),
1068
('equal', 4,6, 4,6),
1064
[('equal', 0, 1, 0, 1),
1065
('replace', 1, 2, 1, 2),
1066
('equal', 2, 3, 2, 3),
1067
('replace', 3, 4, 3, 4),
1068
('equal', 4, 6, 4, 6),
1070
1070
chk_ops('aBcdEcdFg', 'abcdecdfg',
1071
[('equal', 0,1, 0,1),
1072
('replace', 1,8, 1,8),
1071
[('equal', 0, 1, 0, 1),
1072
('replace', 1, 8, 1, 8),
1073
('equal', 8, 9, 8, 9)
1075
1075
chk_ops('aBcdEeXcdFg', 'abcdecdfg',
1076
[('equal', 0,1, 0,1),
1077
('replace', 1,2, 1,2),
1078
('equal', 2,4, 2,4),
1079
('delete', 4,5, 4,4),
1080
('equal', 5,6, 4,5),
1081
('delete', 6,7, 5,5),
1082
('equal', 7,9, 5,7),
1083
('replace', 9,10, 7,8),
1084
('equal', 10,11, 8,9)
1076
[('equal', 0, 1, 0, 1),
1077
('replace', 1, 2, 1, 2),
1078
('equal', 2, 4, 2, 4),
1079
('delete', 4, 5, 4, 4),
1080
('equal', 5, 6, 4, 5),
1081
('delete', 6, 7, 5, 5),
1082
('equal', 7, 9, 5, 7),
1083
('replace', 9, 10, 7, 8),
1084
('equal', 10, 11, 8, 9)
1087
1087
def test_grouped_opcodes(self):
1092
1092
chk_ops('', '', [])
1093
1093
chk_ops([], [], [])
1094
chk_ops('abc', '', [[('delete', 0,3, 0,0)]])
1095
chk_ops('', 'abc', [[('insert', 0,0, 0,3)]])
1094
chk_ops('abc', '', [[('delete', 0, 3, 0, 0)]])
1095
chk_ops('', 'abc', [[('insert', 0, 0, 0, 3)]])
1096
1096
chk_ops('abcd', 'abcd', [])
1097
chk_ops('abcd', 'abce', [[('equal', 0,3, 0,3),
1098
('replace', 3,4, 3,4)
1097
chk_ops('abcd', 'abce', [[('equal', 0, 3, 0, 3),
1098
('replace', 3, 4, 3, 4)
1100
chk_ops('eabc', 'abce', [[('delete', 0,1, 0,0),
1101
('equal', 1,4, 0,3),
1102
('insert', 4,4, 3,4)
1100
chk_ops('eabc', 'abce', [[('delete', 0, 1, 0, 0),
1101
('equal', 1, 4, 0, 3),
1102
('insert', 4, 4, 3, 4)
1104
1104
chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1105
[[('equal', 3,6, 3,6),
1106
('insert', 6,6, 6,11),
1107
('equal', 6,9, 11,14)
1105
[[('equal', 3, 6, 3, 6),
1106
('insert', 6, 6, 6, 11),
1107
('equal', 6, 9, 11, 14)
1109
1109
chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1110
[[('equal', 2,6, 2,6),
1111
('insert', 6,6, 6,11),
1112
('equal', 6,10, 11,15)
1110
[[('equal', 2, 6, 2, 6),
1111
('insert', 6, 6, 6, 11),
1112
('equal', 6, 10, 11, 15)
1114
1114
chk_ops('Xabcdef', 'abcdef',
1115
[[('delete', 0,1, 0,0),
1115
[[('delete', 0, 1, 0, 0),
1116
('equal', 1, 4, 0, 3)
1118
1118
chk_ops('abcdef', 'abcdefX',
1119
[[('equal', 3,6, 3,6),
1120
('insert', 6,6, 6,7)
1119
[[('equal', 3, 6, 3, 6),
1120
('insert', 6, 6, 6, 7)
1131
1131
self.assertDiffBlocks('ABCd efghIjk L',
1132
1132
'AxyzBCn mo pqrstuvwI1 2 L',
1133
[(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1133
[(0, 0, 1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1135
1135
# These are rot13 code snippets.
1136
1136
self.assertDiffBlocks('''\
1178
1178
pynff pzq_zxqve(Pbzznaq):
1179
1179
'''.splitlines(True)
1180
, [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1180
, [(0, 0, 1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1182
1182
def test_patience_unified_diff(self):
1183
1183
txt_a = ['hello there\n',