Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 254688b

Browse files
committedOct 4, 2022
revert : revert needlessly change whitespaces
1 parent 600195f commit 254688b

File tree

1 file changed

+956
-956
lines changed

1 file changed

+956
-956
lines changed
 

‎javascript/tests/diff_match_patch_test.js

Lines changed: 956 additions & 956 deletions
Original file line numberDiff line numberDiff line change
@@ -19,58 +19,58 @@
1919

2020
// If expected and actual are the equivalent, pass the test.
2121
function assertEquivalent(msg, expected, actual) {
22-
if (typeof actual == 'undefined') {
23-
// msg is optional.
24-
actual = expected;
25-
expected = msg;
26-
msg = 'Expected: \'' + expected + '\' Actual: \'' + actual + '\'';
27-
}
28-
if (_equivalent(expected, actual)) {
29-
return assertEquals(msg, String(expected), String(actual));
30-
} else {
31-
return assertEquals(msg, expected, actual);
32-
}
22+
if (typeof actual == 'undefined') {
23+
// msg is optional.
24+
actual = expected;
25+
expected = msg;
26+
msg = 'Expected: \'' + expected + '\' Actual: \'' + actual + '\'';
27+
}
28+
if (_equivalent(expected, actual)) {
29+
return assertEquals(msg, String(expected), String(actual));
30+
} else {
31+
return assertEquals(msg, expected, actual);
32+
}
3333
}
3434

3535

3636
// Are a and b the equivalent? -- Recursive.
3737
function _equivalent(a, b) {
38-
if (a == b) {
39-
return true;
40-
}
41-
if (typeof a == 'object' && typeof b == 'object' && a !== null && b !== null) {
42-
if (a.toString() != b.toString()) {
43-
return false;
44-
}
45-
for (var p in a) {
46-
if (a.hasOwnProperty(p) && !_equivalent(a[p], b[p])) {
47-
return false;
48-
}
49-
}
50-
for (var p in b) {
51-
if (a.hasOwnProperty(p) && !_equivalent(a[p], b[p])) {
52-
return false;
53-
}
54-
}
55-
return true;
56-
}
57-
return false;
38+
if (a == b) {
39+
return true;
40+
}
41+
if (typeof a == 'object' && typeof b == 'object' && a !== null && b !== null) {
42+
if (a.toString() != b.toString()) {
43+
return false;
44+
}
45+
for (var p in a) {
46+
if (a.hasOwnProperty(p) && !_equivalent(a[p], b[p])) {
47+
return false;
48+
}
49+
}
50+
for (var p in b) {
51+
if (a.hasOwnProperty(p) && !_equivalent(a[p], b[p])) {
52+
return false;
53+
}
54+
}
55+
return true;
56+
}
57+
return false;
5858
}
5959

6060

6161
function diff_rebuildtexts(diffs) {
62-
// Construct the two texts which made up the diff originally.
63-
var text1 = '';
64-
var text2 = '';
65-
for (var x = 0; x < diffs.length; x++) {
66-
if (diffs[x][0] != DIFF_INSERT) {
67-
text1 += diffs[x][1];
68-
}
69-
if (diffs[x][0] != DIFF_DELETE) {
70-
text2 += diffs[x][1];
71-
}
72-
}
73-
return [text1, text2];
62+
// Construct the two texts which made up the diff originally.
63+
var text1 = '';
64+
var text2 = '';
65+
for (var x = 0; x < diffs.length; x++) {
66+
if (diffs[x][0] != DIFF_INSERT) {
67+
text1 += diffs[x][1];
68+
}
69+
if (diffs[x][0] != DIFF_DELETE) {
70+
text2 += diffs[x][1];
71+
}
72+
}
73+
return [text1, text2];
7474
}
7575

7676
var dmp = new diff_match_patch();
@@ -80,428 +80,428 @@ var dmp = new diff_match_patch();
8080

8181

8282
function testDiffCommonPrefix() {
83-
// Detect any common prefix.
84-
// Null case.
85-
assertEquals(0, dmp.diff_commonPrefix('abc', 'xyz'));
86-
87-
// Non-null case.
88-
assertEquals(4, dmp.diff_commonPrefix('1234abcdef', '1234xyz'));
89-
90-
// Whole case.
91-
assertEquals(4, dmp.diff_commonPrefix('1234', '1234xyz'));
83+
// Detect any common prefix.
84+
// Null case.
85+
assertEquals(0, dmp.diff_commonPrefix('abc', 'xyz'));
86+
87+
// Non-null case.
88+
assertEquals(4, dmp.diff_commonPrefix('1234abcdef', '1234xyz'));
89+
90+
// Whole case.
91+
assertEquals(4, dmp.diff_commonPrefix('1234', '1234xyz'));
9292
}
9393

9494
function testDiffCommonSuffix() {
95-
// Detect any common suffix.
96-
// Null case.
97-
assertEquals(0, dmp.diff_commonSuffix('abc', 'xyz'));
98-
99-
// Non-null case.
100-
assertEquals(4, dmp.diff_commonSuffix('abcdef1234', 'xyz1234'));
101-
102-
// Whole case.
103-
assertEquals(4, dmp.diff_commonSuffix('1234', 'xyz1234'));
95+
// Detect any common suffix.
96+
// Null case.
97+
assertEquals(0, dmp.diff_commonSuffix('abc', 'xyz'));
98+
99+
// Non-null case.
100+
assertEquals(4, dmp.diff_commonSuffix('abcdef1234', 'xyz1234'));
101+
102+
// Whole case.
103+
assertEquals(4, dmp.diff_commonSuffix('1234', 'xyz1234'));
104104
}
105105

106106
function testDiffCommonOverlap() {
107-
// Detect any suffix/prefix overlap.
108-
// Null case.
109-
assertEquals(0, dmp.diff_commonOverlap_('', 'abcd'));
110-
111-
// Whole case.
112-
assertEquals(3, dmp.diff_commonOverlap_('abc', 'abcd'));
113-
114-
// No overlap.
115-
assertEquals(0, dmp.diff_commonOverlap_('123456', 'abcd'));
116-
117-
// Overlap.
118-
assertEquals(3, dmp.diff_commonOverlap_('123456xxx', 'xxxabcd'));
119-
120-
// Unicode.
121-
// Some overly clever languages (C#) may treat ligatures as equal to their
122-
// component letters. E.g. U+FB01 == 'fi'
123-
assertEquals(0, dmp.diff_commonOverlap_('fi', '\ufb01i'));
107+
// Detect any suffix/prefix overlap.
108+
// Null case.
109+
assertEquals(0, dmp.diff_commonOverlap_('', 'abcd'));
110+
111+
// Whole case.
112+
assertEquals(3, dmp.diff_commonOverlap_('abc', 'abcd'));
113+
114+
// No overlap.
115+
assertEquals(0, dmp.diff_commonOverlap_('123456', 'abcd'));
116+
117+
// Overlap.
118+
assertEquals(3, dmp.diff_commonOverlap_('123456xxx', 'xxxabcd'));
119+
120+
// Unicode.
121+
// Some overly clever languages (C#) may treat ligatures as equal to their
122+
// component letters. E.g. U+FB01 == 'fi'
123+
assertEquals(0, dmp.diff_commonOverlap_('fi', '\ufb01i'));
124124
}
125125

126126
function testDiffHalfMatch() {
127-
// Detect a halfmatch.
128-
dmp.Diff_Timeout = 1;
129-
// No match.
130-
assertEquals(null, dmp.diff_halfMatch_('1234567890', 'abcdef'));
131-
132-
assertEquals(null, dmp.diff_halfMatch_('12345', '23'));
133-
134-
// Single Match.
135-
assertEquivalent(['12', '90', 'a', 'z', '345678'], dmp.diff_halfMatch_('1234567890', 'a345678z'));
136-
137-
assertEquivalent(['a', 'z', '12', '90', '345678'], dmp.diff_halfMatch_('a345678z', '1234567890'));
138-
139-
assertEquivalent(['abc', 'z', '1234', '0', '56789'], dmp.diff_halfMatch_('abc56789z', '1234567890'));
140-
141-
assertEquivalent(['a', 'xyz', '1', '7890', '23456'], dmp.diff_halfMatch_('a23456xyz', '1234567890'));
142-
143-
// Multiple Matches.
144-
assertEquivalent(['12123', '123121', 'a', 'z', '1234123451234'], dmp.diff_halfMatch_('121231234123451234123121', 'a1234123451234z'));
145-
146-
assertEquivalent(['', '-=-=-=-=-=', 'x', '', 'x-=-=-=-=-=-=-='], dmp.diff_halfMatch_('x-=-=-=-=-=-=-=-=-=-=-=-=', 'xx-=-=-=-=-=-=-='));
147-
148-
assertEquivalent(['-=-=-=-=-=', '', '', 'y', '-=-=-=-=-=-=-=y'], dmp.diff_halfMatch_('-=-=-=-=-=-=-=-=-=-=-=-=y', '-=-=-=-=-=-=-=yy'));
149-
150-
// Non-optimal halfmatch.
151-
// Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
152-
assertEquivalent(['qHillo', 'w', 'x', 'Hulloy', 'HelloHe'], dmp.diff_halfMatch_('qHilloHelloHew', 'xHelloHeHulloy'));
153-
154-
// Optimal no halfmatch.
155-
dmp.Diff_Timeout = 0;
156-
assertEquals(null, dmp.diff_halfMatch_('qHilloHelloHew', 'xHelloHeHulloy'));
127+
// Detect a halfmatch.
128+
dmp.Diff_Timeout = 1;
129+
// No match.
130+
assertEquals(null, dmp.diff_halfMatch_('1234567890', 'abcdef'));
131+
132+
assertEquals(null, dmp.diff_halfMatch_('12345', '23'));
133+
134+
// Single Match.
135+
assertEquivalent(['12', '90', 'a', 'z', '345678'], dmp.diff_halfMatch_('1234567890', 'a345678z'));
136+
137+
assertEquivalent(['a', 'z', '12', '90', '345678'], dmp.diff_halfMatch_('a345678z', '1234567890'));
138+
139+
assertEquivalent(['abc', 'z', '1234', '0', '56789'], dmp.diff_halfMatch_('abc56789z', '1234567890'));
140+
141+
assertEquivalent(['a', 'xyz', '1', '7890', '23456'], dmp.diff_halfMatch_('a23456xyz', '1234567890'));
142+
143+
// Multiple Matches.
144+
assertEquivalent(['12123', '123121', 'a', 'z', '1234123451234'], dmp.diff_halfMatch_('121231234123451234123121', 'a1234123451234z'));
145+
146+
assertEquivalent(['', '-=-=-=-=-=', 'x', '', 'x-=-=-=-=-=-=-='], dmp.diff_halfMatch_('x-=-=-=-=-=-=-=-=-=-=-=-=', 'xx-=-=-=-=-=-=-='));
147+
148+
assertEquivalent(['-=-=-=-=-=', '', '', 'y', '-=-=-=-=-=-=-=y'], dmp.diff_halfMatch_('-=-=-=-=-=-=-=-=-=-=-=-=y', '-=-=-=-=-=-=-=yy'));
149+
150+
// Non-optimal halfmatch.
151+
// Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
152+
assertEquivalent(['qHillo', 'w', 'x', 'Hulloy', 'HelloHe'], dmp.diff_halfMatch_('qHilloHelloHew', 'xHelloHeHulloy'));
153+
154+
// Optimal no halfmatch.
155+
dmp.Diff_Timeout = 0;
156+
assertEquals(null, dmp.diff_halfMatch_('qHilloHelloHew', 'xHelloHeHulloy'));
157157
}
158158

159159
function testDiffLinesToChars() {
160-
function assertLinesToCharsResultEquals(a, b) {
161-
assertEquals(a.chars1, b.chars1);
162-
assertEquals(a.chars2, b.chars2);
163-
assertEquivalent(a.lineArray, b.lineArray);
164-
}
165-
166-
// Convert lines down to characters.
167-
assertLinesToCharsResultEquals({chars1: '\x01\x02\x01', chars2: '\x02\x01\x02', lineArray: ['', 'alpha\n', 'beta\n']}, dmp.diff_linesToChars_('alpha\nbeta\nalpha\n', 'beta\nalpha\nbeta\n'));
168-
169-
assertLinesToCharsResultEquals({chars1: '', chars2: '\x01\x02\x03\x03', lineArray: ['', 'alpha\r\n', 'beta\r\n', '\r\n']}, dmp.diff_linesToChars_('', 'alpha\r\nbeta\r\n\r\n\r\n'));
170-
171-
assertLinesToCharsResultEquals({chars1: '\x01', chars2: '\x02', lineArray: ['', 'a', 'b']}, dmp.diff_linesToChars_('a', 'b'));
172-
173-
// More than 256 to reveal any 8-bit limitations.
174-
var n = 300;
175-
var lineList = [];
176-
var charList = [];
177-
for (var i = 1; i < n + 1; i++) {
178-
lineList[i - 1] = i + '\n';
179-
charList[i - 1] = String.fromCharCode(i);
180-
}
181-
assertEquals(n, lineList.length);
182-
var lines = lineList.join('');
183-
var chars = charList.join('');
184-
assertEquals(n, chars.length);
185-
lineList.unshift('');
186-
assertLinesToCharsResultEquals({chars1: chars, chars2: '', lineArray: lineList}, dmp.diff_linesToChars_(lines, ''));
160+
function assertLinesToCharsResultEquals(a, b) {
161+
assertEquals(a.chars1, b.chars1);
162+
assertEquals(a.chars2, b.chars2);
163+
assertEquivalent(a.lineArray, b.lineArray);
164+
}
165+
166+
// Convert lines down to characters.
167+
assertLinesToCharsResultEquals({chars1: '\x01\x02\x01', chars2: '\x02\x01\x02', lineArray: ['', 'alpha\n', 'beta\n']}, dmp.diff_linesToChars_('alpha\nbeta\nalpha\n', 'beta\nalpha\nbeta\n'));
168+
169+
assertLinesToCharsResultEquals({chars1: '', chars2: '\x01\x02\x03\x03', lineArray: ['', 'alpha\r\n', 'beta\r\n', '\r\n']}, dmp.diff_linesToChars_('', 'alpha\r\nbeta\r\n\r\n\r\n'));
170+
171+
assertLinesToCharsResultEquals({chars1: '\x01', chars2: '\x02', lineArray: ['', 'a', 'b']}, dmp.diff_linesToChars_('a', 'b'));
172+
173+
// More than 256 to reveal any 8-bit limitations.
174+
var n = 300;
175+
var lineList = [];
176+
var charList = [];
177+
for (var i = 1; i < n + 1; i++) {
178+
lineList[i - 1] = i + '\n';
179+
charList[i - 1] = String.fromCharCode(i);
180+
}
181+
assertEquals(n, lineList.length);
182+
var lines = lineList.join('');
183+
var chars = charList.join('');
184+
assertEquals(n, chars.length);
185+
lineList.unshift('');
186+
assertLinesToCharsResultEquals({chars1: chars, chars2: '', lineArray: lineList}, dmp.diff_linesToChars_(lines, ''));
187187
}
188188

189189
function testDiffCharsToLines() {
190-
// Convert chars up to lines.
191-
var diffs = [[DIFF_EQUAL, '\x01\x02\x01'], [DIFF_INSERT, '\x02\x01\x02']];
192-
dmp.diff_charsToLines_(diffs, ['', 'alpha\n', 'beta\n']);
193-
assertEquivalent([[DIFF_EQUAL, 'alpha\nbeta\nalpha\n'], [DIFF_INSERT, 'beta\nalpha\nbeta\n']], diffs);
194-
195-
// More than 256 to reveal any 8-bit limitations.
196-
var n = 300;
197-
var lineList = [];
198-
var charList = [];
199-
for (var i = 1; i < n + 1; i++) {
200-
lineList[i - 1] = i + '\n';
201-
charList[i - 1] = String.fromCharCode(i);
202-
}
203-
assertEquals(n, lineList.length);
204-
var lines = lineList.join('');
205-
var chars = charList.join('');
206-
assertEquals(n, chars.length);
207-
lineList.unshift('');
208-
var diffs = [[DIFF_DELETE, chars]];
209-
dmp.diff_charsToLines_(diffs, lineList);
210-
assertEquivalent([[DIFF_DELETE, lines]], diffs);
211-
212-
// More than 65536 to verify any 16-bit limitation.
213-
lineList = [];
214-
for (var i = 0; i < 66000; i++) {
215-
lineList[i] = i + '\n';
216-
}
217-
chars = lineList.join('');
218-
var results = dmp.diff_linesToChars_(chars, '');
219-
diffs = [[DIFF_INSERT, results.chars1]];
220-
dmp.diff_charsToLines_(diffs, results.lineArray);
221-
assertEquals(chars, diffs[0][1]);
190+
// Convert chars up to lines.
191+
var diffs = [[DIFF_EQUAL, '\x01\x02\x01'], [DIFF_INSERT, '\x02\x01\x02']];
192+
dmp.diff_charsToLines_(diffs, ['', 'alpha\n', 'beta\n']);
193+
assertEquivalent([[DIFF_EQUAL, 'alpha\nbeta\nalpha\n'], [DIFF_INSERT, 'beta\nalpha\nbeta\n']], diffs);
194+
195+
// More than 256 to reveal any 8-bit limitations.
196+
var n = 300;
197+
var lineList = [];
198+
var charList = [];
199+
for (var i = 1; i < n + 1; i++) {
200+
lineList[i - 1] = i + '\n';
201+
charList[i - 1] = String.fromCharCode(i);
202+
}
203+
assertEquals(n, lineList.length);
204+
var lines = lineList.join('');
205+
var chars = charList.join('');
206+
assertEquals(n, chars.length);
207+
lineList.unshift('');
208+
var diffs = [[DIFF_DELETE, chars]];
209+
dmp.diff_charsToLines_(diffs, lineList);
210+
assertEquivalent([[DIFF_DELETE, lines]], diffs);
211+
212+
// More than 65536 to verify any 16-bit limitation.
213+
lineList = [];
214+
for (var i = 0; i < 66000; i++) {
215+
lineList[i] = i + '\n';
216+
}
217+
chars = lineList.join('');
218+
var results = dmp.diff_linesToChars_(chars, '');
219+
diffs = [[DIFF_INSERT, results.chars1]];
220+
dmp.diff_charsToLines_(diffs, results.lineArray);
221+
assertEquals(chars, diffs[0][1]);
222222
}
223223

224224
function testDiffCleanupMerge() {
225-
// Cleanup a messy diff.
226-
// Null case.
227-
var diffs = [];
228-
dmp.diff_cleanupMerge(diffs);
229-
assertEquivalent([], diffs);
230-
231-
// No change case.
232-
diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_INSERT, 'c']];
233-
dmp.diff_cleanupMerge(diffs);
234-
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_INSERT, 'c']], diffs);
235-
236-
// Merge equalities.
237-
diffs = [[DIFF_EQUAL, 'a'], [DIFF_EQUAL, 'b'], [DIFF_EQUAL, 'c']];
238-
dmp.diff_cleanupMerge(diffs);
239-
assertEquivalent([[DIFF_EQUAL, 'abc']], diffs);
240-
241-
// Merge deletions.
242-
diffs = [[DIFF_DELETE, 'a'], [DIFF_DELETE, 'b'], [DIFF_DELETE, 'c']];
243-
dmp.diff_cleanupMerge(diffs);
244-
assertEquivalent([[DIFF_DELETE, 'abc']], diffs);
245-
246-
// Merge insertions.
247-
diffs = [[DIFF_INSERT, 'a'], [DIFF_INSERT, 'b'], [DIFF_INSERT, 'c']];
248-
dmp.diff_cleanupMerge(diffs);
249-
assertEquivalent([[DIFF_INSERT, 'abc']], diffs);
250-
251-
// Merge interweave.
252-
diffs = [[DIFF_DELETE, 'a'], [DIFF_INSERT, 'b'], [DIFF_DELETE, 'c'], [DIFF_INSERT, 'd'], [DIFF_EQUAL, 'e'], [DIFF_EQUAL, 'f']];
253-
dmp.diff_cleanupMerge(diffs);
254-
assertEquivalent([[DIFF_DELETE, 'ac'], [DIFF_INSERT, 'bd'], [DIFF_EQUAL, 'ef']], diffs);
255-
256-
// Prefix and suffix detection.
257-
diffs = [[DIFF_DELETE, 'a'], [DIFF_INSERT, 'abc'], [DIFF_DELETE, 'dc']];
258-
dmp.diff_cleanupMerge(diffs);
259-
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'd'], [DIFF_INSERT, 'b'], [DIFF_EQUAL, 'c']], diffs);
260-
261-
// Prefix and suffix detection with equalities.
262-
diffs = [[DIFF_EQUAL, 'x'], [DIFF_DELETE, 'a'], [DIFF_INSERT, 'abc'], [DIFF_DELETE, 'dc'], [DIFF_EQUAL, 'y']];
263-
dmp.diff_cleanupMerge(diffs);
264-
assertEquivalent([[DIFF_EQUAL, 'xa'], [DIFF_DELETE, 'd'], [DIFF_INSERT, 'b'], [DIFF_EQUAL, 'cy']], diffs);
265-
266-
// Slide edit left.
267-
diffs = [[DIFF_EQUAL, 'a'], [DIFF_INSERT, 'ba'], [DIFF_EQUAL, 'c']];
268-
dmp.diff_cleanupMerge(diffs);
269-
assertEquivalent([[DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'ac']], diffs);
270-
271-
// Slide edit right.
272-
diffs = [[DIFF_EQUAL, 'c'], [DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'a']];
273-
dmp.diff_cleanupMerge(diffs);
274-
assertEquivalent([[DIFF_EQUAL, 'ca'], [DIFF_INSERT, 'ba']], diffs);
275-
276-
// Slide edit left recursive.
277-
diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_EQUAL, 'c'], [DIFF_DELETE, 'ac'], [DIFF_EQUAL, 'x']];
278-
dmp.diff_cleanupMerge(diffs);
279-
assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'acx']], diffs);
280-
281-
// Slide edit right recursive.
282-
diffs = [[DIFF_EQUAL, 'x'], [DIFF_DELETE, 'ca'], [DIFF_EQUAL, 'c'], [DIFF_DELETE, 'b'], [DIFF_EQUAL, 'a']];
283-
dmp.diff_cleanupMerge(diffs);
284-
assertEquivalent([[DIFF_EQUAL, 'xca'], [DIFF_DELETE, 'cba']], diffs);
285-
286-
// Empty merge.
287-
diffs = [[DIFF_DELETE, 'b'], [DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'c']];
288-
dmp.diff_cleanupMerge(diffs);
289-
assertEquivalent([[DIFF_INSERT, 'a'], [DIFF_EQUAL, 'bc']], diffs);
290-
291-
// Empty equality.
292-
diffs = [[DIFF_EQUAL, ''], [DIFF_INSERT, 'a'], [DIFF_EQUAL, 'b']];
293-
dmp.diff_cleanupMerge(diffs);
294-
assertEquivalent([[DIFF_INSERT, 'a'], [DIFF_EQUAL, 'b']], diffs);
225+
// Cleanup a messy diff.
226+
// Null case.
227+
var diffs = [];
228+
dmp.diff_cleanupMerge(diffs);
229+
assertEquivalent([], diffs);
230+
231+
// No change case.
232+
diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_INSERT, 'c']];
233+
dmp.diff_cleanupMerge(diffs);
234+
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_INSERT, 'c']], diffs);
235+
236+
// Merge equalities.
237+
diffs = [[DIFF_EQUAL, 'a'], [DIFF_EQUAL, 'b'], [DIFF_EQUAL, 'c']];
238+
dmp.diff_cleanupMerge(diffs);
239+
assertEquivalent([[DIFF_EQUAL, 'abc']], diffs);
240+
241+
// Merge deletions.
242+
diffs = [[DIFF_DELETE, 'a'], [DIFF_DELETE, 'b'], [DIFF_DELETE, 'c']];
243+
dmp.diff_cleanupMerge(diffs);
244+
assertEquivalent([[DIFF_DELETE, 'abc']], diffs);
245+
246+
// Merge insertions.
247+
diffs = [[DIFF_INSERT, 'a'], [DIFF_INSERT, 'b'], [DIFF_INSERT, 'c']];
248+
dmp.diff_cleanupMerge(diffs);
249+
assertEquivalent([[DIFF_INSERT, 'abc']], diffs);
250+
251+
// Merge interweave.
252+
diffs = [[DIFF_DELETE, 'a'], [DIFF_INSERT, 'b'], [DIFF_DELETE, 'c'], [DIFF_INSERT, 'd'], [DIFF_EQUAL, 'e'], [DIFF_EQUAL, 'f']];
253+
dmp.diff_cleanupMerge(diffs);
254+
assertEquivalent([[DIFF_DELETE, 'ac'], [DIFF_INSERT, 'bd'], [DIFF_EQUAL, 'ef']], diffs);
255+
256+
// Prefix and suffix detection.
257+
diffs = [[DIFF_DELETE, 'a'], [DIFF_INSERT, 'abc'], [DIFF_DELETE, 'dc']];
258+
dmp.diff_cleanupMerge(diffs);
259+
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'd'], [DIFF_INSERT, 'b'], [DIFF_EQUAL, 'c']], diffs);
260+
261+
// Prefix and suffix detection with equalities.
262+
diffs = [[DIFF_EQUAL, 'x'], [DIFF_DELETE, 'a'], [DIFF_INSERT, 'abc'], [DIFF_DELETE, 'dc'], [DIFF_EQUAL, 'y']];
263+
dmp.diff_cleanupMerge(diffs);
264+
assertEquivalent([[DIFF_EQUAL, 'xa'], [DIFF_DELETE, 'd'], [DIFF_INSERT, 'b'], [DIFF_EQUAL, 'cy']], diffs);
265+
266+
// Slide edit left.
267+
diffs = [[DIFF_EQUAL, 'a'], [DIFF_INSERT, 'ba'], [DIFF_EQUAL, 'c']];
268+
dmp.diff_cleanupMerge(diffs);
269+
assertEquivalent([[DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'ac']], diffs);
270+
271+
// Slide edit right.
272+
diffs = [[DIFF_EQUAL, 'c'], [DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'a']];
273+
dmp.diff_cleanupMerge(diffs);
274+
assertEquivalent([[DIFF_EQUAL, 'ca'], [DIFF_INSERT, 'ba']], diffs);
275+
276+
// Slide edit left recursive.
277+
diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_EQUAL, 'c'], [DIFF_DELETE, 'ac'], [DIFF_EQUAL, 'x']];
278+
dmp.diff_cleanupMerge(diffs);
279+
assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'acx']], diffs);
280+
281+
// Slide edit right recursive.
282+
diffs = [[DIFF_EQUAL, 'x'], [DIFF_DELETE, 'ca'], [DIFF_EQUAL, 'c'], [DIFF_DELETE, 'b'], [DIFF_EQUAL, 'a']];
283+
dmp.diff_cleanupMerge(diffs);
284+
assertEquivalent([[DIFF_EQUAL, 'xca'], [DIFF_DELETE, 'cba']], diffs);
285+
286+
// Empty merge.
287+
diffs = [[DIFF_DELETE, 'b'], [DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'c']];
288+
dmp.diff_cleanupMerge(diffs);
289+
assertEquivalent([[DIFF_INSERT, 'a'], [DIFF_EQUAL, 'bc']], diffs);
290+
291+
// Empty equality.
292+
diffs = [[DIFF_EQUAL, ''], [DIFF_INSERT, 'a'], [DIFF_EQUAL, 'b']];
293+
dmp.diff_cleanupMerge(diffs);
294+
assertEquivalent([[DIFF_INSERT, 'a'], [DIFF_EQUAL, 'b']], diffs);
295295
}
296296

297297
function testDiffCleanupSemanticLossless() {
298-
// Slide diffs to match logical boundaries.
299-
// Null case.
300-
var diffs = [];
301-
dmp.diff_cleanupSemanticLossless(diffs);
302-
assertEquivalent([], diffs);
303-
304-
// Blank lines.
305-
diffs = [[DIFF_EQUAL, 'AAA\r\n\r\nBBB'], [DIFF_INSERT, '\r\nDDD\r\n\r\nBBB'], [DIFF_EQUAL, '\r\nEEE']];
306-
dmp.diff_cleanupSemanticLossless(diffs);
307-
assertEquivalent([[DIFF_EQUAL, 'AAA\r\n\r\n'], [DIFF_INSERT, 'BBB\r\nDDD\r\n\r\n'], [DIFF_EQUAL, 'BBB\r\nEEE']], diffs);
308-
309-
// Line boundaries.
310-
diffs = [[DIFF_EQUAL, 'AAA\r\nBBB'], [DIFF_INSERT, ' DDD\r\nBBB'], [DIFF_EQUAL, ' EEE']];
311-
dmp.diff_cleanupSemanticLossless(diffs);
312-
assertEquivalent([[DIFF_EQUAL, 'AAA\r\n'], [DIFF_INSERT, 'BBB DDD\r\n'], [DIFF_EQUAL, 'BBB EEE']], diffs);
313-
314-
// Word boundaries.
315-
diffs = [[DIFF_EQUAL, 'The c'], [DIFF_INSERT, 'ow and the c'], [DIFF_EQUAL, 'at.']];
316-
dmp.diff_cleanupSemanticLossless(diffs);
317-
assertEquivalent([[DIFF_EQUAL, 'The '], [DIFF_INSERT, 'cow and the '], [DIFF_EQUAL, 'cat.']], diffs);
318-
319-
// Alphanumeric boundaries.
320-
diffs = [[DIFF_EQUAL, 'The-c'], [DIFF_INSERT, 'ow-and-the-c'], [DIFF_EQUAL, 'at.']];
321-
dmp.diff_cleanupSemanticLossless(diffs);
322-
assertEquivalent([[DIFF_EQUAL, 'The-'], [DIFF_INSERT, 'cow-and-the-'], [DIFF_EQUAL, 'cat.']], diffs);
323-
324-
// Hitting the start.
325-
diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'a'], [DIFF_EQUAL, 'ax']];
326-
dmp.diff_cleanupSemanticLossless(diffs);
327-
assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_EQUAL, 'aax']], diffs);
328-
329-
// Hitting the end.
330-
diffs = [[DIFF_EQUAL, 'xa'], [DIFF_DELETE, 'a'], [DIFF_EQUAL, 'a']];
331-
dmp.diff_cleanupSemanticLossless(diffs);
332-
assertEquivalent([[DIFF_EQUAL, 'xaa'], [DIFF_DELETE, 'a']], diffs);
333-
334-
// Sentence boundaries.
335-
diffs = [[DIFF_EQUAL, 'The xxx. The '], [DIFF_INSERT, 'zzz. The '], [DIFF_EQUAL, 'yyy.']];
336-
dmp.diff_cleanupSemanticLossless(diffs);
337-
assertEquivalent([[DIFF_EQUAL, 'The xxx.'], [DIFF_INSERT, ' The zzz.'], [DIFF_EQUAL, ' The yyy.']], diffs);
298+
// Slide diffs to match logical boundaries.
299+
// Null case.
300+
var diffs = [];
301+
dmp.diff_cleanupSemanticLossless(diffs);
302+
assertEquivalent([], diffs);
303+
304+
// Blank lines.
305+
diffs = [[DIFF_EQUAL, 'AAA\r\n\r\nBBB'], [DIFF_INSERT, '\r\nDDD\r\n\r\nBBB'], [DIFF_EQUAL, '\r\nEEE']];
306+
dmp.diff_cleanupSemanticLossless(diffs);
307+
assertEquivalent([[DIFF_EQUAL, 'AAA\r\n\r\n'], [DIFF_INSERT, 'BBB\r\nDDD\r\n\r\n'], [DIFF_EQUAL, 'BBB\r\nEEE']], diffs);
308+
309+
// Line boundaries.
310+
diffs = [[DIFF_EQUAL, 'AAA\r\nBBB'], [DIFF_INSERT, ' DDD\r\nBBB'], [DIFF_EQUAL, ' EEE']];
311+
dmp.diff_cleanupSemanticLossless(diffs);
312+
assertEquivalent([[DIFF_EQUAL, 'AAA\r\n'], [DIFF_INSERT, 'BBB DDD\r\n'], [DIFF_EQUAL, 'BBB EEE']], diffs);
313+
314+
// Word boundaries.
315+
diffs = [[DIFF_EQUAL, 'The c'], [DIFF_INSERT, 'ow and the c'], [DIFF_EQUAL, 'at.']];
316+
dmp.diff_cleanupSemanticLossless(diffs);
317+
assertEquivalent([[DIFF_EQUAL, 'The '], [DIFF_INSERT, 'cow and the '], [DIFF_EQUAL, 'cat.']], diffs);
318+
319+
// Alphanumeric boundaries.
320+
diffs = [[DIFF_EQUAL, 'The-c'], [DIFF_INSERT, 'ow-and-the-c'], [DIFF_EQUAL, 'at.']];
321+
dmp.diff_cleanupSemanticLossless(diffs);
322+
assertEquivalent([[DIFF_EQUAL, 'The-'], [DIFF_INSERT, 'cow-and-the-'], [DIFF_EQUAL, 'cat.']], diffs);
323+
324+
// Hitting the start.
325+
diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'a'], [DIFF_EQUAL, 'ax']];
326+
dmp.diff_cleanupSemanticLossless(diffs);
327+
assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_EQUAL, 'aax']], diffs);
328+
329+
// Hitting the end.
330+
diffs = [[DIFF_EQUAL, 'xa'], [DIFF_DELETE, 'a'], [DIFF_EQUAL, 'a']];
331+
dmp.diff_cleanupSemanticLossless(diffs);
332+
assertEquivalent([[DIFF_EQUAL, 'xaa'], [DIFF_DELETE, 'a']], diffs);
333+
334+
// Sentence boundaries.
335+
diffs = [[DIFF_EQUAL, 'The xxx. The '], [DIFF_INSERT, 'zzz. The '], [DIFF_EQUAL, 'yyy.']];
336+
dmp.diff_cleanupSemanticLossless(diffs);
337+
assertEquivalent([[DIFF_EQUAL, 'The xxx.'], [DIFF_INSERT, ' The zzz.'], [DIFF_EQUAL, ' The yyy.']], diffs);
338338
}
339339

340340
function testDiffCleanupSemantic() {
341-
// Cleanup semantically trivial equalities.
342-
// Null case.
343-
var diffs = [];
344-
dmp.diff_cleanupSemantic(diffs);
345-
assertEquivalent([], diffs);
346-
347-
// No elimination #1.
348-
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, 'cd'], [DIFF_EQUAL, '12'], [DIFF_DELETE, 'e']];
349-
dmp.diff_cleanupSemantic(diffs);
350-
assertEquivalent([[DIFF_DELETE, 'ab'], [DIFF_INSERT, 'cd'], [DIFF_EQUAL, '12'], [DIFF_DELETE, 'e']], diffs);
351-
352-
// No elimination #2.
353-
diffs = [[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'ABC'], [DIFF_EQUAL, '1234'], [DIFF_DELETE, 'wxyz']];
354-
dmp.diff_cleanupSemantic(diffs);
355-
assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'ABC'], [DIFF_EQUAL, '1234'], [DIFF_DELETE, 'wxyz']], diffs);
356-
357-
// Simple elimination.
358-
diffs = [[DIFF_DELETE, 'a'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, 'c']];
359-
dmp.diff_cleanupSemantic(diffs);
360-
assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'b']], diffs);
361-
362-
// Backpass elimination.
363-
diffs = [[DIFF_DELETE, 'ab'], [DIFF_EQUAL, 'cd'], [DIFF_DELETE, 'e'], [DIFF_EQUAL, 'f'], [DIFF_INSERT, 'g']];
364-
dmp.diff_cleanupSemantic(diffs);
365-
assertEquivalent([[DIFF_DELETE, 'abcdef'], [DIFF_INSERT, 'cdfg']], diffs);
366-
367-
// Multiple eliminations.
368-
diffs = [[DIFF_INSERT, '1'], [DIFF_EQUAL, 'A'], [DIFF_DELETE, 'B'], [DIFF_INSERT, '2'], [DIFF_EQUAL, '_'], [DIFF_INSERT, '1'], [DIFF_EQUAL, 'A'], [DIFF_DELETE, 'B'], [DIFF_INSERT, '2']];
369-
dmp.diff_cleanupSemantic(diffs);
370-
assertEquivalent([[DIFF_DELETE, 'AB_AB'], [DIFF_INSERT, '1A2_1A2']], diffs);
371-
372-
// Word boundaries.
373-
diffs = [[DIFF_EQUAL, 'The c'], [DIFF_DELETE, 'ow and the c'], [DIFF_EQUAL, 'at.']];
374-
dmp.diff_cleanupSemantic(diffs);
375-
assertEquivalent([[DIFF_EQUAL, 'The '], [DIFF_DELETE, 'cow and the '], [DIFF_EQUAL, 'cat.']], diffs);
376-
377-
// No overlap elimination.
378-
diffs = [[DIFF_DELETE, 'abcxx'], [DIFF_INSERT, 'xxdef']];
379-
dmp.diff_cleanupSemantic(diffs);
380-
assertEquivalent([[DIFF_DELETE, 'abcxx'], [DIFF_INSERT, 'xxdef']], diffs);
381-
382-
// Overlap elimination.
383-
diffs = [[DIFF_DELETE, 'abcxxx'], [DIFF_INSERT, 'xxxdef']];
384-
dmp.diff_cleanupSemantic(diffs);
385-
assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'xxx'], [DIFF_INSERT, 'def']], diffs);
386-
387-
// Reverse overlap elimination.
388-
diffs = [[DIFF_DELETE, 'xxxabc'], [DIFF_INSERT, 'defxxx']];
389-
dmp.diff_cleanupSemantic(diffs);
390-
assertEquivalent([[DIFF_INSERT, 'def'], [DIFF_EQUAL, 'xxx'], [DIFF_DELETE, 'abc']], diffs);
391-
392-
// Two overlap eliminations.
393-
diffs = [[DIFF_DELETE, 'abcd1212'], [DIFF_INSERT, '1212efghi'], [DIFF_EQUAL, '----'], [DIFF_DELETE, 'A3'], [DIFF_INSERT, '3BC']];
394-
dmp.diff_cleanupSemantic(diffs);
395-
assertEquivalent([[DIFF_DELETE, 'abcd'], [DIFF_EQUAL, '1212'], [DIFF_INSERT, 'efghi'], [DIFF_EQUAL, '----'], [DIFF_DELETE, 'A'], [DIFF_EQUAL, '3'], [DIFF_INSERT, 'BC']], diffs);
341+
// Cleanup semantically trivial equalities.
342+
// Null case.
343+
var diffs = [];
344+
dmp.diff_cleanupSemantic(diffs);
345+
assertEquivalent([], diffs);
346+
347+
// No elimination #1.
348+
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, 'cd'], [DIFF_EQUAL, '12'], [DIFF_DELETE, 'e']];
349+
dmp.diff_cleanupSemantic(diffs);
350+
assertEquivalent([[DIFF_DELETE, 'ab'], [DIFF_INSERT, 'cd'], [DIFF_EQUAL, '12'], [DIFF_DELETE, 'e']], diffs);
351+
352+
// No elimination #2.
353+
diffs = [[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'ABC'], [DIFF_EQUAL, '1234'], [DIFF_DELETE, 'wxyz']];
354+
dmp.diff_cleanupSemantic(diffs);
355+
assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'ABC'], [DIFF_EQUAL, '1234'], [DIFF_DELETE, 'wxyz']], diffs);
356+
357+
// Simple elimination.
358+
diffs = [[DIFF_DELETE, 'a'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, 'c']];
359+
dmp.diff_cleanupSemantic(diffs);
360+
assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'b']], diffs);
361+
362+
// Backpass elimination.
363+
diffs = [[DIFF_DELETE, 'ab'], [DIFF_EQUAL, 'cd'], [DIFF_DELETE, 'e'], [DIFF_EQUAL, 'f'], [DIFF_INSERT, 'g']];
364+
dmp.diff_cleanupSemantic(diffs);
365+
assertEquivalent([[DIFF_DELETE, 'abcdef'], [DIFF_INSERT, 'cdfg']], diffs);
366+
367+
// Multiple eliminations.
368+
diffs = [[DIFF_INSERT, '1'], [DIFF_EQUAL, 'A'], [DIFF_DELETE, 'B'], [DIFF_INSERT, '2'], [DIFF_EQUAL, '_'], [DIFF_INSERT, '1'], [DIFF_EQUAL, 'A'], [DIFF_DELETE, 'B'], [DIFF_INSERT, '2']];
369+
dmp.diff_cleanupSemantic(diffs);
370+
assertEquivalent([[DIFF_DELETE, 'AB_AB'], [DIFF_INSERT, '1A2_1A2']], diffs);
371+
372+
// Word boundaries.
373+
diffs = [[DIFF_EQUAL, 'The c'], [DIFF_DELETE, 'ow and the c'], [DIFF_EQUAL, 'at.']];
374+
dmp.diff_cleanupSemantic(diffs);
375+
assertEquivalent([[DIFF_EQUAL, 'The '], [DIFF_DELETE, 'cow and the '], [DIFF_EQUAL, 'cat.']], diffs);
376+
377+
// No overlap elimination.
378+
diffs = [[DIFF_DELETE, 'abcxx'], [DIFF_INSERT, 'xxdef']];
379+
dmp.diff_cleanupSemantic(diffs);
380+
assertEquivalent([[DIFF_DELETE, 'abcxx'], [DIFF_INSERT, 'xxdef']], diffs);
381+
382+
// Overlap elimination.
383+
diffs = [[DIFF_DELETE, 'abcxxx'], [DIFF_INSERT, 'xxxdef']];
384+
dmp.diff_cleanupSemantic(diffs);
385+
assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'xxx'], [DIFF_INSERT, 'def']], diffs);
386+
387+
// Reverse overlap elimination.
388+
diffs = [[DIFF_DELETE, 'xxxabc'], [DIFF_INSERT, 'defxxx']];
389+
dmp.diff_cleanupSemantic(diffs);
390+
assertEquivalent([[DIFF_INSERT, 'def'], [DIFF_EQUAL, 'xxx'], [DIFF_DELETE, 'abc']], diffs);
391+
392+
// Two overlap eliminations.
393+
diffs = [[DIFF_DELETE, 'abcd1212'], [DIFF_INSERT, '1212efghi'], [DIFF_EQUAL, '----'], [DIFF_DELETE, 'A3'], [DIFF_INSERT, '3BC']];
394+
dmp.diff_cleanupSemantic(diffs);
395+
assertEquivalent([[DIFF_DELETE, 'abcd'], [DIFF_EQUAL, '1212'], [DIFF_INSERT, 'efghi'], [DIFF_EQUAL, '----'], [DIFF_DELETE, 'A'], [DIFF_EQUAL, '3'], [DIFF_INSERT, 'BC']], diffs);
396396
}
397397

398398
function testDiffCleanupEfficiency() {
399-
// Cleanup operationally trivial equalities.
400-
dmp.Diff_EditCost = 4;
401-
// Null case.
402-
var diffs = [];
403-
dmp.diff_cleanupEfficiency(diffs);
404-
assertEquivalent([], diffs);
405-
406-
// No elimination.
407-
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
408-
dmp.diff_cleanupEfficiency(diffs);
409-
assertEquivalent([[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']], diffs);
410-
411-
// Four-edit elimination.
412-
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'xyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
413-
dmp.diff_cleanupEfficiency(diffs);
414-
assertEquivalent([[DIFF_DELETE, 'abxyzcd'], [DIFF_INSERT, '12xyz34']], diffs);
415-
416-
// Three-edit elimination.
417-
diffs = [[DIFF_INSERT, '12'], [DIFF_EQUAL, 'x'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
418-
dmp.diff_cleanupEfficiency(diffs);
419-
assertEquivalent([[DIFF_DELETE, 'xcd'], [DIFF_INSERT, '12x34']], diffs);
420-
421-
// Backpass elimination.
422-
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'xy'], [DIFF_INSERT, '34'], [DIFF_EQUAL, 'z'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '56']];
423-
dmp.diff_cleanupEfficiency(diffs);
424-
assertEquivalent([[DIFF_DELETE, 'abxyzcd'], [DIFF_INSERT, '12xy34z56']], diffs);
425-
426-
// High cost elimination.
427-
dmp.Diff_EditCost = 5;
428-
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
429-
dmp.diff_cleanupEfficiency(diffs);
430-
assertEquivalent([[DIFF_DELETE, 'abwxyzcd'], [DIFF_INSERT, '12wxyz34']], diffs);
431-
dmp.Diff_EditCost = 4;
399+
// Cleanup operationally trivial equalities.
400+
dmp.Diff_EditCost = 4;
401+
// Null case.
402+
var diffs = [];
403+
dmp.diff_cleanupEfficiency(diffs);
404+
assertEquivalent([], diffs);
405+
406+
// No elimination.
407+
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
408+
dmp.diff_cleanupEfficiency(diffs);
409+
assertEquivalent([[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']], diffs);
410+
411+
// Four-edit elimination.
412+
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'xyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
413+
dmp.diff_cleanupEfficiency(diffs);
414+
assertEquivalent([[DIFF_DELETE, 'abxyzcd'], [DIFF_INSERT, '12xyz34']], diffs);
415+
416+
// Three-edit elimination.
417+
diffs = [[DIFF_INSERT, '12'], [DIFF_EQUAL, 'x'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
418+
dmp.diff_cleanupEfficiency(diffs);
419+
assertEquivalent([[DIFF_DELETE, 'xcd'], [DIFF_INSERT, '12x34']], diffs);
420+
421+
// Backpass elimination.
422+
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'xy'], [DIFF_INSERT, '34'], [DIFF_EQUAL, 'z'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '56']];
423+
dmp.diff_cleanupEfficiency(diffs);
424+
assertEquivalent([[DIFF_DELETE, 'abxyzcd'], [DIFF_INSERT, '12xy34z56']], diffs);
425+
426+
// High cost elimination.
427+
dmp.Diff_EditCost = 5;
428+
diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
429+
dmp.diff_cleanupEfficiency(diffs);
430+
assertEquivalent([[DIFF_DELETE, 'abwxyzcd'], [DIFF_INSERT, '12wxyz34']], diffs);
431+
dmp.Diff_EditCost = 4;
432432
}
433433

434434
function testDiffPrettyHtml() {
435-
// Pretty print.
436-
var diffs = [[DIFF_EQUAL, 'a\n'], [DIFF_DELETE, '<B>b</B>'], [DIFF_INSERT, 'c&d']];
437-
assertEquals('<span>a&para;<br></span><del style="background:#ffe6e6;">&lt;B&gt;b&lt;/B&gt;</del><ins style="background:#e6ffe6;">c&amp;d</ins>', dmp.diff_prettyHtml(diffs));
435+
// Pretty print.
436+
var diffs = [[DIFF_EQUAL, 'a\n'], [DIFF_DELETE, '<B>b</B>'], [DIFF_INSERT, 'c&d']];
437+
assertEquals('<span>a&para;<br></span><del style="background:#ffe6e6;">&lt;B&gt;b&lt;/B&gt;</del><ins style="background:#e6ffe6;">c&amp;d</ins>', dmp.diff_prettyHtml(diffs));
438438
}
439439

440440
function testDiffText() {
441-
// Compute the source and destination texts.
442-
var diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, ' lazy']];
443-
assertEquals('jumps over the lazy', dmp.diff_text1(diffs));
444-
445-
assertEquals('jumped over a lazy', dmp.diff_text2(diffs));
441+
// Compute the source and destination texts.
442+
var diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, ' lazy']];
443+
assertEquals('jumps over the lazy', dmp.diff_text1(diffs));
444+
445+
assertEquals('jumped over a lazy', dmp.diff_text2(diffs));
446446
}
447447

448448
function testDiffDelta() {
449-
// Convert a diff into delta string.
450-
var diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, ' lazy'], [DIFF_INSERT, 'old dog']];
451-
var text1 = dmp.diff_text1(diffs);
452-
assertEquals('jumps over the lazy', text1);
453-
454-
var delta = dmp.diff_toDelta(diffs);
455-
assertEquals('=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog', delta);
456-
457-
// Convert delta string into a diff.
458-
assertEquivalent(diffs, dmp.diff_fromDelta(text1, delta));
459-
460-
// Generates error (19 != 20).
461-
try {
462-
dmp.diff_fromDelta(text1 + 'x', delta);
463-
assertEquals(Error, null);
464-
} catch (e) {
465-
// Exception expected.
466-
}
467-
468-
// Generates error (19 != 18).
469-
try {
470-
dmp.diff_fromDelta(text1.substring(1), delta);
471-
assertEquals(Error, null);
472-
} catch (e) {
473-
// Exception expected.
474-
}
475-
476-
// Generates error (%c3%xy invalid Unicode).
477-
try {
478-
dmp.diff_fromDelta('', '+%c3%xy');
479-
assertEquals(Error, null);
480-
} catch (e) {
481-
// Exception expected.
482-
}
483-
484-
// Test deltas with special characters.
485-
diffs = [[DIFF_EQUAL, '\u0680 \x00 \t %'], [DIFF_DELETE, '\u0681 \x01 \n ^'], [DIFF_INSERT, '\u0682 \x02 \\ |']];
486-
text1 = dmp.diff_text1(diffs);
487-
assertEquals('\u0680 \x00 \t %\u0681 \x01 \n ^', text1);
488-
489-
delta = dmp.diff_toDelta(diffs);
490-
assertEquals('=7\t-7\t+%DA%82 %02 %5C %7C', delta);
491-
492-
// Convert delta string into a diff.
493-
assertEquivalent(diffs, dmp.diff_fromDelta(text1, delta));
494-
495-
diffs = [[DIFF_EQUAL, '\ud83d\ude4b\ud83d'], [DIFF_INSERT, '\ude4c\ud83d'], [DIFF_EQUAL, '\ude4b']];
496-
try {
497-
delta = dmp.diff_toDelta(diffs);
498-
assertEquals('=2\t+%F0%9F%99%8C\t=2', delta);
499-
} catch ( e ) {
500-
assertEquals(false, true);
501-
}
502-
503-
(function(){
504-
const originalText = `U+1F17x 🅰️ 🅱️ 🅾️ 🅿️ safhawifhkw
449+
// Convert a diff into delta string.
450+
var diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, ' lazy'], [DIFF_INSERT, 'old dog']];
451+
var text1 = dmp.diff_text1(diffs);
452+
assertEquals('jumps over the lazy', text1);
453+
454+
var delta = dmp.diff_toDelta(diffs);
455+
assertEquals('=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog', delta);
456+
457+
// Convert delta string into a diff.
458+
assertEquivalent(diffs, dmp.diff_fromDelta(text1, delta));
459+
460+
// Generates error (19 != 20).
461+
try {
462+
dmp.diff_fromDelta(text1 + 'x', delta);
463+
assertEquals(Error, null);
464+
} catch (e) {
465+
// Exception expected.
466+
}
467+
468+
// Generates error (19 != 18).
469+
try {
470+
dmp.diff_fromDelta(text1.substring(1), delta);
471+
assertEquals(Error, null);
472+
} catch (e) {
473+
// Exception expected.
474+
}
475+
476+
// Generates error (%c3%xy invalid Unicode).
477+
try {
478+
dmp.diff_fromDelta('', '+%c3%xy');
479+
assertEquals(Error, null);
480+
} catch (e) {
481+
// Exception expected.
482+
}
483+
484+
// Test deltas with special characters.
485+
diffs = [[DIFF_EQUAL, '\u0680 \x00 \t %'], [DIFF_DELETE, '\u0681 \x01 \n ^'], [DIFF_INSERT, '\u0682 \x02 \\ |']];
486+
text1 = dmp.diff_text1(diffs);
487+
assertEquals('\u0680 \x00 \t %\u0681 \x01 \n ^', text1);
488+
489+
delta = dmp.diff_toDelta(diffs);
490+
assertEquals('=7\t-7\t+%DA%82 %02 %5C %7C', delta);
491+
492+
// Convert delta string into a diff.
493+
assertEquivalent(diffs, dmp.diff_fromDelta(text1, delta));
494+
495+
diffs = [[DIFF_EQUAL, '\ud83d\ude4b\ud83d'], [DIFF_INSERT, '\ude4c\ud83d'], [DIFF_EQUAL, '\ude4b']];
496+
try {
497+
delta = dmp.diff_toDelta(diffs);
498+
assertEquals('=2\t+%F0%9F%99%8C\t=2', delta);
499+
} catch ( e ) {
500+
assertEquals(false, true);
501+
}
502+
503+
(function(){
504+
const originalText = `U+1F17x 🅰️ 🅱️ 🅾️ 🅿️ safhawifhkw
505505
U+1F18x 🆎
506506
0 1 2 3 4 5 6 7 8 9 A B C D E F
507507
U+1F19x 🆑 🆒 🆓 🆔 🆕 🆖 🆗 🆘 🆙 🆚
@@ -512,585 +512,585 @@ function testDiffDelta() {
512512
U+1F25x 🉐 🉑
513513
U+1F30x 🌀 🌁 🌂 🌃 🌄 🌅 🌆 🌇 🌈 🌉 🌊 🌋 🌌 🌍 🌎 🌏
514514
U+1F31x 🌐 🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘 🌙 🌚 🌛 🌜 🌝 🌞 `;
515-
516-
// applies some random edits to string and returns new, edited string
517-
function applyRandomTextEdit(text) {
518-
let textArr = [...text];
519-
let r = Math.random();
520-
if(r < 1/3) { // swap
521-
let swapCount = Math.floor(Math.random()*5);
522-
for(let i = 0; i < swapCount; i++) {
523-
let swapPos1 = Math.floor(Math.random()*textArr.length);
524-
let swapPos2 = Math.floor(Math.random()*textArr.length);
525-
let char1 = textArr[swapPos1];
526-
let char2 = textArr[swapPos2];
527-
textArr[swapPos1] = char2;
528-
textArr[swapPos2] = char1;
529-
}
530-
} else if(r < 2/3) { // remove
531-
let removeCount = Math.floor(Math.random()*5);
532-
for(let i = 0; i < removeCount; i++) {
533-
let removePos = Math.floor(Math.random()*textArr.length);
534-
textArr[removePos] = "";
535-
}
536-
} else { // add
537-
let addCount = Math.floor(Math.random()*5);
538-
for(let i = 0; i < addCount; i++) {
539-
let addPos = Math.floor(Math.random()*textArr.length);
540-
let addFromPos = Math.floor(Math.random()*textArr.length);
541-
textArr[addPos] = textArr[addPos] + textArr[addFromPos];
542-
}
543-
}
544-
return textArr.join("");
545-
}
546-
547-
for(let i = 0; i < 1000; i++) {
548-
newText = applyRandomTextEdit(originalText);
549-
dmp.diff_toDelta(dmp.diff_main(originalText, newText));
550-
}
551-
})();
552-
553-
// Unicode - splitting surrogates
554-
try {
555-
assertEquivalent(
556-
dmp.diff_toDelta([[DIFF_INSERT,'\ud83c\udd71'], [DIFF_EQUAL, '\ud83c\udd70\ud83c\udd71']]),
557-
dmp.diff_toDelta(dmp.diff_main('\ud83c\udd70\ud83c\udd71', '\ud83c\udd71\ud83c\udd70\ud83c\udd71'))
558-
);
559-
} catch ( e ) {
560-
assertEquals('Inserting similar surrogate pair at beginning', 'crashed');
561-
}
562-
563-
try {
564-
assertEquivalent(
565-
dmp.diff_toDelta([[DIFF_EQUAL,'\ud83c\udd70'], [DIFF_INSERT, '\ud83c\udd70'], [DIFF_EQUAL, '\ud83c\udd71']]),
566-
dmp.diff_toDelta(dmp.diff_main('\ud83c\udd70\ud83c\udd71', '\ud83c\udd70\ud83c\udd70\ud83c\udd71'))
567-
);
568-
} catch ( e ) {
569-
assertEquals('Inserting similar surrogate pair in the middle', 'crashed');
570-
}
571-
572-
try {
573-
assertEquivalent(
574-
dmp.diff_toDelta([[DIFF_DELETE,'\ud83c\udd71'], [DIFF_EQUAL, '\ud83c\udd70\ud83c\udd71']]),
575-
dmp.diff_toDelta(dmp.diff_main('\ud83c\udd71\ud83c\udd70\ud83c\udd71', '\ud83c\udd70\ud83c\udd71'))
576-
);
577-
} catch ( e ) {
578-
assertEquals('Deleting similar surrogate pair at the beginning', 'crashed');
579-
}
580-
581-
try {
582-
assertEquivalent(
583-
dmp.diff_toDelta([[DIFF_EQUAL, '\ud83c\udd70'], [DIFF_DELETE,'\ud83c\udd72'], [DIFF_EQUAL, '\ud83c\udd71']]),
584-
dmp.diff_toDelta(dmp.diff_main('\ud83c\udd70\ud83c\udd72\ud83c\udd71', '\ud83c\udd70\ud83c\udd71'))
585-
);
586-
} catch ( e ) {
587-
assertEquals('Deleting similar surrogate pair in the middle', 'crashed');
588-
}
589-
590-
try {
591-
assertEquivalent(
592-
dmp.diff_toDelta([[DIFF_DELETE, '\ud83c\udd70'], [DIFF_INSERT, '\ud83c\udd71']]),
593-
dmp.diff_toDelta([[DIFF_EQUAL, '\ud83c'], [DIFF_DELETE, '\udd70'], [DIFF_INSERT, '\udd71']]),
594-
);
595-
} catch ( e ) {
596-
assertEquals('Swap surrogate pair', 'crashed');
597-
}
598-
599-
try {
600-
assertEquivalent(
601-
dmp.diff_toDelta([[DIFF_INSERT, '\ud83c\udd70'], [DIFF_DELETE, '\ud83c\udd71']]),
602-
dmp.diff_toDelta([[DIFF_EQUAL, '\ud83c'], [DIFF_INSERT, '\udd70'], [DIFF_DELETE, '\udd71']]),
603-
);
604-
} catch ( e ) {
605-
assertEquals('Swap surrogate pair', 'crashed');
606-
}
607-
608-
// Empty diff groups
609-
assertEquivalent(
610-
dmp.diff_toDelta([[DIFF_EQUAL, 'abcdef'], [DIFF_DELETE, ''], [DIFF_INSERT, 'ghijk']]),
611-
dmp.diff_toDelta([[DIFF_EQUAL, 'abcdef'], [DIFF_INSERT, 'ghijk']]),
612-
);
613-
614-
// Different versions of the library may have created deltas with
615-
// half of a surrogate pair encoded as if it were valid UTF-8
616-
try {
617-
assertEquivalent(
618-
dmp.diff_toDelta(dmp.diff_fromDelta('\ud83c\udd70', '-2\t+%F0%9F%85%B1')),
619-
dmp.diff_toDelta(dmp.diff_fromDelta('\ud83c\udd70', '=1\t-1\t+%ED%B5%B1'))
620-
);
621-
} catch ( e ) {
622-
assertEquals('Decode UTF8-encoded surrogate half', 'crashed');
623-
}
624-
625-
// Verify pool of unchanged characters.
626-
diffs = [[DIFF_INSERT, 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ']];
627-
var text2 = dmp.diff_text2(diffs);
628-
assertEquals('A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ', text2);
629-
630-
delta = dmp.diff_toDelta(diffs);
631-
assertEquals('+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ', delta);
632-
633-
// Convert delta string into a diff.
634-
assertEquivalent(diffs, dmp.diff_fromDelta('', delta));
635-
636-
// 160 kb string.
637-
var a = 'abcdefghij';
638-
for (var i = 0; i < 14; i++) {
639-
a += a;
640-
}
641-
diffs = [[DIFF_INSERT, a]];
642-
delta = dmp.diff_toDelta(diffs);
643-
assertEquals('+' + a, delta);
644-
645-
// Convert delta string into a diff.
646-
assertEquivalent(diffs, dmp.diff_fromDelta('', delta));
515+
516+
// applies some random edits to string and returns new, edited string
517+
function applyRandomTextEdit(text) {
518+
let textArr = [...text];
519+
let r = Math.random();
520+
if(r < 1/3) { // swap
521+
let swapCount = Math.floor(Math.random()*5);
522+
for(let i = 0; i < swapCount; i++) {
523+
let swapPos1 = Math.floor(Math.random()*textArr.length);
524+
let swapPos2 = Math.floor(Math.random()*textArr.length);
525+
let char1 = textArr[swapPos1];
526+
let char2 = textArr[swapPos2];
527+
textArr[swapPos1] = char2;
528+
textArr[swapPos2] = char1;
529+
}
530+
} else if(r < 2/3) { // remove
531+
let removeCount = Math.floor(Math.random()*5);
532+
for(let i = 0; i < removeCount; i++) {
533+
let removePos = Math.floor(Math.random()*textArr.length);
534+
textArr[removePos] = "";
535+
}
536+
} else { // add
537+
let addCount = Math.floor(Math.random()*5);
538+
for(let i = 0; i < addCount; i++) {
539+
let addPos = Math.floor(Math.random()*textArr.length);
540+
let addFromPos = Math.floor(Math.random()*textArr.length);
541+
textArr[addPos] = textArr[addPos] + textArr[addFromPos];
542+
}
543+
}
544+
return textArr.join("");
545+
}
546+
547+
for(let i = 0; i < 1000; i++) {
548+
newText = applyRandomTextEdit(originalText);
549+
dmp.diff_toDelta(dmp.diff_main(originalText, newText));
550+
}
551+
})();
552+
553+
// Unicode - splitting surrogates
554+
try {
555+
assertEquivalent(
556+
dmp.diff_toDelta([[DIFF_INSERT,'\ud83c\udd71'], [DIFF_EQUAL, '\ud83c\udd70\ud83c\udd71']]),
557+
dmp.diff_toDelta(dmp.diff_main('\ud83c\udd70\ud83c\udd71', '\ud83c\udd71\ud83c\udd70\ud83c\udd71'))
558+
);
559+
} catch ( e ) {
560+
assertEquals('Inserting similar surrogate pair at beginning', 'crashed');
561+
}
562+
563+
try {
564+
assertEquivalent(
565+
dmp.diff_toDelta([[DIFF_EQUAL,'\ud83c\udd70'], [DIFF_INSERT, '\ud83c\udd70'], [DIFF_EQUAL, '\ud83c\udd71']]),
566+
dmp.diff_toDelta(dmp.diff_main('\ud83c\udd70\ud83c\udd71', '\ud83c\udd70\ud83c\udd70\ud83c\udd71'))
567+
);
568+
} catch ( e ) {
569+
assertEquals('Inserting similar surrogate pair in the middle', 'crashed');
570+
}
571+
572+
try {
573+
assertEquivalent(
574+
dmp.diff_toDelta([[DIFF_DELETE,'\ud83c\udd71'], [DIFF_EQUAL, '\ud83c\udd70\ud83c\udd71']]),
575+
dmp.diff_toDelta(dmp.diff_main('\ud83c\udd71\ud83c\udd70\ud83c\udd71', '\ud83c\udd70\ud83c\udd71'))
576+
);
577+
} catch ( e ) {
578+
assertEquals('Deleting similar surrogate pair at the beginning', 'crashed');
579+
}
580+
581+
try {
582+
assertEquivalent(
583+
dmp.diff_toDelta([[DIFF_EQUAL, '\ud83c\udd70'], [DIFF_DELETE,'\ud83c\udd72'], [DIFF_EQUAL, '\ud83c\udd71']]),
584+
dmp.diff_toDelta(dmp.diff_main('\ud83c\udd70\ud83c\udd72\ud83c\udd71', '\ud83c\udd70\ud83c\udd71'))
585+
);
586+
} catch ( e ) {
587+
assertEquals('Deleting similar surrogate pair in the middle', 'crashed');
588+
}
589+
590+
try {
591+
assertEquivalent(
592+
dmp.diff_toDelta([[DIFF_DELETE, '\ud83c\udd70'], [DIFF_INSERT, '\ud83c\udd71']]),
593+
dmp.diff_toDelta([[DIFF_EQUAL, '\ud83c'], [DIFF_DELETE, '\udd70'], [DIFF_INSERT, '\udd71']]),
594+
);
595+
} catch ( e ) {
596+
assertEquals('Swap surrogate pair', 'crashed');
597+
}
598+
599+
try {
600+
assertEquivalent(
601+
dmp.diff_toDelta([[DIFF_INSERT, '\ud83c\udd70'], [DIFF_DELETE, '\ud83c\udd71']]),
602+
dmp.diff_toDelta([[DIFF_EQUAL, '\ud83c'], [DIFF_INSERT, '\udd70'], [DIFF_DELETE, '\udd71']]),
603+
);
604+
} catch ( e ) {
605+
assertEquals('Swap surrogate pair', 'crashed');
606+
}
607+
608+
// Empty diff groups
609+
assertEquivalent(
610+
dmp.diff_toDelta([[DIFF_EQUAL, 'abcdef'], [DIFF_DELETE, ''], [DIFF_INSERT, 'ghijk']]),
611+
dmp.diff_toDelta([[DIFF_EQUAL, 'abcdef'], [DIFF_INSERT, 'ghijk']]),
612+
);
613+
614+
// Different versions of the library may have created deltas with
615+
// half of a surrogate pair encoded as if it were valid UTF-8
616+
try {
617+
assertEquivalent(
618+
dmp.diff_toDelta(dmp.diff_fromDelta('\ud83c\udd70', '-2\t+%F0%9F%85%B1')),
619+
dmp.diff_toDelta(dmp.diff_fromDelta('\ud83c\udd70', '=1\t-1\t+%ED%B5%B1'))
620+
);
621+
} catch ( e ) {
622+
assertEquals('Decode UTF8-encoded surrogate half', 'crashed');
623+
}
624+
625+
// Verify pool of unchanged characters.
626+
diffs = [[DIFF_INSERT, 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ']];
627+
var text2 = dmp.diff_text2(diffs);
628+
assertEquals('A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ', text2);
629+
630+
delta = dmp.diff_toDelta(diffs);
631+
assertEquals('+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ', delta);
632+
633+
// Convert delta string into a diff.
634+
assertEquivalent(diffs, dmp.diff_fromDelta('', delta));
635+
636+
// 160 kb string.
637+
var a = 'abcdefghij';
638+
for (var i = 0; i < 14; i++) {
639+
a += a;
640+
}
641+
diffs = [[DIFF_INSERT, a]];
642+
delta = dmp.diff_toDelta(diffs);
643+
assertEquals('+' + a, delta);
644+
645+
// Convert delta string into a diff.
646+
assertEquivalent(diffs, dmp.diff_fromDelta('', delta));
647647
}
648648

649649
function testDiffXIndex() {
650-
// Translate a location in text1 to text2.
651-
// Translation on equality.
652-
assertEquals(5, dmp.diff_xIndex([[DIFF_DELETE, 'a'], [DIFF_INSERT, '1234'], [DIFF_EQUAL, 'xyz']], 2));
653-
654-
// Translation on deletion.
655-
assertEquals(1, dmp.diff_xIndex([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '1234'], [DIFF_EQUAL, 'xyz']], 3));
650+
// Translate a location in text1 to text2.
651+
// Translation on equality.
652+
assertEquals(5, dmp.diff_xIndex([[DIFF_DELETE, 'a'], [DIFF_INSERT, '1234'], [DIFF_EQUAL, 'xyz']], 2));
653+
654+
// Translation on deletion.
655+
assertEquals(1, dmp.diff_xIndex([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '1234'], [DIFF_EQUAL, 'xyz']], 3));
656656
}
657657

658658
function testDiffLevenshtein() {
659-
// Levenshtein with trailing equality.
660-
assertEquals(4, dmp.diff_levenshtein([[DIFF_DELETE, 'abc'], [DIFF_INSERT, '1234'], [DIFF_EQUAL, 'xyz']]));
661-
// Levenshtein with leading equality.
662-
assertEquals(4, dmp.diff_levenshtein([[DIFF_EQUAL, 'xyz'], [DIFF_DELETE, 'abc'], [DIFF_INSERT, '1234']]));
663-
// Levenshtein with middle equality.
664-
assertEquals(7, dmp.diff_levenshtein([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'xyz'], [DIFF_INSERT, '1234']]));
659+
// Levenshtein with trailing equality.
660+
assertEquals(4, dmp.diff_levenshtein([[DIFF_DELETE, 'abc'], [DIFF_INSERT, '1234'], [DIFF_EQUAL, 'xyz']]));
661+
// Levenshtein with leading equality.
662+
assertEquals(4, dmp.diff_levenshtein([[DIFF_EQUAL, 'xyz'], [DIFF_DELETE, 'abc'], [DIFF_INSERT, '1234']]));
663+
// Levenshtein with middle equality.
664+
assertEquals(7, dmp.diff_levenshtein([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'xyz'], [DIFF_INSERT, '1234']]));
665665
}
666666

667667
function testDiffBisect() {
668-
// Normal.
669-
var a = 'cat';
670-
var b = 'map';
671-
// Since the resulting diff hasn't been normalized, it would be ok if
672-
// the insertion and deletion pairs are swapped.
673-
// If the order changes, tweak this test as required.
674-
assertEquivalent([[DIFF_DELETE, 'c'], [DIFF_INSERT, 'm'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, 't'], [DIFF_INSERT, 'p']], dmp.diff_bisect_(a, b, Number.MAX_VALUE));
675-
676-
// Timeout.
677-
assertEquivalent([[DIFF_DELETE, 'cat'], [DIFF_INSERT, 'map']], dmp.diff_bisect_(a, b, 0));
668+
// Normal.
669+
var a = 'cat';
670+
var b = 'map';
671+
// Since the resulting diff hasn't been normalized, it would be ok if
672+
// the insertion and deletion pairs are swapped.
673+
// If the order changes, tweak this test as required.
674+
assertEquivalent([[DIFF_DELETE, 'c'], [DIFF_INSERT, 'm'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, 't'], [DIFF_INSERT, 'p']], dmp.diff_bisect_(a, b, Number.MAX_VALUE));
675+
676+
// Timeout.
677+
assertEquivalent([[DIFF_DELETE, 'cat'], [DIFF_INSERT, 'map']], dmp.diff_bisect_(a, b, 0));
678678
}
679679

680680
function testDiffMain() {
681-
// Perform a trivial diff.
682-
// Null case.
683-
assertEquivalent([], dmp.diff_main('', '', false));
684-
685-
// Equality.
686-
assertEquivalent([[DIFF_EQUAL, 'abc']], dmp.diff_main('abc', 'abc', false));
687-
688-
// Simple insertion.
689-
assertEquivalent([[DIFF_EQUAL, 'ab'], [DIFF_INSERT, '123'], [DIFF_EQUAL, 'c']], dmp.diff_main('abc', 'ab123c', false));
690-
691-
// Simple deletion.
692-
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '123'], [DIFF_EQUAL, 'bc']], dmp.diff_main('a123bc', 'abc', false));
693-
694-
// Two insertions.
695-
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_INSERT, '123'], [DIFF_EQUAL, 'b'], [DIFF_INSERT, '456'], [DIFF_EQUAL, 'c']], dmp.diff_main('abc', 'a123b456c', false));
696-
697-
// Two deletions.
698-
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '123'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, '456'], [DIFF_EQUAL, 'c']], dmp.diff_main('a123b456c', 'abc', false));
699-
700-
// Perform a real diff.
701-
// Switch off the timeout.
702-
dmp.Diff_Timeout = 0;
703-
// Simple cases.
704-
assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_INSERT, 'b']], dmp.diff_main('a', 'b', false));
705-
706-
assertEquivalent([[DIFF_DELETE, 'Apple'], [DIFF_INSERT, 'Banana'], [DIFF_EQUAL, 's are a'], [DIFF_INSERT, 'lso'], [DIFF_EQUAL, ' fruit.']], dmp.diff_main('Apples are a fruit.', 'Bananas are also fruit.', false));
707-
708-
assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_INSERT, '\u0680'], [DIFF_EQUAL, 'x'], [DIFF_DELETE, '\t'], [DIFF_INSERT, '\0']], dmp.diff_main('ax\t', '\u0680x\0', false));
709-
710-
// Overlaps.
711-
assertEquivalent([[DIFF_DELETE, '1'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, 'y'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, '2'], [DIFF_INSERT, 'xab']], dmp.diff_main('1ayb2', 'abxab', false));
712-
713-
assertEquivalent([[DIFF_INSERT, 'xaxcx'], [DIFF_EQUAL, 'abc'], [DIFF_DELETE, 'y']], dmp.diff_main('abcy', 'xaxcxabc', false));
714-
715-
assertEquivalent([[DIFF_DELETE, 'ABCD'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, '='], [DIFF_INSERT, '-'], [DIFF_EQUAL, 'bcd'], [DIFF_DELETE, '='], [DIFF_INSERT, '-'], [DIFF_EQUAL, 'efghijklmnopqrs'], [DIFF_DELETE, 'EFGHIJKLMNOefg']], dmp.diff_main('ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg', 'a-bcd-efghijklmnopqrs', false));
716-
717-
// Large equality.
718-
assertEquivalent([[DIFF_INSERT, ' '], [DIFF_EQUAL, 'a'], [DIFF_INSERT, 'nd'], [DIFF_EQUAL, ' [[Pennsylvania]]'], [DIFF_DELETE, ' and [[New']], dmp.diff_main('a [[Pennsylvania]] and [[New', ' and [[Pennsylvania]]', false));
719-
720-
// Timeout.
721-
dmp.Diff_Timeout = 0.1; // 100ms
722-
var a = '`Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.\n';
723-
var b = 'I am the very model of a modern major general,\nI\'ve information vegetable, animal, and mineral,\nI know the kings of England, and I quote the fights historical,\nFrom Marathon to Waterloo, in order categorical.\n';
724-
// Increase the text lengths by 1024 times to ensure a timeout.
725-
for (var i = 0; i < 10; i++) {
726-
a += a;
727-
b += b;
728-
}
729-
var startTime = (new Date()).getTime();
730-
dmp.diff_main(a, b);
731-
var endTime = (new Date()).getTime();
732-
// Test that we took at least the timeout period.
733-
assertTrue(dmp.Diff_Timeout * 1000 <= endTime - startTime);
734-
// Test that we didn't take forever (be forgiving).
735-
// Theoretically this test could fail very occasionally if the
736-
// OS task swaps or locks up for a second at the wrong moment.
737-
assertTrue(dmp.Diff_Timeout * 1000 * 2 > endTime - startTime);
738-
dmp.Diff_Timeout = 0;
739-
740-
// Test the linemode speedup.
741-
// Must be long to pass the 100 char cutoff.
742-
// Simple line-mode.
743-
a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n';
744-
b = 'abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n';
745-
assertEquivalent(dmp.diff_main(a, b, false), dmp.diff_main(a, b, true));
746-
747-
// Single line-mode.
748-
a = '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890';
749-
b = 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij';
750-
assertEquivalent(dmp.diff_main(a, b, false), dmp.diff_main(a, b, true));
751-
752-
// Overlap line-mode.
753-
a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n';
754-
b = 'abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n';
755-
var texts_linemode = diff_rebuildtexts(dmp.diff_main(a, b, true));
756-
var texts_textmode = diff_rebuildtexts(dmp.diff_main(a, b, false));
757-
assertEquivalent(texts_textmode, texts_linemode);
758-
759-
// Test null inputs.
760-
try {
761-
dmp.diff_main(null, null);
762-
assertEquals(Error, null);
763-
} catch (e) {
764-
// Exception expected.
765-
}
681+
// Perform a trivial diff.
682+
// Null case.
683+
assertEquivalent([], dmp.diff_main('', '', false));
684+
685+
// Equality.
686+
assertEquivalent([[DIFF_EQUAL, 'abc']], dmp.diff_main('abc', 'abc', false));
687+
688+
// Simple insertion.
689+
assertEquivalent([[DIFF_EQUAL, 'ab'], [DIFF_INSERT, '123'], [DIFF_EQUAL, 'c']], dmp.diff_main('abc', 'ab123c', false));
690+
691+
// Simple deletion.
692+
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '123'], [DIFF_EQUAL, 'bc']], dmp.diff_main('a123bc', 'abc', false));
693+
694+
// Two insertions.
695+
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_INSERT, '123'], [DIFF_EQUAL, 'b'], [DIFF_INSERT, '456'], [DIFF_EQUAL, 'c']], dmp.diff_main('abc', 'a123b456c', false));
696+
697+
// Two deletions.
698+
assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '123'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, '456'], [DIFF_EQUAL, 'c']], dmp.diff_main('a123b456c', 'abc', false));
699+
700+
// Perform a real diff.
701+
// Switch off the timeout.
702+
dmp.Diff_Timeout = 0;
703+
// Simple cases.
704+
assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_INSERT, 'b']], dmp.diff_main('a', 'b', false));
705+
706+
assertEquivalent([[DIFF_DELETE, 'Apple'], [DIFF_INSERT, 'Banana'], [DIFF_EQUAL, 's are a'], [DIFF_INSERT, 'lso'], [DIFF_EQUAL, ' fruit.']], dmp.diff_main('Apples are a fruit.', 'Bananas are also fruit.', false));
707+
708+
assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_INSERT, '\u0680'], [DIFF_EQUAL, 'x'], [DIFF_DELETE, '\t'], [DIFF_INSERT, '\0']], dmp.diff_main('ax\t', '\u0680x\0', false));
709+
710+
// Overlaps.
711+
assertEquivalent([[DIFF_DELETE, '1'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, 'y'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, '2'], [DIFF_INSERT, 'xab']], dmp.diff_main('1ayb2', 'abxab', false));
712+
713+
assertEquivalent([[DIFF_INSERT, 'xaxcx'], [DIFF_EQUAL, 'abc'], [DIFF_DELETE, 'y']], dmp.diff_main('abcy', 'xaxcxabc', false));
714+
715+
assertEquivalent([[DIFF_DELETE, 'ABCD'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, '='], [DIFF_INSERT, '-'], [DIFF_EQUAL, 'bcd'], [DIFF_DELETE, '='], [DIFF_INSERT, '-'], [DIFF_EQUAL, 'efghijklmnopqrs'], [DIFF_DELETE, 'EFGHIJKLMNOefg']], dmp.diff_main('ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg', 'a-bcd-efghijklmnopqrs', false));
716+
717+
// Large equality.
718+
assertEquivalent([[DIFF_INSERT, ' '], [DIFF_EQUAL, 'a'], [DIFF_INSERT, 'nd'], [DIFF_EQUAL, ' [[Pennsylvania]]'], [DIFF_DELETE, ' and [[New']], dmp.diff_main('a [[Pennsylvania]] and [[New', ' and [[Pennsylvania]]', false));
719+
720+
// Timeout.
721+
dmp.Diff_Timeout = 0.1; // 100ms
722+
var a = '`Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.\n';
723+
var b = 'I am the very model of a modern major general,\nI\'ve information vegetable, animal, and mineral,\nI know the kings of England, and I quote the fights historical,\nFrom Marathon to Waterloo, in order categorical.\n';
724+
// Increase the text lengths by 1024 times to ensure a timeout.
725+
for (var i = 0; i < 10; i++) {
726+
a += a;
727+
b += b;
728+
}
729+
var startTime = (new Date()).getTime();
730+
dmp.diff_main(a, b);
731+
var endTime = (new Date()).getTime();
732+
// Test that we took at least the timeout period.
733+
assertTrue(dmp.Diff_Timeout * 1000 <= endTime - startTime);
734+
// Test that we didn't take forever (be forgiving).
735+
// Theoretically this test could fail very occasionally if the
736+
// OS task swaps or locks up for a second at the wrong moment.
737+
assertTrue(dmp.Diff_Timeout * 1000 * 2 > endTime - startTime);
738+
dmp.Diff_Timeout = 0;
739+
740+
// Test the linemode speedup.
741+
// Must be long to pass the 100 char cutoff.
742+
// Simple line-mode.
743+
a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n';
744+
b = 'abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n';
745+
assertEquivalent(dmp.diff_main(a, b, false), dmp.diff_main(a, b, true));
746+
747+
// Single line-mode.
748+
a = '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890';
749+
b = 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij';
750+
assertEquivalent(dmp.diff_main(a, b, false), dmp.diff_main(a, b, true));
751+
752+
// Overlap line-mode.
753+
a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n';
754+
b = 'abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n';
755+
var texts_linemode = diff_rebuildtexts(dmp.diff_main(a, b, true));
756+
var texts_textmode = diff_rebuildtexts(dmp.diff_main(a, b, false));
757+
assertEquivalent(texts_textmode, texts_linemode);
758+
759+
// Test null inputs.
760+
try {
761+
dmp.diff_main(null, null);
762+
assertEquals(Error, null);
763+
} catch (e) {
764+
// Exception expected.
765+
}
766766
}
767767

768768

769769
// MATCH TEST FUNCTIONS
770770

771771

772772
function testMatchAlphabet() {
773-
// Initialise the bitmasks for Bitap.
774-
// Unique.
775-
assertEquivalent({'a':4, 'b':2, 'c':1}, dmp.match_alphabet_('abc'));
776-
777-
// Duplicates.
778-
assertEquivalent({'a':37, 'b':18, 'c':8}, dmp.match_alphabet_('abcaba'));
773+
// Initialise the bitmasks for Bitap.
774+
// Unique.
775+
assertEquivalent({'a':4, 'b':2, 'c':1}, dmp.match_alphabet_('abc'));
776+
777+
// Duplicates.
778+
assertEquivalent({'a':37, 'b':18, 'c':8}, dmp.match_alphabet_('abcaba'));
779779
}
780780

781781
function testMatchBitap() {
782-
// Bitap algorithm.
783-
dmp.Match_Distance = 100;
784-
dmp.Match_Threshold = 0.5;
785-
// Exact matches.
786-
assertEquals(5, dmp.match_bitap_('abcdefghijk', 'fgh', 5));
787-
788-
assertEquals(5, dmp.match_bitap_('abcdefghijk', 'fgh', 0));
789-
790-
// Fuzzy matches.
791-
assertEquals(4, dmp.match_bitap_('abcdefghijk', 'efxhi', 0));
792-
793-
assertEquals(2, dmp.match_bitap_('abcdefghijk', 'cdefxyhijk', 5));
794-
795-
assertEquals(-1, dmp.match_bitap_('abcdefghijk', 'bxy', 1));
796-
797-
// Overflow.
798-
assertEquals(2, dmp.match_bitap_('123456789xx0', '3456789x0', 2));
799-
800-
// Threshold test.
801-
dmp.Match_Threshold = 0.4;
802-
assertEquals(4, dmp.match_bitap_('abcdefghijk', 'efxyhi', 1));
803-
804-
dmp.Match_Threshold = 0.3;
805-
assertEquals(-1, dmp.match_bitap_('abcdefghijk', 'efxyhi', 1));
806-
807-
dmp.Match_Threshold = 0.0;
808-
assertEquals(1, dmp.match_bitap_('abcdefghijk', 'bcdef', 1));
809-
dmp.Match_Threshold = 0.5;
810-
811-
// Multiple select.
812-
assertEquals(0, dmp.match_bitap_('abcdexyzabcde', 'abccde', 3));
813-
814-
assertEquals(8, dmp.match_bitap_('abcdexyzabcde', 'abccde', 5));
815-
816-
// Distance test.
817-
dmp.Match_Distance = 10; // Strict location.
818-
assertEquals(-1, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24));
819-
820-
assertEquals(0, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdxxefg', 1));
821-
822-
dmp.Match_Distance = 1000; // Loose location.
823-
assertEquals(0, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24));
782+
// Bitap algorithm.
783+
dmp.Match_Distance = 100;
784+
dmp.Match_Threshold = 0.5;
785+
// Exact matches.
786+
assertEquals(5, dmp.match_bitap_('abcdefghijk', 'fgh', 5));
787+
788+
assertEquals(5, dmp.match_bitap_('abcdefghijk', 'fgh', 0));
789+
790+
// Fuzzy matches.
791+
assertEquals(4, dmp.match_bitap_('abcdefghijk', 'efxhi', 0));
792+
793+
assertEquals(2, dmp.match_bitap_('abcdefghijk', 'cdefxyhijk', 5));
794+
795+
assertEquals(-1, dmp.match_bitap_('abcdefghijk', 'bxy', 1));
796+
797+
// Overflow.
798+
assertEquals(2, dmp.match_bitap_('123456789xx0', '3456789x0', 2));
799+
800+
// Threshold test.
801+
dmp.Match_Threshold = 0.4;
802+
assertEquals(4, dmp.match_bitap_('abcdefghijk', 'efxyhi', 1));
803+
804+
dmp.Match_Threshold = 0.3;
805+
assertEquals(-1, dmp.match_bitap_('abcdefghijk', 'efxyhi', 1));
806+
807+
dmp.Match_Threshold = 0.0;
808+
assertEquals(1, dmp.match_bitap_('abcdefghijk', 'bcdef', 1));
809+
dmp.Match_Threshold = 0.5;
810+
811+
// Multiple select.
812+
assertEquals(0, dmp.match_bitap_('abcdexyzabcde', 'abccde', 3));
813+
814+
assertEquals(8, dmp.match_bitap_('abcdexyzabcde', 'abccde', 5));
815+
816+
// Distance test.
817+
dmp.Match_Distance = 10; // Strict location.
818+
assertEquals(-1, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24));
819+
820+
assertEquals(0, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdxxefg', 1));
821+
822+
dmp.Match_Distance = 1000; // Loose location.
823+
assertEquals(0, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24));
824824
}
825825

826826
function testMatchMain() {
827-
// Full match.
828-
// Shortcut matches.
829-
assertEquals(0, dmp.match_main('abcdef', 'abcdef', 1000));
830-
831-
assertEquals(-1, dmp.match_main('', 'abcdef', 1));
832-
833-
assertEquals(3, dmp.match_main('abcdef', '', 3));
834-
835-
assertEquals(3, dmp.match_main('abcdef', 'de', 3));
836-
837-
// Beyond end match.
838-
assertEquals(3, dmp.match_main("abcdef", "defy", 4));
839-
840-
// Oversized pattern.
841-
assertEquals(0, dmp.match_main("abcdef", "abcdefy", 0));
842-
843-
// Complex match.
844-
assertEquals(4, dmp.match_main('I am the very model of a modern major general.', ' that berry ', 5));
845-
846-
// Test null inputs.
847-
try {
848-
dmp.match_main(null, null, 0);
849-
assertEquals(Error, null);
850-
} catch (e) {
851-
// Exception expected.
852-
}
827+
// Full match.
828+
// Shortcut matches.
829+
assertEquals(0, dmp.match_main('abcdef', 'abcdef', 1000));
830+
831+
assertEquals(-1, dmp.match_main('', 'abcdef', 1));
832+
833+
assertEquals(3, dmp.match_main('abcdef', '', 3));
834+
835+
assertEquals(3, dmp.match_main('abcdef', 'de', 3));
836+
837+
// Beyond end match.
838+
assertEquals(3, dmp.match_main("abcdef", "defy", 4));
839+
840+
// Oversized pattern.
841+
assertEquals(0, dmp.match_main("abcdef", "abcdefy", 0));
842+
843+
// Complex match.
844+
assertEquals(4, dmp.match_main('I am the very model of a modern major general.', ' that berry ', 5));
845+
846+
// Test null inputs.
847+
try {
848+
dmp.match_main(null, null, 0);
849+
assertEquals(Error, null);
850+
} catch (e) {
851+
// Exception expected.
852+
}
853853
}
854854

855855

856856
// PATCH TEST FUNCTIONS
857857

858858

859859
function testPatchObj() {
860-
// Patch Object.
861-
var p = new diff_match_patch.patch_obj();
862-
p.start1 = 20;
863-
p.start2 = 21;
864-
p.length1 = 18;
865-
p.length2 = 17;
866-
p.diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, '\nlaz']];
867-
var strp = p.toString();
868-
assertEquals('@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n', strp);
860+
// Patch Object.
861+
var p = new diff_match_patch.patch_obj();
862+
p.start1 = 20;
863+
p.start2 = 21;
864+
p.length1 = 18;
865+
p.length2 = 17;
866+
p.diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, '\nlaz']];
867+
var strp = p.toString();
868+
assertEquals('@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n', strp);
869869
}
870870

871871
function testPatchFromText() {
872-
assertEquivalent([], dmp.patch_fromText(strp));
873-
874-
var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n';
875-
assertEquals(strp, dmp.patch_fromText(strp)[0].toString());
876-
877-
assertEquals('@@ -1 +1 @@\n-a\n+b\n', dmp.patch_fromText('@@ -1 +1 @@\n-a\n+b\n')[0].toString());
878-
879-
assertEquals('@@ -1,3 +0,0 @@\n-abc\n', dmp.patch_fromText('@@ -1,3 +0,0 @@\n-abc\n')[0].toString());
880-
881-
assertEquals('@@ -0,0 +1,3 @@\n+abc\n', dmp.patch_fromText('@@ -0,0 +1,3 @@\n+abc\n')[0].toString());
882-
883-
// Generates error.
884-
try {
885-
dmp.patch_fromText('Bad\nPatch\n');
886-
assertEquals(Error, null);
887-
} catch (e) {
888-
// Exception expected.
889-
}
872+
assertEquivalent([], dmp.patch_fromText(strp));
873+
874+
var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n';
875+
assertEquals(strp, dmp.patch_fromText(strp)[0].toString());
876+
877+
assertEquals('@@ -1 +1 @@\n-a\n+b\n', dmp.patch_fromText('@@ -1 +1 @@\n-a\n+b\n')[0].toString());
878+
879+
assertEquals('@@ -1,3 +0,0 @@\n-abc\n', dmp.patch_fromText('@@ -1,3 +0,0 @@\n-abc\n')[0].toString());
880+
881+
assertEquals('@@ -0,0 +1,3 @@\n+abc\n', dmp.patch_fromText('@@ -0,0 +1,3 @@\n+abc\n')[0].toString());
882+
883+
// Generates error.
884+
try {
885+
dmp.patch_fromText('Bad\nPatch\n');
886+
assertEquals(Error, null);
887+
} catch (e) {
888+
// Exception expected.
889+
}
890890
}
891891

892892
function testPatchToText() {
893-
var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n';
894-
var p = dmp.patch_fromText(strp);
893+
var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n';
894+
var p = dmp.patch_fromText(strp);
895+
assertEquals(strp, dmp.patch_toText(p));
896+
897+
strp = '@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n';
898+
p = dmp.patch_fromText(strp);
895899
assertEquals(strp, dmp.patch_toText(p));
896-
897-
strp = '@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n';
898-
p = dmp.patch_fromText(strp);
899-
assertEquals(strp, dmp.patch_toText(p));
900900
}
901901

902902
function testPatchAddContext() {
903-
dmp.Patch_Margin = 4;
904-
var p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0];
905-
dmp.patch_addContext_(p, 'The quick brown fox jumps over the lazy dog.');
906-
assertEquals('@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n', p.toString());
907-
908-
// Same, but not enough trailing context.
909-
p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0];
910-
dmp.patch_addContext_(p, 'The quick brown fox jumps.');
911-
assertEquals('@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n', p.toString());
912-
913-
// Same, but not enough leading context.
914-
p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0];
915-
dmp.patch_addContext_(p, 'The quick brown fox jumps.');
916-
assertEquals('@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n', p.toString());
917-
918-
// Same, but with ambiguity.
919-
p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0];
920-
dmp.patch_addContext_(p, 'The quick brown fox jumps. The quick brown fox crashes.');
921-
assertEquals('@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n', p.toString());
903+
dmp.Patch_Margin = 4;
904+
var p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0];
905+
dmp.patch_addContext_(p, 'The quick brown fox jumps over the lazy dog.');
906+
assertEquals('@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n', p.toString());
907+
908+
// Same, but not enough trailing context.
909+
p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0];
910+
dmp.patch_addContext_(p, 'The quick brown fox jumps.');
911+
assertEquals('@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n', p.toString());
912+
913+
// Same, but not enough leading context.
914+
p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0];
915+
dmp.patch_addContext_(p, 'The quick brown fox jumps.');
916+
assertEquals('@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n', p.toString());
917+
918+
// Same, but with ambiguity.
919+
p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0];
920+
dmp.patch_addContext_(p, 'The quick brown fox jumps. The quick brown fox crashes.');
921+
assertEquals('@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n', p.toString());
922922
}
923923

924924
function testPatchMake() {
925-
// Null case.
926-
var patches = dmp.patch_make('', '');
927-
assertEquals('', dmp.patch_toText(patches));
928-
929-
var text1 = 'The quick brown fox jumps over the lazy dog.';
930-
var text2 = 'That quick brown fox jumped over a lazy dog.';
931-
// Text2+Text1 inputs.
932-
var expectedPatch = '@@ -1,8 +1,7 @@\n Th\n-at\n+e\n qui\n@@ -21,17 +21,18 @@\n jump\n-ed\n+s\n over \n-a\n+the\n laz\n';
933-
// The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context.
934-
patches = dmp.patch_make(text2, text1);
935-
assertEquals(expectedPatch, dmp.patch_toText(patches));
936-
937-
// Text1+Text2 inputs.
938-
expectedPatch = '@@ -1,11 +1,12 @@\n Th\n-e\n+at\n quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n';
939-
patches = dmp.patch_make(text1, text2);
940-
assertEquals(expectedPatch, dmp.patch_toText(patches));
941-
942-
// Diff input.
943-
var diffs = dmp.diff_main(text1, text2, false);
944-
patches = dmp.patch_make(diffs);
945-
assertEquals(expectedPatch, dmp.patch_toText(patches));
946-
947-
// Text1+Diff inputs.
948-
patches = dmp.patch_make(text1, diffs);
949-
assertEquals(expectedPatch, dmp.patch_toText(patches));
950-
951-
// Text1+Text2+Diff inputs (deprecated).
952-
patches = dmp.patch_make(text1, text2, diffs);
953-
assertEquals(expectedPatch, dmp.patch_toText(patches));
954-
955-
// Character encoding.
956-
patches = dmp.patch_make('`1234567890-=[]\\;\',./', '~!@#$%^&*()_+{}|:"<>?');
957-
assertEquals('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n', dmp.patch_toText(patches));
958-
959-
// Character decoding.
960-
diffs = [[DIFF_DELETE, '`1234567890-=[]\\;\',./'], [DIFF_INSERT, '~!@#$%^&*()_+{}|:"<>?']];
961-
assertEquivalent(diffs, dmp.patch_fromText('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n')[0].diffs);
962-
963-
// Long string with repeats.
964-
text1 = '';
965-
for (var x = 0; x < 100; x++) {
966-
text1 += 'abcdef';
967-
}
968-
text2 = text1 + '123';
969-
expectedPatch = '@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n';
970-
patches = dmp.patch_make(text1, text2);
971-
assertEquals(expectedPatch, dmp.patch_toText(patches));
972-
973-
// Test null inputs.
974-
try {
975-
dmp.patch_make(null);
976-
assertEquals(Error, null);
977-
} catch (e) {
978-
// Exception expected.
979-
}
925+
// Null case.
926+
var patches = dmp.patch_make('', '');
927+
assertEquals('', dmp.patch_toText(patches));
928+
929+
var text1 = 'The quick brown fox jumps over the lazy dog.';
930+
var text2 = 'That quick brown fox jumped over a lazy dog.';
931+
// Text2+Text1 inputs.
932+
var expectedPatch = '@@ -1,8 +1,7 @@\n Th\n-at\n+e\n qui\n@@ -21,17 +21,18 @@\n jump\n-ed\n+s\n over \n-a\n+the\n laz\n';
933+
// The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context.
934+
patches = dmp.patch_make(text2, text1);
935+
assertEquals(expectedPatch, dmp.patch_toText(patches));
936+
937+
// Text1+Text2 inputs.
938+
expectedPatch = '@@ -1,11 +1,12 @@\n Th\n-e\n+at\n quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n';
939+
patches = dmp.patch_make(text1, text2);
940+
assertEquals(expectedPatch, dmp.patch_toText(patches));
941+
942+
// Diff input.
943+
var diffs = dmp.diff_main(text1, text2, false);
944+
patches = dmp.patch_make(diffs);
945+
assertEquals(expectedPatch, dmp.patch_toText(patches));
946+
947+
// Text1+Diff inputs.
948+
patches = dmp.patch_make(text1, diffs);
949+
assertEquals(expectedPatch, dmp.patch_toText(patches));
950+
951+
// Text1+Text2+Diff inputs (deprecated).
952+
patches = dmp.patch_make(text1, text2, diffs);
953+
assertEquals(expectedPatch, dmp.patch_toText(patches));
954+
955+
// Character encoding.
956+
patches = dmp.patch_make('`1234567890-=[]\\;\',./', '~!@#$%^&*()_+{}|:"<>?');
957+
assertEquals('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n', dmp.patch_toText(patches));
958+
959+
// Character decoding.
960+
diffs = [[DIFF_DELETE, '`1234567890-=[]\\;\',./'], [DIFF_INSERT, '~!@#$%^&*()_+{}|:"<>?']];
961+
assertEquivalent(diffs, dmp.patch_fromText('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n')[0].diffs);
962+
963+
// Long string with repeats.
964+
text1 = '';
965+
for (var x = 0; x < 100; x++) {
966+
text1 += 'abcdef';
967+
}
968+
text2 = text1 + '123';
969+
expectedPatch = '@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n';
970+
patches = dmp.patch_make(text1, text2);
971+
assertEquals(expectedPatch, dmp.patch_toText(patches));
972+
973+
// Test null inputs.
974+
try {
975+
dmp.patch_make(null);
976+
assertEquals(Error, null);
977+
} catch (e) {
978+
// Exception expected.
979+
}
980980
}
981981

982982
function testPatchSplitMax() {
983-
// Assumes that dmp.Match_MaxBits is 32.
984-
var patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz01234567890', 'XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0');
985-
dmp.patch_splitMax(patches);
986-
assertEquals('@@ -1,32 +1,46 @@\n+X\n ab\n+X\n cd\n+X\n ef\n+X\n gh\n+X\n ij\n+X\n kl\n+X\n mn\n+X\n op\n+X\n qr\n+X\n st\n+X\n uv\n+X\n wx\n+X\n yz\n+X\n 012345\n@@ -25,13 +39,18 @@\n zX01\n+X\n 23\n+X\n 45\n+X\n 67\n+X\n 89\n+X\n 0\n', dmp.patch_toText(patches));
987-
988-
patches = dmp.patch_make('abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz', 'abcdefuvwxyz');
989-
var oldToText = dmp.patch_toText(patches);
990-
dmp.patch_splitMax(patches);
991-
assertEquals(oldToText, dmp.patch_toText(patches));
992-
993-
patches = dmp.patch_make('1234567890123456789012345678901234567890123456789012345678901234567890', 'abc');
994-
dmp.patch_splitMax(patches);
995-
assertEquals('@@ -1,32 +1,4 @@\n-1234567890123456789012345678\n 9012\n@@ -29,32 +1,4 @@\n-9012345678901234567890123456\n 7890\n@@ -57,14 +1,3 @@\n-78901234567890\n+abc\n', dmp.patch_toText(patches));
996-
997-
patches = dmp.patch_make('abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1', 'abcdefghij , h : 1 , t : 1 abcdefghij , h : 1 , t : 1 abcdefghij , h : 0 , t : 1');
998-
dmp.patch_splitMax(patches);
999-
assertEquals('@@ -2,32 +2,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n@@ -29,32 +29,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n', dmp.patch_toText(patches));
983+
// Assumes that dmp.Match_MaxBits is 32.
984+
var patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz01234567890', 'XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0');
985+
dmp.patch_splitMax(patches);
986+
assertEquals('@@ -1,32 +1,46 @@\n+X\n ab\n+X\n cd\n+X\n ef\n+X\n gh\n+X\n ij\n+X\n kl\n+X\n mn\n+X\n op\n+X\n qr\n+X\n st\n+X\n uv\n+X\n wx\n+X\n yz\n+X\n 012345\n@@ -25,13 +39,18 @@\n zX01\n+X\n 23\n+X\n 45\n+X\n 67\n+X\n 89\n+X\n 0\n', dmp.patch_toText(patches));
987+
988+
patches = dmp.patch_make('abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz', 'abcdefuvwxyz');
989+
var oldToText = dmp.patch_toText(patches);
990+
dmp.patch_splitMax(patches);
991+
assertEquals(oldToText, dmp.patch_toText(patches));
992+
993+
patches = dmp.patch_make('1234567890123456789012345678901234567890123456789012345678901234567890', 'abc');
994+
dmp.patch_splitMax(patches);
995+
assertEquals('@@ -1,32 +1,4 @@\n-1234567890123456789012345678\n 9012\n@@ -29,32 +1,4 @@\n-9012345678901234567890123456\n 7890\n@@ -57,14 +1,3 @@\n-78901234567890\n+abc\n', dmp.patch_toText(patches));
996+
997+
patches = dmp.patch_make('abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1', 'abcdefghij , h : 1 , t : 1 abcdefghij , h : 1 , t : 1 abcdefghij , h : 0 , t : 1');
998+
dmp.patch_splitMax(patches);
999+
assertEquals('@@ -2,32 +2,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n@@ -29,32 +29,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n', dmp.patch_toText(patches));
10001000
}
10011001

10021002
function testPatchAddPadding() {
1003-
// Both edges full.
1004-
var patches = dmp.patch_make('', 'test');
1005-
assertEquals('@@ -0,0 +1,4 @@\n+test\n', dmp.patch_toText(patches));
1006-
dmp.patch_addPadding(patches);
1007-
assertEquals('@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n', dmp.patch_toText(patches));
1008-
1009-
// Both edges partial.
1010-
patches = dmp.patch_make('XY', 'XtestY');
1011-
assertEquals('@@ -1,2 +1,6 @@\n X\n+test\n Y\n', dmp.patch_toText(patches));
1012-
dmp.patch_addPadding(patches);
1013-
assertEquals('@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n', dmp.patch_toText(patches));
1014-
1015-
// Both edges none.
1016-
patches = dmp.patch_make('XXXXYYYY', 'XXXXtestYYYY');
1017-
assertEquals('@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches));
1018-
dmp.patch_addPadding(patches);
1019-
assertEquals('@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches));
1003+
// Both edges full.
1004+
var patches = dmp.patch_make('', 'test');
1005+
assertEquals('@@ -0,0 +1,4 @@\n+test\n', dmp.patch_toText(patches));
1006+
dmp.patch_addPadding(patches);
1007+
assertEquals('@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n', dmp.patch_toText(patches));
1008+
1009+
// Both edges partial.
1010+
patches = dmp.patch_make('XY', 'XtestY');
1011+
assertEquals('@@ -1,2 +1,6 @@\n X\n+test\n Y\n', dmp.patch_toText(patches));
1012+
dmp.patch_addPadding(patches);
1013+
assertEquals('@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n', dmp.patch_toText(patches));
1014+
1015+
// Both edges none.
1016+
patches = dmp.patch_make('XXXXYYYY', 'XXXXtestYYYY');
1017+
assertEquals('@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches));
1018+
dmp.patch_addPadding(patches);
1019+
assertEquals('@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches));
10201020
}
10211021

10221022
function testPatchApply() {
1023-
dmp.Match_Distance = 1000;
1024-
dmp.Match_Threshold = 0.5;
1025-
dmp.Patch_DeleteThreshold = 0.5;
1026-
// Null case.
1027-
var patches = dmp.patch_make('', '');
1028-
var results = dmp.patch_apply(patches, 'Hello world.');
1029-
assertEquivalent(['Hello world.', []], results);
1030-
1031-
// Exact match.
1032-
patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'That quick brown fox jumped over a lazy dog.');
1033-
results = dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.');
1034-
assertEquivalent(['That quick brown fox jumped over a lazy dog.', [true, true]], results);
1035-
1036-
// Partial match.
1037-
results = dmp.patch_apply(patches, 'The quick red rabbit jumps over the tired tiger.');
1038-
assertEquivalent(['That quick red rabbit jumped over a tired tiger.', [true, true]], results);
1039-
1040-
// Failed match.
1041-
results = dmp.patch_apply(patches, 'I am the very model of a modern major general.');
1042-
assertEquivalent(['I am the very model of a modern major general.', [false, false]], results);
1043-
1044-
// Big delete, small change.
1045-
patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
1046-
results = dmp.patch_apply(patches, 'x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y');
1047-
assertEquivalent(['xabcy', [true, true]], results);
1048-
1049-
// Big delete, big change 1.
1050-
patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
1051-
results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y');
1052-
assertEquivalent(['xabc12345678901234567890---------------++++++++++---------------12345678901234567890y', [false, true]], results);
1053-
1054-
// Big delete, big change 2.
1055-
dmp.Patch_DeleteThreshold = 0.6;
1056-
patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
1057-
results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y');
1058-
assertEquivalent(['xabcy', [true, true]], results);
1059-
dmp.Patch_DeleteThreshold = 0.5;
1060-
1061-
// Compensate for failed patch.
1062-
dmp.Match_Threshold = 0.0;
1063-
dmp.Match_Distance = 0;
1064-
patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz--------------------1234567890', 'abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890');
1065-
results = dmp.patch_apply(patches, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890');
1066-
assertEquivalent(['ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890', [false, true]], results);
1067-
dmp.Match_Threshold = 0.5;
1068-
dmp.Match_Distance = 1000;
1069-
1070-
// No side effects.
1071-
patches = dmp.patch_make('', 'test');
1072-
var patchstr = dmp.patch_toText(patches);
1073-
dmp.patch_apply(patches, '');
1074-
assertEquals(patchstr, dmp.patch_toText(patches));
1075-
1076-
// No side effects with major delete.
1077-
patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'Woof');
1078-
patchstr = dmp.patch_toText(patches);
1079-
dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.');
1080-
assertEquals(patchstr, dmp.patch_toText(patches));
1081-
1082-
// Edge exact match.
1083-
patches = dmp.patch_make('', 'test');
1084-
results = dmp.patch_apply(patches, '');
1085-
assertEquivalent(['test', [true]], results);
1086-
1087-
// Near edge exact match.
1088-
patches = dmp.patch_make('XY', 'XtestY');
1089-
results = dmp.patch_apply(patches, 'XY');
1090-
assertEquivalent(['XtestY', [true]], results);
1091-
1092-
// Edge partial match.
1093-
patches = dmp.patch_make('y', 'y123');
1094-
results = dmp.patch_apply(patches, 'x');
1095-
assertEquivalent(['x123', [true]], results);
1023+
dmp.Match_Distance = 1000;
1024+
dmp.Match_Threshold = 0.5;
1025+
dmp.Patch_DeleteThreshold = 0.5;
1026+
// Null case.
1027+
var patches = dmp.patch_make('', '');
1028+
var results = dmp.patch_apply(patches, 'Hello world.');
1029+
assertEquivalent(['Hello world.', []], results);
1030+
1031+
// Exact match.
1032+
patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'That quick brown fox jumped over a lazy dog.');
1033+
results = dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.');
1034+
assertEquivalent(['That quick brown fox jumped over a lazy dog.', [true, true]], results);
1035+
1036+
// Partial match.
1037+
results = dmp.patch_apply(patches, 'The quick red rabbit jumps over the tired tiger.');
1038+
assertEquivalent(['That quick red rabbit jumped over a tired tiger.', [true, true]], results);
1039+
1040+
// Failed match.
1041+
results = dmp.patch_apply(patches, 'I am the very model of a modern major general.');
1042+
assertEquivalent(['I am the very model of a modern major general.', [false, false]], results);
1043+
1044+
// Big delete, small change.
1045+
patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
1046+
results = dmp.patch_apply(patches, 'x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y');
1047+
assertEquivalent(['xabcy', [true, true]], results);
1048+
1049+
// Big delete, big change 1.
1050+
patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
1051+
results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y');
1052+
assertEquivalent(['xabc12345678901234567890---------------++++++++++---------------12345678901234567890y', [false, true]], results);
1053+
1054+
// Big delete, big change 2.
1055+
dmp.Patch_DeleteThreshold = 0.6;
1056+
patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
1057+
results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y');
1058+
assertEquivalent(['xabcy', [true, true]], results);
1059+
dmp.Patch_DeleteThreshold = 0.5;
1060+
1061+
// Compensate for failed patch.
1062+
dmp.Match_Threshold = 0.0;
1063+
dmp.Match_Distance = 0;
1064+
patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz--------------------1234567890', 'abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890');
1065+
results = dmp.patch_apply(patches, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890');
1066+
assertEquivalent(['ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890', [false, true]], results);
1067+
dmp.Match_Threshold = 0.5;
1068+
dmp.Match_Distance = 1000;
1069+
1070+
// No side effects.
1071+
patches = dmp.patch_make('', 'test');
1072+
var patchstr = dmp.patch_toText(patches);
1073+
dmp.patch_apply(patches, '');
1074+
assertEquals(patchstr, dmp.patch_toText(patches));
1075+
1076+
// No side effects with major delete.
1077+
patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'Woof');
1078+
patchstr = dmp.patch_toText(patches);
1079+
dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.');
1080+
assertEquals(patchstr, dmp.patch_toText(patches));
1081+
1082+
// Edge exact match.
1083+
patches = dmp.patch_make('', 'test');
1084+
results = dmp.patch_apply(patches, '');
1085+
assertEquivalent(['test', [true]], results);
1086+
1087+
// Near edge exact match.
1088+
patches = dmp.patch_make('XY', 'XtestY');
1089+
results = dmp.patch_apply(patches, 'XY');
1090+
assertEquivalent(['XtestY', [true]], results);
1091+
1092+
// Edge partial match.
1093+
patches = dmp.patch_make('y', 'y123');
1094+
results = dmp.patch_apply(patches, 'x');
1095+
assertEquivalent(['x123', [true]], results);
10961096
}

0 commit comments

Comments
 (0)
Please sign in to comment.