source: main/trunk/model-sites-dev/von-sparql/textedit-regex/js/diff_match_patch/diff_match_patch_test.js@ 29739

Last change on this file since 29739 was 29739, checked in by davidb, 9 years ago

Web application used to edit text using programming by demonstration (PBD)

  • Property svn:executable set to *
File size: 37.4 KB
Line 
1/**
2 * Test Harness for Diff Match and Patch
3 *
4 * Copyright 2006 Google Inc.
5 * http://code.google.com/p/google-diff-match-patch/
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20
21// If expected and actual are the equivalent, pass the test.
22function assertEquivalent(msg, expected, actual) {
23 if (typeof actual == 'undefined') {
24 // msg is optional.
25 actual = expected;
26 expected = msg;
27 msg = 'Expected: \'' + expected + '\' Actual: \'' + actual + '\'';
28 }
29 if (_equivalent(expected, actual)) {
30 assertEquals(msg, String.toString(expected), String.toString(actual));
31 } else {
32 assertEquals(msg, expected, actual);
33 }
34}
35
36
37// Are a and b the equivalent? -- Recursive.
38function _equivalent(a, b) {
39 if (a == b) {
40 return true;
41 }
42 if (typeof a == 'object' && typeof b == 'object' && a !== null && b !== null) {
43 if (a.toString() != b.toString()) {
44 return false;
45 }
46 for (var p in a) {
47 if (!_equivalent(a[p], b[p])) {
48 return false;
49 }
50 }
51 for (var p in b) {
52 if (!_equivalent(a[p], b[p])) {
53 return false;
54 }
55 }
56 return true;
57 }
58 return false;
59}
60
61
62function diff_rebuildtexts(diffs) {
63 // Construct the two texts which made up the diff originally.
64 var text1 = '';
65 var text2 = '';
66 for (var x = 0; x < diffs.length; x++) {
67 if (diffs[x][0] != DIFF_INSERT) {
68 text1 += diffs[x][1];
69 }
70 if (diffs[x][0] != DIFF_DELETE) {
71 text2 += diffs[x][1];
72 }
73 }
74 return [text1, text2];
75}
76
77var dmp = new diff_match_patch();
78
79
80// DIFF TEST FUNCTIONS
81
82
83function testDiffCommonPrefix() {
84 // Detect any common prefix.
85 // Null case.
86 assertEquals(0, dmp.diff_commonPrefix('abc', 'xyz'));
87
88 // Non-null case.
89 assertEquals(4, dmp.diff_commonPrefix('1234abcdef', '1234xyz'));
90
91 // Whole case.
92 assertEquals(4, dmp.diff_commonPrefix('1234', '1234xyz'));
93}
94
95function testDiffCommonSuffix() {
96 // Detect any common suffix.
97 // Null case.
98 assertEquals(0, dmp.diff_commonSuffix('abc', 'xyz'));
99
100 // Non-null case.
101 assertEquals(4, dmp.diff_commonSuffix('abcdef1234', 'xyz1234'));
102
103 // Whole case.
104 assertEquals(4, dmp.diff_commonSuffix('1234', 'xyz1234'));
105}
106
107function testDiffCommonOverlap() {
108 // Detect any suffix/prefix overlap.
109 // Null case.
110 assertEquals(0, dmp.diff_commonOverlap_('', 'abcd'));
111
112 // Whole case.
113 assertEquals(3, dmp.diff_commonOverlap_('abc', 'abcd'));
114
115 // No overlap.
116 assertEquals(0, dmp.diff_commonOverlap_('123456', 'abcd'));
117
118 // Overlap.
119 assertEquals(3, dmp.diff_commonOverlap_('123456xxx', 'xxxabcd'));
120
121 // Unicode.
122 // Some overly clever languages (C#) may treat ligatures as equal to their
123 // component letters. E.g. U+FB01 == 'fi'
124 assertEquals(0, dmp.diff_commonOverlap_('fi', '\ufb01i'));
125}
126
127function testDiffHalfMatch() {
128 // Detect a halfmatch.
129 dmp.Diff_Timeout = 1;
130 // No match.
131 assertEquals(null, dmp.diff_halfMatch_('1234567890', 'abcdef'));
132
133 assertEquals(null, dmp.diff_halfMatch_('12345', '23'));
134
135 // Single Match.
136 assertEquivalent(['12', '90', 'a', 'z', '345678'], dmp.diff_halfMatch_('1234567890', 'a345678z'));
137
138 assertEquivalent(['a', 'z', '12', '90', '345678'], dmp.diff_halfMatch_('a345678z', '1234567890'));
139
140 assertEquivalent(['abc', 'z', '1234', '0', '56789'], dmp.diff_halfMatch_('abc56789z', '1234567890'));
141
142 assertEquivalent(['a', 'xyz', '1', '7890', '23456'], dmp.diff_halfMatch_('a23456xyz', '1234567890'));
143
144 // Multiple Matches.
145 assertEquivalent(['12123', '123121', 'a', 'z', '1234123451234'], dmp.diff_halfMatch_('121231234123451234123121', 'a1234123451234z'));
146
147 assertEquivalent(['', '-=-=-=-=-=', 'x', '', 'x-=-=-=-=-=-=-='], dmp.diff_halfMatch_('x-=-=-=-=-=-=-=-=-=-=-=-=', 'xx-=-=-=-=-=-=-='));
148
149 assertEquivalent(['-=-=-=-=-=', '', '', 'y', '-=-=-=-=-=-=-=y'], dmp.diff_halfMatch_('-=-=-=-=-=-=-=-=-=-=-=-=y', '-=-=-=-=-=-=-=yy'));
150
151 // Non-optimal halfmatch.
152 // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
153 assertEquivalent(['qHillo', 'w', 'x', 'Hulloy', 'HelloHe'], dmp.diff_halfMatch_('qHilloHelloHew', 'xHelloHeHulloy'));
154
155 // Optimal no halfmatch.
156 dmp.Diff_Timeout = 0;
157 assertEquals(null, dmp.diff_halfMatch_('qHilloHelloHew', 'xHelloHeHulloy'));
158}
159
160function testDiffLinesToChars() {
161 function assertLinesToCharsResultEquals(a, b) {
162 assertEquals(a.chars1, b.chars1);
163 assertEquals(a.chars2, b.chars2);
164 assertEquivalent(a.lineArray, b.lineArray);
165 }
166
167 // Convert lines down to characters.
168 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'));
169
170 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'));
171
172 assertLinesToCharsResultEquals({chars1: '\x01', chars2: '\x02', lineArray: ['', 'a', 'b']}, dmp.diff_linesToChars_('a', 'b'));
173
174 // More than 256 to reveal any 8-bit limitations.
175 var n = 300;
176 var lineList = [];
177 var charList = [];
178 for (var x = 1; x < n + 1; x++) {
179 lineList[x - 1] = x + '\n';
180 charList[x - 1] = String.fromCharCode(x);
181 }
182 assertEquals(n, lineList.length);
183 var lines = lineList.join('');
184 var chars = charList.join('');
185 assertEquals(n, chars.length);
186 lineList.unshift('');
187 assertLinesToCharsResultEquals({chars1: chars, chars2: '', lineArray: lineList}, dmp.diff_linesToChars_(lines, ''));
188}
189
190function testDiffCharsToLines() {
191 // Convert chars up to lines.
192 var diffs = [[DIFF_EQUAL, '\x01\x02\x01'], [DIFF_INSERT, '\x02\x01\x02']];
193 dmp.diff_charsToLines_(diffs, ['', 'alpha\n', 'beta\n']);
194 assertEquivalent([[DIFF_EQUAL, 'alpha\nbeta\nalpha\n'], [DIFF_INSERT, 'beta\nalpha\nbeta\n']], diffs);
195
196 // More than 256 to reveal any 8-bit limitations.
197 var n = 300;
198 var lineList = [];
199 var charList = [];
200 for (var x = 1; x < n + 1; x++) {
201 lineList[x - 1] = x + '\n';
202 charList[x - 1] = String.fromCharCode(x);
203 }
204 assertEquals(n, lineList.length);
205 var lines = lineList.join('');
206 var chars = charList.join('');
207 assertEquals(n, chars.length);
208 lineList.unshift('');
209 var diffs = [[DIFF_DELETE, chars]];
210 dmp.diff_charsToLines_(diffs, lineList);
211 assertEquivalent([[DIFF_DELETE, lines]], diffs);
212}
213
214function testDiffCleanupMerge() {
215 // Cleanup a messy diff.
216 // Null case.
217 var diffs = [];
218 dmp.diff_cleanupMerge(diffs);
219 assertEquivalent([], diffs);
220
221 // No change case.
222 diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_INSERT, 'c']];
223 dmp.diff_cleanupMerge(diffs);
224 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_INSERT, 'c']], diffs);
225
226 // Merge equalities.
227 diffs = [[DIFF_EQUAL, 'a'], [DIFF_EQUAL, 'b'], [DIFF_EQUAL, 'c']];
228 dmp.diff_cleanupMerge(diffs);
229 assertEquivalent([[DIFF_EQUAL, 'abc']], diffs);
230
231 // Merge deletions.
232 diffs = [[DIFF_DELETE, 'a'], [DIFF_DELETE, 'b'], [DIFF_DELETE, 'c']];
233 dmp.diff_cleanupMerge(diffs);
234 assertEquivalent([[DIFF_DELETE, 'abc']], diffs);
235
236 // Merge insertions.
237 diffs = [[DIFF_INSERT, 'a'], [DIFF_INSERT, 'b'], [DIFF_INSERT, 'c']];
238 dmp.diff_cleanupMerge(diffs);
239 assertEquivalent([[DIFF_INSERT, 'abc']], diffs);
240
241 // Merge interweave.
242 diffs = [[DIFF_DELETE, 'a'], [DIFF_INSERT, 'b'], [DIFF_DELETE, 'c'], [DIFF_INSERT, 'd'], [DIFF_EQUAL, 'e'], [DIFF_EQUAL, 'f']];
243 dmp.diff_cleanupMerge(diffs);
244 assertEquivalent([[DIFF_DELETE, 'ac'], [DIFF_INSERT, 'bd'], [DIFF_EQUAL, 'ef']], diffs);
245
246 // Prefix and suffix detection.
247 diffs = [[DIFF_DELETE, 'a'], [DIFF_INSERT, 'abc'], [DIFF_DELETE, 'dc']];
248 dmp.diff_cleanupMerge(diffs);
249 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'd'], [DIFF_INSERT, 'b'], [DIFF_EQUAL, 'c']], diffs);
250
251 // Prefix and suffix detection with equalities.
252 diffs = [[DIFF_EQUAL, 'x'], [DIFF_DELETE, 'a'], [DIFF_INSERT, 'abc'], [DIFF_DELETE, 'dc'], [DIFF_EQUAL, 'y']];
253 dmp.diff_cleanupMerge(diffs);
254 assertEquivalent([[DIFF_EQUAL, 'xa'], [DIFF_DELETE, 'd'], [DIFF_INSERT, 'b'], [DIFF_EQUAL, 'cy']], diffs);
255
256 // Slide edit left.
257 diffs = [[DIFF_EQUAL, 'a'], [DIFF_INSERT, 'ba'], [DIFF_EQUAL, 'c']];
258 dmp.diff_cleanupMerge(diffs);
259 assertEquivalent([[DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'ac']], diffs);
260
261 // Slide edit right.
262 diffs = [[DIFF_EQUAL, 'c'], [DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'a']];
263 dmp.diff_cleanupMerge(diffs);
264 assertEquivalent([[DIFF_EQUAL, 'ca'], [DIFF_INSERT, 'ba']], diffs);
265
266 // Slide edit left recursive.
267 diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_EQUAL, 'c'], [DIFF_DELETE, 'ac'], [DIFF_EQUAL, 'x']];
268 dmp.diff_cleanupMerge(diffs);
269 assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'acx']], diffs);
270
271 // Slide edit right recursive.
272 diffs = [[DIFF_EQUAL, 'x'], [DIFF_DELETE, 'ca'], [DIFF_EQUAL, 'c'], [DIFF_DELETE, 'b'], [DIFF_EQUAL, 'a']];
273 dmp.diff_cleanupMerge(diffs);
274 assertEquivalent([[DIFF_EQUAL, 'xca'], [DIFF_DELETE, 'cba']], diffs);
275}
276
277function testDiffCleanupSemanticLossless() {
278 // Slide diffs to match logical boundaries.
279 // Null case.
280 var diffs = [];
281 dmp.diff_cleanupSemanticLossless(diffs);
282 assertEquivalent([], diffs);
283
284 // Blank lines.
285 diffs = [[DIFF_EQUAL, 'AAA\r\n\r\nBBB'], [DIFF_INSERT, '\r\nDDD\r\n\r\nBBB'], [DIFF_EQUAL, '\r\nEEE']];
286 dmp.diff_cleanupSemanticLossless(diffs);
287 assertEquivalent([[DIFF_EQUAL, 'AAA\r\n\r\n'], [DIFF_INSERT, 'BBB\r\nDDD\r\n\r\n'], [DIFF_EQUAL, 'BBB\r\nEEE']], diffs);
288
289 // Line boundaries.
290 diffs = [[DIFF_EQUAL, 'AAA\r\nBBB'], [DIFF_INSERT, ' DDD\r\nBBB'], [DIFF_EQUAL, ' EEE']];
291 dmp.diff_cleanupSemanticLossless(diffs);
292 assertEquivalent([[DIFF_EQUAL, 'AAA\r\n'], [DIFF_INSERT, 'BBB DDD\r\n'], [DIFF_EQUAL, 'BBB EEE']], diffs);
293
294 // Word boundaries.
295 diffs = [[DIFF_EQUAL, 'The c'], [DIFF_INSERT, 'ow and the c'], [DIFF_EQUAL, 'at.']];
296 dmp.diff_cleanupSemanticLossless(diffs);
297 assertEquivalent([[DIFF_EQUAL, 'The '], [DIFF_INSERT, 'cow and the '], [DIFF_EQUAL, 'cat.']], diffs);
298
299 // Alphanumeric boundaries.
300 diffs = [[DIFF_EQUAL, 'The-c'], [DIFF_INSERT, 'ow-and-the-c'], [DIFF_EQUAL, 'at.']];
301 dmp.diff_cleanupSemanticLossless(diffs);
302 assertEquivalent([[DIFF_EQUAL, 'The-'], [DIFF_INSERT, 'cow-and-the-'], [DIFF_EQUAL, 'cat.']], diffs);
303
304 // Hitting the start.
305 diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'a'], [DIFF_EQUAL, 'ax']];
306 dmp.diff_cleanupSemanticLossless(diffs);
307 assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_EQUAL, 'aax']], diffs);
308
309 // Hitting the end.
310 diffs = [[DIFF_EQUAL, 'xa'], [DIFF_DELETE, 'a'], [DIFF_EQUAL, 'a']];
311 dmp.diff_cleanupSemanticLossless(diffs);
312 assertEquivalent([[DIFF_EQUAL, 'xaa'], [DIFF_DELETE, 'a']], diffs);
313
314 // Sentence boundaries.
315 diffs = [[DIFF_EQUAL, 'The xxx. The '], [DIFF_INSERT, 'zzz. The '], [DIFF_EQUAL, 'yyy.']];
316 dmp.diff_cleanupSemanticLossless(diffs);
317 assertEquivalent([[DIFF_EQUAL, 'The xxx.'], [DIFF_INSERT, ' The zzz.'], [DIFF_EQUAL, ' The yyy.']], diffs);
318}
319
320function testDiffCleanupSemantic() {
321 // Cleanup semantically trivial equalities.
322 // Null case.
323 var diffs = [];
324 dmp.diff_cleanupSemantic(diffs);
325 assertEquivalent([], diffs);
326
327 // No elimination #1.
328 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, 'cd'], [DIFF_EQUAL, '12'], [DIFF_DELETE, 'e']];
329 dmp.diff_cleanupSemantic(diffs);
330 assertEquivalent([[DIFF_DELETE, 'ab'], [DIFF_INSERT, 'cd'], [DIFF_EQUAL, '12'], [DIFF_DELETE, 'e']], diffs);
331
332 // No elimination #2.
333 diffs = [[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'ABC'], [DIFF_EQUAL, '1234'], [DIFF_DELETE, 'wxyz']];
334 dmp.diff_cleanupSemantic(diffs);
335 assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'ABC'], [DIFF_EQUAL, '1234'], [DIFF_DELETE, 'wxyz']], diffs);
336
337 // Simple elimination.
338 diffs = [[DIFF_DELETE, 'a'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, 'c']];
339 dmp.diff_cleanupSemantic(diffs);
340 assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'b']], diffs);
341
342 // Backpass elimination.
343 diffs = [[DIFF_DELETE, 'ab'], [DIFF_EQUAL, 'cd'], [DIFF_DELETE, 'e'], [DIFF_EQUAL, 'f'], [DIFF_INSERT, 'g']];
344 dmp.diff_cleanupSemantic(diffs);
345 assertEquivalent([[DIFF_DELETE, 'abcdef'], [DIFF_INSERT, 'cdfg']], diffs);
346
347 // Multiple eliminations.
348 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']];
349 dmp.diff_cleanupSemantic(diffs);
350 assertEquivalent([[DIFF_DELETE, 'AB_AB'], [DIFF_INSERT, '1A2_1A2']], diffs);
351
352 // Word boundaries.
353 diffs = [[DIFF_EQUAL, 'The c'], [DIFF_DELETE, 'ow and the c'], [DIFF_EQUAL, 'at.']];
354 dmp.diff_cleanupSemantic(diffs);
355 assertEquivalent([[DIFF_EQUAL, 'The '], [DIFF_DELETE, 'cow and the '], [DIFF_EQUAL, 'cat.']], diffs);
356
357 // No overlap elimination.
358 diffs = [[DIFF_DELETE, 'abcxx'], [DIFF_INSERT, 'xxdef']];
359 dmp.diff_cleanupSemantic(diffs);
360 assertEquivalent([[DIFF_DELETE, 'abcxx'], [DIFF_INSERT, 'xxdef']], diffs);
361
362 // Overlap elimination.
363 diffs = [[DIFF_DELETE, 'abcxxx'], [DIFF_INSERT, 'xxxdef']];
364 dmp.diff_cleanupSemantic(diffs);
365 assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'xxx'], [DIFF_INSERT, 'def']], diffs);
366
367 // Reverse overlap elimination.
368 diffs = [[DIFF_DELETE, 'xxxabc'], [DIFF_INSERT, 'defxxx']];
369 dmp.diff_cleanupSemantic(diffs);
370 assertEquivalent([[DIFF_INSERT, 'def'], [DIFF_EQUAL, 'xxx'], [DIFF_DELETE, 'abc']], diffs);
371
372 // Two overlap eliminations.
373 diffs = [[DIFF_DELETE, 'abcd1212'], [DIFF_INSERT, '1212efghi'], [DIFF_EQUAL, '----'], [DIFF_DELETE, 'A3'], [DIFF_INSERT, '3BC']];
374 dmp.diff_cleanupSemantic(diffs);
375 assertEquivalent([[DIFF_DELETE, 'abcd'], [DIFF_EQUAL, '1212'], [DIFF_INSERT, 'efghi'], [DIFF_EQUAL, '----'], [DIFF_DELETE, 'A'], [DIFF_EQUAL, '3'], [DIFF_INSERT, 'BC']], diffs);
376}
377
378function testDiffCleanupEfficiency() {
379 // Cleanup operationally trivial equalities.
380 dmp.Diff_EditCost = 4;
381 // Null case.
382 var diffs = [];
383 dmp.diff_cleanupEfficiency(diffs);
384 assertEquivalent([], diffs);
385
386 // No elimination.
387 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
388 dmp.diff_cleanupEfficiency(diffs);
389 assertEquivalent([[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']], diffs);
390
391 // Four-edit elimination.
392 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'xyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
393 dmp.diff_cleanupEfficiency(diffs);
394 assertEquivalent([[DIFF_DELETE, 'abxyzcd'], [DIFF_INSERT, '12xyz34']], diffs);
395
396 // Three-edit elimination.
397 diffs = [[DIFF_INSERT, '12'], [DIFF_EQUAL, 'x'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
398 dmp.diff_cleanupEfficiency(diffs);
399 assertEquivalent([[DIFF_DELETE, 'xcd'], [DIFF_INSERT, '12x34']], diffs);
400
401 // Backpass elimination.
402 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'xy'], [DIFF_INSERT, '34'], [DIFF_EQUAL, 'z'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '56']];
403 dmp.diff_cleanupEfficiency(diffs);
404 assertEquivalent([[DIFF_DELETE, 'abxyzcd'], [DIFF_INSERT, '12xy34z56']], diffs);
405
406 // High cost elimination.
407 dmp.Diff_EditCost = 5;
408 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];
409 dmp.diff_cleanupEfficiency(diffs);
410 assertEquivalent([[DIFF_DELETE, 'abwxyzcd'], [DIFF_INSERT, '12wxyz34']], diffs);
411 dmp.Diff_EditCost = 4;
412}
413
414function testDiffPrettyHtml() {
415 // Pretty print.
416 var diffs = [[DIFF_EQUAL, 'a\n'], [DIFF_DELETE, '<B>b</B>'], [DIFF_INSERT, 'c&d']];
417 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));
418}
419
420function testDiffText() {
421 // Compute the source and destination texts.
422 var diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, ' lazy']];
423 assertEquals('jumps over the lazy', dmp.diff_text1(diffs));
424
425 assertEquals('jumped over a lazy', dmp.diff_text2(diffs));
426}
427
428function testDiffDelta() {
429 // Convert a diff into delta string.
430 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']];
431 var text1 = dmp.diff_text1(diffs);
432 assertEquals('jumps over the lazy', text1);
433
434 var delta = dmp.diff_toDelta(diffs);
435 assertEquals('=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog', delta);
436
437 // Convert delta string into a diff.
438 assertEquivalent(diffs, dmp.diff_fromDelta(text1, delta));
439
440 // Generates error (19 != 20).
441 try {
442 dmp.diff_fromDelta(text1 + 'x', delta);
443 assertEquals(Error, null);
444 } catch (e) {
445 // Exception expected.
446 }
447
448 // Generates error (19 != 18).
449 try {
450 dmp.diff_fromDelta(text1.substring(1), delta);
451 assertEquals(Error, null);
452 } catch (e) {
453 // Exception expected.
454 }
455
456 // Generates error (%c3%xy invalid Unicode).
457 try {
458 dmp.diff_fromDelta('', '+%c3%xy');
459 assertEquals(Error, null);
460 } catch (e) {
461 // Exception expected.
462 }
463
464 // Test deltas with special characters.
465 diffs = [[DIFF_EQUAL, '\u0680 \x00 \t %'], [DIFF_DELETE, '\u0681 \x01 \n ^'], [DIFF_INSERT, '\u0682 \x02 \\ |']];
466 text1 = dmp.diff_text1(diffs);
467 assertEquals('\u0680 \x00 \t %\u0681 \x01 \n ^', text1);
468
469 delta = dmp.diff_toDelta(diffs);
470 assertEquals('=7\t-7\t+%DA%82 %02 %5C %7C', delta);
471
472 // Convert delta string into a diff.
473 assertEquivalent(diffs, dmp.diff_fromDelta(text1, delta));
474
475 // Verify pool of unchanged characters.
476 diffs = [[DIFF_INSERT, 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ']];
477 var text2 = dmp.diff_text2(diffs);
478 assertEquals('A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ', text2);
479
480 delta = dmp.diff_toDelta(diffs);
481 assertEquals('+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ', delta);
482
483 // Convert delta string into a diff.
484 assertEquivalent(diffs, dmp.diff_fromDelta('', delta));
485}
486
487function testDiffXIndex() {
488 // Translate a location in text1 to text2.
489 // Translation on equality.
490 assertEquals(5, dmp.diff_xIndex([[DIFF_DELETE, 'a'], [DIFF_INSERT, '1234'], [DIFF_EQUAL, 'xyz']], 2));
491
492 // Translation on deletion.
493 assertEquals(1, dmp.diff_xIndex([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '1234'], [DIFF_EQUAL, 'xyz']], 3));
494}
495
496function testDiffLevenshtein() {
497 // Levenshtein with trailing equality.
498 assertEquals(4, dmp.diff_levenshtein([[DIFF_DELETE, 'abc'], [DIFF_INSERT, '1234'], [DIFF_EQUAL, 'xyz']]));
499 // Levenshtein with leading equality.
500 assertEquals(4, dmp.diff_levenshtein([[DIFF_EQUAL, 'xyz'], [DIFF_DELETE, 'abc'], [DIFF_INSERT, '1234']]));
501 // Levenshtein with middle equality.
502 assertEquals(7, dmp.diff_levenshtein([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'xyz'], [DIFF_INSERT, '1234']]));
503}
504
505function testDiffBisect() {
506 // Normal.
507 var a = 'cat';
508 var b = 'map';
509 // Since the resulting diff hasn't been normalized, it would be ok if
510 // the insertion and deletion pairs are swapped.
511 // If the order changes, tweak this test as required.
512 assertEquivalent([[DIFF_DELETE, 'c'], [DIFF_INSERT, 'm'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, 't'], [DIFF_INSERT, 'p']], dmp.diff_bisect_(a, b, Number.MAX_VALUE));
513
514 // Timeout.
515 assertEquivalent([[DIFF_DELETE, 'cat'], [DIFF_INSERT, 'map']], dmp.diff_bisect_(a, b, 0));
516}
517
518function testDiffMain() {
519 // Perform a trivial diff.
520 // Null case.
521 assertEquivalent([], dmp.diff_main('', '', false));
522
523 // Equality.
524 assertEquivalent([[DIFF_EQUAL, 'abc']], dmp.diff_main('abc', 'abc', false));
525
526 // Simple insertion.
527 assertEquivalent([[DIFF_EQUAL, 'ab'], [DIFF_INSERT, '123'], [DIFF_EQUAL, 'c']], dmp.diff_main('abc', 'ab123c', false));
528
529 // Simple deletion.
530 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '123'], [DIFF_EQUAL, 'bc']], dmp.diff_main('a123bc', 'abc', false));
531
532 // Two insertions.
533 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_INSERT, '123'], [DIFF_EQUAL, 'b'], [DIFF_INSERT, '456'], [DIFF_EQUAL, 'c']], dmp.diff_main('abc', 'a123b456c', false));
534
535 // Two deletions.
536 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '123'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, '456'], [DIFF_EQUAL, 'c']], dmp.diff_main('a123b456c', 'abc', false));
537
538 // Perform a real diff.
539 // Switch off the timeout.
540 dmp.Diff_Timeout = 0;
541 // Simple cases.
542 assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_INSERT, 'b']], dmp.diff_main('a', 'b', false));
543
544 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));
545
546 assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_INSERT, '\u0680'], [DIFF_EQUAL, 'x'], [DIFF_DELETE, '\t'], [DIFF_INSERT, '\0']], dmp.diff_main('ax\t', '\u0680x\0', false));
547
548 // Overlaps.
549 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));
550
551 assertEquivalent([[DIFF_INSERT, 'xaxcx'], [DIFF_EQUAL, 'abc'], [DIFF_DELETE, 'y']], dmp.diff_main('abcy', 'xaxcxabc', false));
552
553 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));
554
555 // Large equality.
556 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));
557
558 // Timeout.
559 dmp.Diff_Timeout = 0.1; // 100ms
560 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';
561 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';
562 // Increase the text lengths by 1024 times to ensure a timeout.
563 for (var x = 0; x < 10; x++) {
564 a = a + a;
565 b = b + b;
566 }
567 var startTime = (new Date()).getTime();
568 dmp.diff_main(a, b);
569 var endTime = (new Date()).getTime();
570 // Test that we took at least the timeout period.
571 assertTrue(dmp.Diff_Timeout * 1000 <= endTime - startTime);
572 // Test that we didn't take forever (be forgiving).
573 // Theoretically this test could fail very occasionally if the
574 // OS task swaps or locks up for a second at the wrong moment.
575 // ****
576 // TODO(fraser): For unknown reasons this is taking 500 ms on Google's
577 // internal test system. Whereas browsers take 140 ms.
578 //assertTrue(dmp.Diff_Timeout * 1000 * 2 > endTime - startTime);
579 // ****
580 dmp.Diff_Timeout = 0;
581
582 // Test the linemode speedup.
583 // Must be long to pass the 100 char cutoff.
584 // Simple line-mode.
585 a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n';
586 b = 'abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n';
587 assertEquivalent(dmp.diff_main(a, b, false), dmp.diff_main(a, b, true));
588
589 // Single line-mode.
590 a = '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890';
591 b = 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij';
592 assertEquivalent(dmp.diff_main(a, b, false), dmp.diff_main(a, b, true));
593
594 // Overlap line-mode.
595 a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n';
596 b = 'abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n';
597 var texts_linemode = diff_rebuildtexts(dmp.diff_main(a, b, true));
598 var texts_textmode = diff_rebuildtexts(dmp.diff_main(a, b, false));
599 assertEquivalent(texts_textmode, texts_linemode);
600
601 // Test null inputs.
602 try {
603 dmp.diff_main(null, null);
604 assertEquals(Error, null);
605 } catch (e) {
606 // Exception expected.
607 }
608}
609
610
611// MATCH TEST FUNCTIONS
612
613
614function testMatchAlphabet() {
615 // Initialise the bitmasks for Bitap.
616 // Unique.
617 assertEquivalent({'a':4, 'b':2, 'c':1}, dmp.match_alphabet_('abc'));
618
619 // Duplicates.
620 assertEquivalent({'a':37, 'b':18, 'c':8}, dmp.match_alphabet_('abcaba'));
621}
622
623function testMatchBitap() {
624 // Bitap algorithm.
625 dmp.Match_Distance = 100;
626 dmp.Match_Threshold = 0.5;
627 // Exact matches.
628 assertEquals(5, dmp.match_bitap_('abcdefghijk', 'fgh', 5));
629
630 assertEquals(5, dmp.match_bitap_('abcdefghijk', 'fgh', 0));
631
632 // Fuzzy matches.
633 assertEquals(4, dmp.match_bitap_('abcdefghijk', 'efxhi', 0));
634
635 assertEquals(2, dmp.match_bitap_('abcdefghijk', 'cdefxyhijk', 5));
636
637 assertEquals(-1, dmp.match_bitap_('abcdefghijk', 'bxy', 1));
638
639 // Overflow.
640 assertEquals(2, dmp.match_bitap_('123456789xx0', '3456789x0', 2));
641
642 // Threshold test.
643 dmp.Match_Threshold = 0.4;
644 assertEquals(4, dmp.match_bitap_('abcdefghijk', 'efxyhi', 1));
645
646 dmp.Match_Threshold = 0.3;
647 assertEquals(-1, dmp.match_bitap_('abcdefghijk', 'efxyhi', 1));
648
649 dmp.Match_Threshold = 0.0;
650 assertEquals(1, dmp.match_bitap_('abcdefghijk', 'bcdef', 1));
651 dmp.Match_Threshold = 0.5;
652
653 // Multiple select.
654 assertEquals(0, dmp.match_bitap_('abcdexyzabcde', 'abccde', 3));
655
656 assertEquals(8, dmp.match_bitap_('abcdexyzabcde', 'abccde', 5));
657
658 // Distance test.
659 dmp.Match_Distance = 10; // Strict location.
660 assertEquals(-1, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24));
661
662 assertEquals(0, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdxxefg', 1));
663
664 dmp.Match_Distance = 1000; // Loose location.
665 assertEquals(0, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24));
666}
667
668function testMatchMain() {
669 // Full match.
670 // Shortcut matches.
671 assertEquals(0, dmp.match_main('abcdef', 'abcdef', 1000));
672
673 assertEquals(-1, dmp.match_main('', 'abcdef', 1));
674
675 assertEquals(3, dmp.match_main('abcdef', '', 3));
676
677 assertEquals(3, dmp.match_main('abcdef', 'de', 3));
678
679 // Beyond end match.
680 assertEquals(3, dmp.match_main("abcdef", "defy", 4));
681
682 // Oversized pattern.
683 assertEquals(0, dmp.match_main("abcdef", "abcdefy", 0));
684
685 // Complex match.
686 assertEquals(4, dmp.match_main('I am the very model of a modern major general.', ' that berry ', 5));
687
688 // Test null inputs.
689 try {
690 dmp.match_main(null, null, 0);
691 assertEquals(Error, null);
692 } catch (e) {
693 // Exception expected.
694 }
695}
696
697
698// PATCH TEST FUNCTIONS
699
700
701function testPatchObj() {
702 // Patch Object.
703 var p = new diff_match_patch.patch_obj();
704 p.start1 = 20;
705 p.start2 = 21;
706 p.length1 = 18;
707 p.length2 = 17;
708 p.diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, '\nlaz']];
709 var strp = p.toString();
710 assertEquals('@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n', strp);
711}
712
713function testPatchFromText() {
714 assertEquivalent([], dmp.patch_fromText(strp));
715
716 var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n';
717 assertEquals(strp, dmp.patch_fromText(strp)[0].toString());
718
719 assertEquals('@@ -1 +1 @@\n-a\n+b\n', dmp.patch_fromText('@@ -1 +1 @@\n-a\n+b\n')[0].toString());
720
721 assertEquals('@@ -1,3 +0,0 @@\n-abc\n', dmp.patch_fromText('@@ -1,3 +0,0 @@\n-abc\n')[0].toString());
722
723 assertEquals('@@ -0,0 +1,3 @@\n+abc\n', dmp.patch_fromText('@@ -0,0 +1,3 @@\n+abc\n')[0].toString());
724
725 // Generates error.
726 try {
727 dmp.patch_fromText('Bad\nPatch\n');
728 assertEquals(Error, null);
729 } catch (e) {
730 // Exception expected.
731 }
732}
733
734function testPatchToText() {
735 var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n';
736 var p = dmp.patch_fromText(strp);
737 assertEquals(strp, dmp.patch_toText(p));
738
739 strp = '@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n';
740 p = dmp.patch_fromText(strp);
741 assertEquals(strp, dmp.patch_toText(p));
742}
743
744function testPatchAddContext() {
745 dmp.Patch_Margin = 4;
746 var p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0];
747 dmp.patch_addContext_(p, 'The quick brown fox jumps over the lazy dog.');
748 assertEquals('@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n', p.toString());
749
750 // Same, but not enough trailing context.
751 p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0];
752 dmp.patch_addContext_(p, 'The quick brown fox jumps.');
753 assertEquals('@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n', p.toString());
754
755 // Same, but not enough leading context.
756 p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0];
757 dmp.patch_addContext_(p, 'The quick brown fox jumps.');
758 assertEquals('@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n', p.toString());
759
760 // Same, but with ambiguity.
761 p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0];
762 dmp.patch_addContext_(p, 'The quick brown fox jumps. The quick brown fox crashes.');
763 assertEquals('@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n', p.toString());
764}
765
766function testPatchMake() {
767 // Null case.
768 var patches = dmp.patch_make('', '');
769 assertEquals('', dmp.patch_toText(patches));
770
771 var text1 = 'The quick brown fox jumps over the lazy dog.';
772 var text2 = 'That quick brown fox jumped over a lazy dog.';
773 // Text2+Text1 inputs.
774 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';
775 // The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context.
776 patches = dmp.patch_make(text2, text1);
777 assertEquals(expectedPatch, dmp.patch_toText(patches));
778
779 // Text1+Text2 inputs.
780 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';
781 patches = dmp.patch_make(text1, text2);
782 assertEquals(expectedPatch, dmp.patch_toText(patches));
783
784 // Diff input.
785 var diffs = dmp.diff_main(text1, text2, false);
786 patches = dmp.patch_make(diffs);
787 assertEquals(expectedPatch, dmp.patch_toText(patches));
788
789 // Text1+Diff inputs.
790 patches = dmp.patch_make(text1, diffs);
791 assertEquals(expectedPatch, dmp.patch_toText(patches));
792
793 // Text1+Text2+Diff inputs (deprecated).
794 patches = dmp.patch_make(text1, text2, diffs);
795 assertEquals(expectedPatch, dmp.patch_toText(patches));
796
797 // Character encoding.
798 patches = dmp.patch_make('`1234567890-=[]\\;\',./', '~!@#$%^&*()_+{}|:"<>?');
799 assertEquals('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n', dmp.patch_toText(patches));
800
801 // Character decoding.
802 diffs = [[DIFF_DELETE, '`1234567890-=[]\\;\',./'], [DIFF_INSERT, '~!@#$%^&*()_+{}|:"<>?']];
803 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);
804
805 // Long string with repeats.
806 text1 = '';
807 for (var x = 0; x < 100; x++) {
808 text1 += 'abcdef';
809 }
810 text2 = text1 + '123';
811 expectedPatch = '@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n';
812 patches = dmp.patch_make(text1, text2);
813 assertEquals(expectedPatch, dmp.patch_toText(patches));
814
815 // Test null inputs.
816 try {
817 dmp.patch_make(null);
818 assertEquals(Error, null);
819 } catch (e) {
820 // Exception expected.
821 }
822}
823
824function testPatchSplitMax() {
825 // Assumes that dmp.Match_MaxBits is 32.
826 var patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz01234567890', 'XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0');
827 dmp.patch_splitMax(patches);
828 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));
829
830 patches = dmp.patch_make('abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz', 'abcdefuvwxyz');
831 var oldToText = dmp.patch_toText(patches);
832 dmp.patch_splitMax(patches);
833 assertEquals(oldToText, dmp.patch_toText(patches));
834
835 patches = dmp.patch_make('1234567890123456789012345678901234567890123456789012345678901234567890', 'abc');
836 dmp.patch_splitMax(patches);
837 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));
838
839 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');
840 dmp.patch_splitMax(patches);
841 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));
842}
843
844function testPatchAddPadding() {
845 // Both edges full.
846 var patches = dmp.patch_make('', 'test');
847 assertEquals('@@ -0,0 +1,4 @@\n+test\n', dmp.patch_toText(patches));
848 dmp.patch_addPadding(patches);
849 assertEquals('@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n', dmp.patch_toText(patches));
850
851 // Both edges partial.
852 patches = dmp.patch_make('XY', 'XtestY');
853 assertEquals('@@ -1,2 +1,6 @@\n X\n+test\n Y\n', dmp.patch_toText(patches));
854 dmp.patch_addPadding(patches);
855 assertEquals('@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n', dmp.patch_toText(patches));
856
857 // Both edges none.
858 patches = dmp.patch_make('XXXXYYYY', 'XXXXtestYYYY');
859 assertEquals('@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches));
860 dmp.patch_addPadding(patches);
861 assertEquals('@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches));
862}
863
864function testPatchApply() {
865 dmp.Match_Distance = 1000;
866 dmp.Match_Threshold = 0.5;
867 dmp.Patch_DeleteThreshold = 0.5;
868 // Null case.
869 var patches = dmp.patch_make('', '');
870 var results = dmp.patch_apply(patches, 'Hello world.');
871 assertEquivalent(['Hello world.', []], results);
872
873 // Exact match.
874 patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'That quick brown fox jumped over a lazy dog.');
875 results = dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.');
876 assertEquivalent(['That quick brown fox jumped over a lazy dog.', [true, true]], results);
877
878 // Partial match.
879 results = dmp.patch_apply(patches, 'The quick red rabbit jumps over the tired tiger.');
880 assertEquivalent(['That quick red rabbit jumped over a tired tiger.', [true, true]], results);
881
882 // Failed match.
883 results = dmp.patch_apply(patches, 'I am the very model of a modern major general.');
884 assertEquivalent(['I am the very model of a modern major general.', [false, false]], results);
885
886 // Big delete, small change.
887 patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
888 results = dmp.patch_apply(patches, 'x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y');
889 assertEquivalent(['xabcy', [true, true]], results);
890
891 // Big delete, big change 1.
892 patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
893 results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y');
894 assertEquivalent(['xabc12345678901234567890---------------++++++++++---------------12345678901234567890y', [false, true]], results);
895
896 // Big delete, big change 2.
897 dmp.Patch_DeleteThreshold = 0.6;
898 patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');
899 results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y');
900 assertEquivalent(['xabcy', [true, true]], results);
901 dmp.Patch_DeleteThreshold = 0.5;
902
903 // Compensate for failed patch.
904 dmp.Match_Threshold = 0.0;
905 dmp.Match_Distance = 0;
906 patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz--------------------1234567890', 'abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890');
907 results = dmp.patch_apply(patches, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890');
908 assertEquivalent(['ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890', [false, true]], results);
909 dmp.Match_Threshold = 0.5;
910 dmp.Match_Distance = 1000;
911
912 // No side effects.
913 patches = dmp.patch_make('', 'test');
914 var patchstr = dmp.patch_toText(patches);
915 dmp.patch_apply(patches, '');
916 assertEquals(patchstr, dmp.patch_toText(patches));
917
918 // No side effects with major delete.
919 patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'Woof');
920 patchstr = dmp.patch_toText(patches);
921 dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.');
922 assertEquals(patchstr, dmp.patch_toText(patches));
923
924 // Edge exact match.
925 patches = dmp.patch_make('', 'test');
926 results = dmp.patch_apply(patches, '');
927 assertEquivalent(['test', [true]], results);
928
929 // Near edge exact match.
930 patches = dmp.patch_make('XY', 'XtestY');
931 results = dmp.patch_apply(patches, 'XY');
932 assertEquivalent(['XtestY', [true]], results);
933
934 // Edge partial match.
935 patches = dmp.patch_make('y', 'y123');
936 results = dmp.patch_apply(patches, 'x');
937 assertEquivalent(['x123', [true]], results);
938}
Note: See TracBrowser for help on using the repository browser.