diff --git a/.gitignore b/.gitignore index 41779de8..65503677 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ xcuserdata dart/tests/Speedtest.dart.js.deps dart/tests/Speedtest.dart.js.map +.vscode/launch.json diff --git a/dart/DMPClass.dart b/dart/DMPClass.dart index 7be14226..01c2dad8 100644 --- a/dart/DMPClass.dart +++ b/dart/DMPClass.dart @@ -91,8 +91,7 @@ class DiffMatchPatch { * internally for recursive calls. Users should set DiffTimeout instead. * Returns a List of Diff objects. */ - List diff_main(String text1, String text2, - [bool checklines = true, DateTime deadline]) { + List diff_main(String? text1, String? text2, [bool checklines = true, DateTime? deadline]) { // Set a deadline by which time the diff must be complete. if (deadline == null) { deadline = new DateTime.now(); @@ -100,8 +99,7 @@ class DiffMatchPatch { // One year should be sufficient for 'infinity'. deadline = deadline.add(new Duration(days: 365)); } else { - deadline = deadline - .add(new Duration(milliseconds: (Diff_Timeout * 1000).toInt())); + deadline = deadline.add(new Duration(milliseconds: (Diff_Timeout * 1000).toInt())); } } // Check for null inputs. @@ -157,8 +155,7 @@ class DiffMatchPatch { * [deadline] is the time when the diff should be complete by. * Returns a List of Diff objects. */ - List _diff_compute( - String text1, String text2, bool checklines, DateTime deadline) { + List _diff_compute(String text1, String text2, bool checklines, DateTime deadline) { List diffs = []; if (text1.length == 0) { @@ -178,8 +175,7 @@ class DiffMatchPatch { int i = longtext.indexOf(shorttext); if (i != -1) { // Shorter text is inside the longer text (speedup). - Operation op = - (text1.length > text2.length) ? Operation.delete : Operation.insert; + Operation op = (text1.length > text2.length) ? Operation.delete : Operation.insert; diffs.add(new Diff(op, longtext.substring(0, i))); diffs.add(new Diff(Operation.equal, shorttext)); diffs.add(new Diff(op, longtext.substring(i + shorttext.length))); @@ -267,8 +263,7 @@ class DiffMatchPatch { // Delete the offending records and add the merged ones. diffs.removeRange(pointer - count_delete - count_insert, pointer); pointer = pointer - count_delete - count_insert; - final subDiff = diff_main(text_delete.toString(), - text_insert.toString(), false, deadline); + final subDiff = diff_main(text_delete.toString(), text_insert.toString(), false, deadline); for (int j = subDiff.length - 1; j >= 0; j--) { diffs.insert(pointer, subDiff[j]); } @@ -303,12 +298,8 @@ class DiffMatchPatch { final max_d = (text1_length + text2_length + 1) ~/ 2; final v_offset = max_d; final v_length = 2 * max_d; - final v1 = new List(v_length); - final v2 = new List(v_length); - for (int x = 0; x < v_length; x++) { - v1[x] = -1; - v2[x] = -1; - } + final v1 = new List.filled(v_length, -1); + final v2 = new List.filled(v_length, -1); v1[v_offset + 1] = 0; v2[v_offset + 1] = 0; final delta = text1_length - text2_length; @@ -337,8 +328,7 @@ class DiffMatchPatch { x1 = v1[k1_offset - 1] + 1; } int y1 = x1 - k1; - while ( - x1 < text1_length && y1 < text2_length && text1[x1] == text2[y1]) { + while (x1 < text1_length && y1 < text2_length && text1[x1] == text2[y1]) { x1++; y1++; } @@ -372,9 +362,7 @@ class DiffMatchPatch { x2 = v2[k2_offset - 1] + 1; } int y2 = x2 - k2; - while (x2 < text1_length && - y2 < text2_length && - text1[text1_length - x2 - 1] == text2[text2_length - y2 - 1]) { + while (x2 < text1_length && y2 < text2_length && text1[text1_length - x2 - 1] == text2[text2_length - y2 - 1]) { x2++; y2++; } @@ -402,10 +390,7 @@ class DiffMatchPatch { } // Diff took too long and hit the deadline or // number of diffs equals number of characters, no commonality at all. - return [ - new Diff(Operation.delete, text1), - new Diff(Operation.insert, text2) - ]; + return [new Diff(Operation.delete, text1), new Diff(Operation.insert, text2)]; } /** @@ -425,8 +410,7 @@ class DiffMatchPatch { * [deadline] is the time at which to bail if not yet complete. * Returns a List of Diff objects. */ - List _diff_bisectSplit( - String text1, String text2, int x, int y, DateTime deadline) { + List _diff_bisectSplit(String text1, String text2, int x, int y, DateTime deadline) { final text1a = text1.substring(0, x); final text2a = text2.substring(0, y); final text1b = text1.substring(x); @@ -481,8 +465,7 @@ class DiffMatchPatch { * [maxLines] is the maximum length for lineArray. * Returns an encoded string. */ - String _diff_linesToCharsMunge(String text, List lineArray, - Map lineHash, int maxLines) { + String _diff_linesToCharsMunge(String text, List lineArray, Map lineHash, int maxLines) { int lineStart = 0; int lineEnd = -1; String line; @@ -498,7 +481,7 @@ class DiffMatchPatch { line = text.substring(lineStart, lineEnd + 1); if (lineHash.containsKey(line)) { - chars.writeCharCode(lineHash[line]); + chars.writeCharCode(lineHash[line]!); } else { if (lineArray.length == maxLines) { // Bail out at 65535 because @@ -538,7 +521,7 @@ class DiffMatchPatch { * Hack to allow unit tests to call private method. Do not use. */ void test_diff_charsToLines(List diffs, List lineArray) { - _diff_charsToLines(diffs, lineArray); + _diff_charsToLines(diffs, lineArray); } /** @@ -620,8 +603,7 @@ class DiffMatchPatch { return best; } length += found; - if (found == 0 || - text1.substring(text_length - length) == text2.substring(0, length)) { + if (found == 0 || text1.substring(text_length - length) == text2.substring(0, length)) { best = length; length++; } @@ -645,7 +627,7 @@ class DiffMatchPatch { * the suffix of text1, the prefix of text2, the suffix of text2 and the * common middle. Or null if there was no match. */ - List _diff_halfMatch(String text1, String text2) { + List? _diff_halfMatch(String text1, String text2) { if (Diff_Timeout <= 0) { // Don't risk returning a non-optimal diff if we have unlimited time. return null; @@ -657,16 +639,14 @@ class DiffMatchPatch { } // First check if the second quarter is the seed for a half-match. - final hm1 = _diff_halfMatchI( - longtext, shorttext, ((longtext.length + 3) / 4).ceil().toInt()); + final hm1 = _diff_halfMatchI(longtext, shorttext, ((longtext.length + 3) / 4).ceil().toInt()); // Check again based on the third quarter. - final hm2 = _diff_halfMatchI( - longtext, shorttext, ((longtext.length + 1) / 2).ceil().toInt()); + final hm2 = _diff_halfMatchI(longtext, shorttext, ((longtext.length + 1) / 2).ceil().toInt()); List hm; if (hm1 == null && hm2 == null) { return null; } else if (hm2 == null) { - hm = hm1; + hm = hm1!; } else if (hm1 == null) { hm = hm2; } else { @@ -686,7 +666,7 @@ class DiffMatchPatch { /** * Hack to allow unit tests to call private method. Do not use. */ - List test_diff_halfMatch(String text1, String text2) { + List? test_diff_halfMatch(String text1, String text2) { return _diff_halfMatch(text1, text2); } @@ -700,22 +680,18 @@ class DiffMatchPatch { * the suffix of longtext, the prefix of shorttext, the suffix of * shorttext and the common middle. Or null if there was no match. */ - List _diff_halfMatchI(String longtext, String shorttext, int i) { + List? _diff_halfMatchI(String longtext, String shorttext, int i) { // Start with a 1/4 length substring at position i as a seed. - final seed = - longtext.substring(i, i + (longtext.length / 4).floor().toInt()); + final seed = longtext.substring(i, i + (longtext.length / 4).floor().toInt()); int j = -1; String best_common = ''; String best_longtext_a = '', best_longtext_b = ''; String best_shorttext_a = '', best_shorttext_b = ''; while ((j = shorttext.indexOf(seed, j + 1)) != -1) { - int prefixLength = - diff_commonPrefix(longtext.substring(i), shorttext.substring(j)); - int suffixLength = diff_commonSuffix( - longtext.substring(0, i), shorttext.substring(0, j)); + int prefixLength = diff_commonPrefix(longtext.substring(i), shorttext.substring(j)); + int suffixLength = diff_commonSuffix(longtext.substring(0, i), shorttext.substring(0, j)); if (best_common.length < suffixLength + prefixLength) { - best_common = shorttext.substring(j - suffixLength, j) + - shorttext.substring(j, j + prefixLength); + best_common = shorttext.substring(j - suffixLength, j) + shorttext.substring(j, j + prefixLength); best_longtext_a = longtext.substring(0, i - suffixLength); best_longtext_b = longtext.substring(i + prefixLength); best_shorttext_a = shorttext.substring(0, j - suffixLength); @@ -723,13 +699,7 @@ class DiffMatchPatch { } } if (best_common.length * 2 >= longtext.length) { - return [ - best_longtext_a, - best_longtext_b, - best_shorttext_a, - best_shorttext_b, - best_common - ]; + return [best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b, best_common]; } else { return null; } @@ -744,7 +714,7 @@ class DiffMatchPatch { // Stack of indices where equalities are found. final equalities = []; // Always equal to diffs[equalities.last()].text - String lastEquality = null; + String? lastEquality; int pointer = 0; // Index of current position. // Number of characters that changed prior to the equality. int length_insertions1 = 0; @@ -771,13 +741,10 @@ class DiffMatchPatch { // Eliminate an equality that is smaller or equal to the edits on both // sides of it. if (lastEquality != null && - (lastEquality.length <= - max(length_insertions1, length_deletions1)) && - (lastEquality.length <= - max(length_insertions2, length_deletions2))) { + (lastEquality.length <= max(length_insertions1, length_deletions1)) && + (lastEquality.length <= max(length_insertions2, length_deletions2))) { // Duplicate record. - diffs.insert( - equalities.last, new Diff(Operation.delete, lastEquality)); + diffs.insert(equalities.last, new Diff(Operation.delete, lastEquality)); // Change second copy to insert. diffs[equalities.last + 1].operation = Operation.insert; // Throw away the equality we just deleted. @@ -812,39 +779,27 @@ class DiffMatchPatch { // Only extract an overlap if it is as big as the edit ahead or behind it. pointer = 1; while (pointer < diffs.length) { - if (diffs[pointer - 1].operation == Operation.delete && - diffs[pointer].operation == Operation.insert) { + if (diffs[pointer - 1].operation == Operation.delete && diffs[pointer].operation == Operation.insert) { String deletion = diffs[pointer - 1].text; String insertion = diffs[pointer].text; int overlap_length1 = _diff_commonOverlap(deletion, insertion); int overlap_length2 = _diff_commonOverlap(insertion, deletion); if (overlap_length1 >= overlap_length2) { - if (overlap_length1 >= deletion.length / 2 || - overlap_length1 >= insertion.length / 2) { + if (overlap_length1 >= deletion.length / 2 || overlap_length1 >= insertion.length / 2) { // Overlap found. // Insert an equality and trim the surrounding edits. - diffs.insert( - pointer, - new Diff( - Operation.equal, insertion.substring(0, overlap_length1))); - diffs[pointer - 1].text = - deletion.substring(0, deletion.length - overlap_length1); + diffs.insert(pointer, new Diff(Operation.equal, insertion.substring(0, overlap_length1))); + diffs[pointer - 1].text = deletion.substring(0, deletion.length - overlap_length1); diffs[pointer + 1].text = insertion.substring(overlap_length1); pointer++; } } else { - if (overlap_length2 >= deletion.length / 2 || - overlap_length2 >= insertion.length / 2) { + if (overlap_length2 >= deletion.length / 2 || overlap_length2 >= insertion.length / 2) { // Reverse overlap found. // Insert an equality and swap and trim the surrounding edits. - diffs.insert( - pointer, - new Diff( - Operation.equal, deletion.substring(0, overlap_length2))); - diffs[pointer - 1] = new Diff(Operation.insert, - insertion.substring(0, insertion.length - overlap_length2)); - diffs[pointer + 1] = - new Diff(Operation.delete, deletion.substring(overlap_length2)); + diffs.insert(pointer, new Diff(Operation.equal, deletion.substring(0, overlap_length2))); + diffs[pointer - 1] = new Diff(Operation.insert, insertion.substring(0, insertion.length - overlap_length2)); + diffs[pointer + 1] = new Diff(Operation.delete, deletion.substring(overlap_length2)); pointer++; } } @@ -914,8 +869,7 @@ class DiffMatchPatch { int pointer = 1; // Intentionally ignore the first and last element (don't need checking). while (pointer < diffs.length - 1) { - if (diffs[pointer - 1].operation == Operation.equal && - diffs[pointer + 1].operation == Operation.equal) { + if (diffs[pointer - 1].operation == Operation.equal && diffs[pointer + 1].operation == Operation.equal) { // This is a single edit surrounded by equalities. String equality1 = diffs[pointer - 1].text; String edit = diffs[pointer].text; @@ -934,14 +888,12 @@ class DiffMatchPatch { String bestEquality1 = equality1; String bestEdit = edit; String bestEquality2 = equality2; - int bestScore = _diff_cleanupSemanticScore(equality1, edit) + - _diff_cleanupSemanticScore(edit, equality2); + int bestScore = _diff_cleanupSemanticScore(equality1, edit) + _diff_cleanupSemanticScore(edit, equality2); while (!edit.isEmpty && !equality2.isEmpty && edit[0] == equality2[0]) { equality1 = equality1 + edit[0]; edit = edit.substring(1) + equality2[0]; equality2 = equality2.substring(1); - int score = _diff_cleanupSemanticScore(equality1, edit) + - _diff_cleanupSemanticScore(edit, equality2); + int score = _diff_cleanupSemanticScore(equality1, edit) + _diff_cleanupSemanticScore(edit, equality2); // The >= encourages trailing rather than leading whitespace on edits. if (score >= bestScore) { bestScore = score; @@ -995,7 +947,7 @@ class DiffMatchPatch { // Stack of indices where equalities are found. final equalities = []; // Always equal to diffs[equalities.last()].text - String lastEquality = null; + String? lastEquality; int pointer = 0; // Index of current position. // Is there an insertion operation before the last equality. bool pre_ins = false; @@ -1008,8 +960,7 @@ class DiffMatchPatch { while (pointer < diffs.length) { if (diffs[pointer].operation == Operation.equal) { // Equality found. - if (diffs[pointer].text.length < Diff_EditCost && - (post_ins || post_del)) { + if (diffs[pointer].text.length < Diff_EditCost && (post_ins || post_del)) { // Candidate found. equalities.add(pointer); pre_ins = post_ins; @@ -1039,14 +990,9 @@ class DiffMatchPatch { if (lastEquality != null && ((pre_ins && pre_del && post_ins && post_del) || ((lastEquality.length < Diff_EditCost / 2) && - ((pre_ins ? 1 : 0) + - (pre_del ? 1 : 0) + - (post_ins ? 1 : 0) + - (post_del ? 1 : 0)) == - 3))) { + ((pre_ins ? 1 : 0) + (pre_del ? 1 : 0) + (post_ins ? 1 : 0) + (post_del ? 1 : 0)) == 3))) { // Duplicate record. - diffs.insert( - equalities.last, new Diff(Operation.delete, lastEquality)); + diffs.insert(equalities.last, new Diff(Operation.delete, lastEquality)); // Change second copy to insert. diffs[equalities.last + 1].operation = Operation.insert; equalities.removeLast(); // Throw away the equality we just deleted. @@ -1106,17 +1052,11 @@ class DiffMatchPatch { commonlength = diff_commonPrefix(text_insert, text_delete); if (commonlength != 0) { if ((pointer - count_delete - count_insert) > 0 && - diffs[pointer - count_delete - count_insert - 1] - .operation == - Operation.equal) { + diffs[pointer - count_delete - count_insert - 1].operation == Operation.equal) { final i = pointer - count_delete - count_insert - 1; - diffs[i].text = - diffs[i].text + text_insert.substring(0, commonlength); + diffs[i].text = diffs[i].text + text_insert.substring(0, commonlength); } else { - diffs.insert( - 0, - new Diff(Operation.equal, - text_insert.substring(0, commonlength))); + diffs.insert(0, new Diff(Operation.equal, text_insert.substring(0, commonlength))); pointer++; } text_insert = text_insert.substring(commonlength); @@ -1126,13 +1066,9 @@ class DiffMatchPatch { // Factor out any common suffixies. commonlength = diff_commonSuffix(text_insert, text_delete); if (commonlength != 0) { - diffs[pointer].text = - text_insert.substring(text_insert.length - commonlength) + - diffs[pointer].text; - text_insert = - text_insert.substring(0, text_insert.length - commonlength); - text_delete = - text_delete.substring(0, text_delete.length - commonlength); + diffs[pointer].text = text_insert.substring(text_insert.length - commonlength) + diffs[pointer].text; + text_insert = text_insert.substring(0, text_insert.length - commonlength); + text_delete = text_delete.substring(0, text_delete.length - commonlength); } } // Delete the offending records and add the merged ones. @@ -1147,11 +1083,9 @@ class DiffMatchPatch { pointer++; } pointer++; - } else if (pointer != 0 && - diffs[pointer - 1].operation == Operation.equal) { + } else if (pointer != 0 && diffs[pointer - 1].operation == Operation.equal) { // Merge this equality with the previous one. - diffs[pointer - 1].text = - diffs[pointer - 1].text + diffs[pointer].text; + diffs[pointer - 1].text = diffs[pointer - 1].text + diffs[pointer].text; diffs.removeAt(pointer); } else { pointer++; @@ -1174,25 +1108,19 @@ class DiffMatchPatch { pointer = 1; // Intentionally ignore the first and last element (don't need checking). while (pointer < diffs.length - 1) { - if (diffs[pointer - 1].operation == Operation.equal && - diffs[pointer + 1].operation == Operation.equal) { + if (diffs[pointer - 1].operation == Operation.equal && diffs[pointer + 1].operation == Operation.equal) { // This is a single edit surrounded by equalities. if (diffs[pointer].text.endsWith(diffs[pointer - 1].text)) { // Shift the edit over the previous equality. diffs[pointer].text = diffs[pointer - 1].text + - diffs[pointer].text.substring(0, - diffs[pointer].text.length - diffs[pointer - 1].text.length); - diffs[pointer + 1].text = - diffs[pointer - 1].text + diffs[pointer + 1].text; + diffs[pointer].text.substring(0, diffs[pointer].text.length - diffs[pointer - 1].text.length); + diffs[pointer + 1].text = diffs[pointer - 1].text + diffs[pointer + 1].text; diffs.removeAt(pointer - 1); changes = true; } else if (diffs[pointer].text.startsWith(diffs[pointer + 1].text)) { // Shift the edit over the next equality. - diffs[pointer - 1].text = - diffs[pointer - 1].text + diffs[pointer + 1].text; - diffs[pointer].text = - diffs[pointer].text.substring(diffs[pointer + 1].text.length) + - diffs[pointer + 1].text; + diffs[pointer - 1].text = diffs[pointer - 1].text + diffs[pointer + 1].text; + diffs[pointer].text = diffs[pointer].text.substring(diffs[pointer + 1].text.length) + diffs[pointer + 1].text; diffs.removeAt(pointer + 1); changes = true; } @@ -1218,7 +1146,7 @@ class DiffMatchPatch { int chars2 = 0; int last_chars1 = 0; int last_chars2 = 0; - Diff lastDiff = null; + Diff? lastDiff; for (Diff aDiff in diffs) { if (aDiff.operation != Operation.insert) { // Equality or deletion. @@ -1417,8 +1345,7 @@ class DiffMatchPatch { throw new ArgumentError('Invalid number in diff_fromDelta: $param'); } if (n < 0) { - throw new ArgumentError( - 'Negative number in diff_fromDelta: $param'); + throw new ArgumentError('Negative number in diff_fromDelta: $param'); } String text; try { @@ -1435,8 +1362,7 @@ class DiffMatchPatch { break; default: // Anything else is an error. - throw new ArgumentError( - 'Invalid diff operation in diff_fromDelta: ${token[0]}'); + throw new ArgumentError('Invalid diff operation in diff_fromDelta: ${token[0]}'); } } if (pointer != text1.length) { @@ -1456,7 +1382,7 @@ class DiffMatchPatch { * [loc] is the location to search around. * Returns the best match index or -1. */ - int match_main(String text, String pattern, int loc) { + int match_main(String? text, String? pattern, int loc) { // Check for null inputs. if (text == null || pattern == null) { throw new ArgumentError('Null inputs. (match_main)'); @@ -1469,8 +1395,7 @@ class DiffMatchPatch { } else if (text.length == 0) { // Nothing to match. return -1; - } else if (loc + pattern.length <= text.length && - text.substring(loc, loc + pattern.length) == pattern) { + } else if (loc + pattern.length <= text.length && text.substring(loc, loc + pattern.length) == pattern) { // Perfect match at the perfect spot! (Includes case of null pattern) return loc; } else { @@ -1499,13 +1424,11 @@ class DiffMatchPatch { // Is there a nearby exact match? (speedup) int best_loc = text.indexOf(pattern, loc); if (best_loc != -1) { - score_threshold = - min(_match_bitapScore(0, best_loc, loc, pattern), score_threshold); + score_threshold = min(_match_bitapScore(0, best_loc, loc, pattern), score_threshold); // What about in the other direction? (speedup) best_loc = text.lastIndexOf(pattern, loc + pattern.length); if (best_loc != -1) { - score_threshold = - min(_match_bitapScore(0, best_loc, loc, pattern), score_threshold); + score_threshold = min(_match_bitapScore(0, best_loc, loc, pattern), score_threshold); } } @@ -1515,7 +1438,7 @@ class DiffMatchPatch { int bin_min, bin_mid; int bin_max = pattern.length + text.length; - List last_rd; + List? last_rd; for (int d = 0; d < pattern.length; d++) { // Scan for the best match; each iteration allows for one more error. // Run a binary search to determine how far from 'loc' we can stray at @@ -1523,8 +1446,7 @@ class DiffMatchPatch { bin_min = 0; bin_mid = bin_max; while (bin_min < bin_mid) { - if (_match_bitapScore(d, loc + bin_mid, loc, pattern) <= - score_threshold) { + if (_match_bitapScore(d, loc + bin_mid, loc, pattern) <= score_threshold) { bin_min = bin_mid; } else { bin_max = bin_mid; @@ -1536,7 +1458,7 @@ class DiffMatchPatch { int start = max(1, loc - bin_mid + 1); int finish = min(loc + bin_mid, text.length) + pattern.length; - final rd = new List(finish + 2); + final rd = new List.filled(finish + 2, 0); rd[finish + 1] = (1 << d) - 1; for (int j = finish; j >= start; j--) { int charMatch; @@ -1544,16 +1466,14 @@ class DiffMatchPatch { // Out of range. charMatch = 0; } else { - charMatch = s[text[j - 1]]; + charMatch = s[text[j - 1]]!; } if (d == 0) { // First pass: exact match. rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; } else { // Subsequent passes: fuzzy match. - rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | - (((last_rd[j + 1] | last_rd[j]) << 1) | 1) | - last_rd[j + 1]; + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((last_rd![j + 1] | last_rd[j]) << 1) | 1) | last_rd[j + 1]; } if ((rd[j] & matchmask) != 0) { double score = _match_bitapScore(d, j - 1, loc, pattern); @@ -1618,7 +1538,7 @@ class DiffMatchPatch { s[pattern[i]] = 0; } for (int i = 0; i < pattern.length; i++) { - s[pattern[i]] = s[pattern[i]] | (1 << (pattern.length - i - 1)); + s[pattern[i]] = s[pattern[i]]! | (1 << (pattern.length - i - 1)); } return s; } @@ -1650,8 +1570,8 @@ class DiffMatchPatch { while (text.indexOf(pattern) != text.lastIndexOf(pattern) && pattern.length < Match_MaxBits - Patch_Margin - Patch_Margin) { padding += Patch_Margin; - pattern = text.substring(max(0, patch.start2 - padding), - min(text.length, patch.start2 + patch.length1 + padding)); + pattern = + text.substring(max(0, patch.start2 - padding), min(text.length, patch.start2 + patch.length1 + padding)); } // Add one chunk for good luck. padding += Patch_Margin; @@ -1662,8 +1582,8 @@ class DiffMatchPatch { patch.diffs.insert(0, new Diff(Operation.equal, prefix)); } // Add the suffix. - final suffix = text.substring(patch.start2 + patch.length1, - min(text.length, patch.start2 + patch.length1 + padding)); + final suffix = + text.substring(patch.start2 + patch.length1, min(text.length, patch.start2 + patch.length1 + padding)); if (!suffix.isEmpty) { patch.diffs.add(new Diff(Operation.equal, suffix)); } @@ -1713,17 +1633,17 @@ class DiffMatchPatch { } else if (a is List && opt_b == null && opt_c == null) { // Method 2: diffs // Compute text1 from diffs. - diffs = a; + diffs = a as List; text1 = diff_text1(diffs); } else if (a is String && opt_b is List && opt_c == null) { // Method 3: text1, diffs text1 = a; - diffs = opt_b; + diffs = opt_b as List; } else if (a is String && opt_b is String && opt_c is List) { // Method 4: text1, text2, diffs // text2 is not used. text1 = a; - diffs = opt_c; + diffs = opt_c as List; } else { throw new ArgumentError('Unknown call format to patch_make.'); } @@ -1751,20 +1671,17 @@ class DiffMatchPatch { case Operation.insert: patch.diffs.add(aDiff); patch.length2 += aDiff.text.length; - postpatch_text = postpatch_text.substring(0, char_count2) + - aDiff.text + - postpatch_text.substring(char_count2); + postpatch_text = + postpatch_text.substring(0, char_count2) + aDiff.text + postpatch_text.substring(char_count2); break; case Operation.delete: patch.length1 += aDiff.text.length; patch.diffs.add(aDiff); - postpatch_text = postpatch_text.substring(0, char_count2) + - postpatch_text.substring(char_count2 + aDiff.text.length); + postpatch_text = + postpatch_text.substring(0, char_count2) + postpatch_text.substring(char_count2 + aDiff.text.length); break; case Operation.equal: - if (aDiff.text.length <= 2 * Patch_Margin && - !patch.diffs.isEmpty && - aDiff != diffs.last) { + if (aDiff.text.length <= 2 * Patch_Margin && !patch.diffs.isEmpty && aDiff != diffs.last) { // Small equality inside a patch. patch.diffs.add(aDiff); patch.length1 += aDiff.text.length; @@ -1852,7 +1769,7 @@ class DiffMatchPatch { // 20, but the first patch was found at 12, delta is 2 and the second patch // has an effective expected position of 22. int delta = 0; - final results = new List(patches.length); + final results = new List.filled(patches.length, false); for (Patch aPatch in patches) { int expected_loc = aPatch.start2 + delta; String text1 = diff_text1(aPatch.diffs); @@ -1861,13 +1778,10 @@ class DiffMatchPatch { if (text1.length > Match_MaxBits) { // patch_splitMax will only provide an oversized pattern in the case of // a monster delete. - start_loc = - match_main(text, text1.substring(0, Match_MaxBits), expected_loc); + start_loc = match_main(text, text1.substring(0, Match_MaxBits), expected_loc); if (start_loc != -1) { end_loc = match_main( - text, - text1.substring(text1.length - Match_MaxBits), - expected_loc + text1.length - Match_MaxBits); + text, text1.substring(text1.length - Match_MaxBits), expected_loc + text1.length - Match_MaxBits); if (end_loc == -1 || start_loc >= end_loc) { // Can't find valid trailing context. Drop this patch. start_loc = -1; @@ -1887,23 +1801,18 @@ class DiffMatchPatch { delta = start_loc - expected_loc; String text2; if (end_loc == -1) { - text2 = text.substring( - start_loc, min(start_loc + text1.length, text.length)); + text2 = text.substring(start_loc, min(start_loc + text1.length, text.length)); } else { - text2 = text.substring( - start_loc, min(end_loc + Match_MaxBits, text.length)); + text2 = text.substring(start_loc, min(end_loc + Match_MaxBits, text.length)); } if (text1 == text2) { // Perfect match, just shove the replacement text in. - text = text.substring(0, start_loc) + - diff_text2(aPatch.diffs) + - text.substring(start_loc + text1.length); + text = text.substring(0, start_loc) + diff_text2(aPatch.diffs) + text.substring(start_loc + text1.length); } else { // Imperfect match. Run a diff to get a framework of equivalent // indices. final diffs = diff_main(text1, text2, false); - if (text1.length > Match_MaxBits && - diff_levenshtein(diffs) / text1.length > Patch_DeleteThreshold) { + if (text1.length > Match_MaxBits && diff_levenshtein(diffs) / text1.length > Patch_DeleteThreshold) { // The end points match, but the content is unacceptably bad. results[x] = false; } else { @@ -1914,14 +1823,11 @@ class DiffMatchPatch { int index2 = diff_xIndex(diffs, index1); if (aDiff.operation == Operation.insert) { // Insertion - text = text.substring(0, start_loc + index2) + - aDiff.text + - text.substring(start_loc + index2); + text = text.substring(0, start_loc + index2) + aDiff.text + text.substring(start_loc + index2); } else if (aDiff.operation == Operation.delete) { // Deletion text = text.substring(0, start_loc + index2) + - text.substring(start_loc + - diff_xIndex(diffs, index1 + aDiff.text.length)); + text.substring(start_loc + diff_xIndex(diffs, index1 + aDiff.text.length)); } } if (aDiff.operation != Operation.delete) { @@ -1972,8 +1878,7 @@ class DiffMatchPatch { // Grow first equality. Diff firstDiff = diffs[0]; int extraLength = paddingLength - firstDiff.text.length; - firstDiff.text = - nullPadding.substring(firstDiff.text.length) + firstDiff.text; + firstDiff.text = nullPadding.substring(firstDiff.text.length) + firstDiff.text; patch.start1 -= extraLength; patch.start2 -= extraLength; patch.length1 += extraLength; @@ -2028,8 +1933,7 @@ class DiffMatchPatch { patch.length1 = patch.length2 = precontext.length; patch.diffs.add(new Diff(Operation.equal, precontext)); } - while (!bigpatch.diffs.isEmpty && - patch.length1 < patch_size - Patch_Margin) { + while (!bigpatch.diffs.isEmpty && patch.length1 < patch_size - Patch_Margin) { Operation diff_type = bigpatch.diffs[0].operation; String diff_text = bigpatch.diffs[0].text; if (diff_type == Operation.insert) { @@ -2051,10 +1955,7 @@ class DiffMatchPatch { bigpatch.diffs.removeAt(0); } else { // Deletion or equality. Only take as much as we can stomach. - diff_text = diff_text.substring( - 0, - min(diff_text.length, - patch_size - patch.length1 - Patch_Margin)); + diff_text = diff_text.substring(0, min(diff_text.length, patch_size - patch.length1 - Patch_Margin)); patch.length1 += diff_text.length; start1 += diff_text.length; if (diff_type == Operation.equal) { @@ -2067,15 +1968,13 @@ class DiffMatchPatch { if (diff_text == bigpatch.diffs[0].text) { bigpatch.diffs.removeAt(0); } else { - bigpatch.diffs[0].text = - bigpatch.diffs[0].text.substring(diff_text.length); + bigpatch.diffs[0].text = bigpatch.diffs[0].text.substring(diff_text.length); } } } // Compute the head context for the next patch. precontext = diff_text2(patch.diffs); - precontext = - precontext.substring(max(0, precontext.length - Patch_Margin)); + precontext = precontext.substring(max(0, precontext.length - Patch_Margin)); // Append the end context for this patch. String postcontext; if (diff_text1(bigpatch.diffs).length > Patch_Margin) { @@ -2086,8 +1985,7 @@ class DiffMatchPatch { if (!postcontext.isEmpty) { patch.length1 += postcontext.length; patch.length2 += postcontext.length; - if (!patch.diffs.isEmpty && - patch.diffs.last.operation == Operation.equal) { + if (!patch.diffs.isEmpty && patch.diffs.last.operation == Operation.equal) { patch.diffs.last.text = patch.diffs.last.text + postcontext; } else { patch.diffs.add(new Diff(Operation.equal, postcontext)); @@ -2125,42 +2023,41 @@ class DiffMatchPatch { } final text = textline.split('\n'); int textPointer = 0; - final patchHeader = - new RegExp('^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@\$'); + final patchHeader = new RegExp('^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@\$'); while (textPointer < text.length) { - Match m = patchHeader.firstMatch(text[textPointer]); + Match? m = patchHeader.firstMatch(text[textPointer]); if (m == null) { throw new ArgumentError('Invalid patch string: ${text[textPointer]}'); } final patch = new Patch(); patches.add(patch); - patch.start1 = int.parse(m.group(1)); - if (m.group(2).isEmpty) { + patch.start1 = int.parse(m.group(1)!); + if (m.group(2)!.isEmpty) { patch.start1--; patch.length1 = 1; } else if (m.group(2) == '0') { patch.length1 = 0; } else { patch.start1--; - patch.length1 = int.parse(m.group(2)); + patch.length1 = int.parse(m.group(2)!); } - patch.start2 = int.parse(m.group(3)); - if (m.group(4).isEmpty) { + patch.start2 = int.parse(m.group(3)!); + if (m.group(4)!.isEmpty) { patch.start2--; patch.length2 = 1; } else if (m.group(4) == '0') { patch.length2 = 0; } else { patch.start2--; - patch.length2 = int.parse(m.group(4)); + patch.length2 = int.parse(m.group(4)!); } textPointer++; while (textPointer < text.length) { if (!text[textPointer].isEmpty) { final sign = text[textPointer][0]; - String line; + String? line; try { line = Uri.decodeFull(text[textPointer].substring(1)); } on ArgumentError { diff --git a/dart/PatchClass.dart b/dart/PatchClass.dart index 4544e4b8..dbdb5857 100644 --- a/dart/PatchClass.dart +++ b/dart/PatchClass.dart @@ -22,18 +22,16 @@ part of DiffMatchPatch; * Class representing one patch operation. */ class Patch { - List diffs; - int start1; - int start2; + List diffs = List.empty(growable: true); + int start1 = 0; + int start2 = 0; int length1 = 0; int length2 = 0; /** * Constructor. Initializes with an empty list of diffs. */ - Patch() { - this.diffs = []; - } + Patch(); /** * Emulate GNU diff's format. diff --git a/dart/tests/DiffMatchPatchTest.dart b/dart/tests/DiffMatchPatchTest.dart index d808cd86..9f25be72 100644 --- a/dart/tests/DiffMatchPatchTest.dart +++ b/dart/tests/DiffMatchPatchTest.dart @@ -22,8 +22,7 @@ import '../DiffMatchPatch.dart'; class Expect { static void equals(var expected, var actual, String msg) { if (expected == actual) return; - throw new Exception( - 'Expect.equals(expected: <$expected>, actual: <$actual> $msg) fails.'); + throw new Exception('Expect.equals(expected: <$expected>, actual: <$actual> $msg) fails.'); } static void isNull(actual, String msg) { @@ -57,9 +56,9 @@ class Expect { // messages when an unexpected item is inserted in a list. if (expected.length != actual.length) { throw new Exception('Expect.listEquals(list length, ' - 'expected: <${expected.length}>, actual: <${actual.length}> $msg) ' - 'fails: Next element <' - '${expected.length > n ? expected[n] : actual[n]}>'); + 'expected: <${expected.length}>, actual: <${actual.length}> $msg) ' + 'fails: Next element <' + '${expected.length > n ? expected[n] : actual[n]}>'); } } @@ -95,11 +94,10 @@ List _diff_rebuildtexts(diffs) { return [text1.toString(), text2.toString()]; } -DiffMatchPatch dmp; +DiffMatchPatch dmp = DiffMatchPatch(); // DIFF TEST FUNCTIONS - void testDiffCommonPrefix() { // Detect any common prefix. Expect.equals(0, dmp.diff_commonPrefix('abc', 'xyz'), 'diff_commonPrefix: Null case.'); @@ -140,22 +138,34 @@ void testDiffHalfmatch() { Expect.isNull(dmp.test_diff_halfMatch('12345', '23'), 'diff_halfMatch: No match #2.'); - Expect.listEquals(['12', '90', 'a', 'z', '345678'], dmp.test_diff_halfMatch('1234567890', 'a345678z'), 'diff_halfMatch: Single Match #1.'); + Expect.listEquals(['12', '90', 'a', 'z', '345678'], dmp.test_diff_halfMatch('1234567890', 'a345678z')!, + 'diff_halfMatch: Single Match #1.'); - Expect.listEquals(['a', 'z', '12', '90', '345678'], dmp.test_diff_halfMatch('a345678z', '1234567890'), 'diff_halfMatch: Single Match #2.'); + Expect.listEquals(['a', 'z', '12', '90', '345678'], dmp.test_diff_halfMatch('a345678z', '1234567890')!, + 'diff_halfMatch: Single Match #2.'); - Expect.listEquals(['abc', 'z', '1234', '0', '56789'], dmp.test_diff_halfMatch('abc56789z', '1234567890'), 'diff_halfMatch: Single Match #3.'); + Expect.listEquals(['abc', 'z', '1234', '0', '56789'], dmp.test_diff_halfMatch('abc56789z', '1234567890')!, + 'diff_halfMatch: Single Match #3.'); - Expect.listEquals(['a', 'xyz', '1', '7890', '23456'], dmp.test_diff_halfMatch('a23456xyz', '1234567890'), 'diff_halfMatch: Single Match #4.'); + Expect.listEquals(['a', 'xyz', '1', '7890', '23456'], dmp.test_diff_halfMatch('a23456xyz', '1234567890')!, + 'diff_halfMatch: Single Match #4.'); - Expect.listEquals(['12123', '123121', 'a', 'z', '1234123451234'], dmp.test_diff_halfMatch('121231234123451234123121', 'a1234123451234z'), 'diff_halfMatch: Multiple Matches #1.'); + Expect.listEquals(['12123', '123121', 'a', 'z', '1234123451234'], + dmp.test_diff_halfMatch('121231234123451234123121', 'a1234123451234z')!, 'diff_halfMatch: Multiple Matches #1.'); - Expect.listEquals(['', '-=-=-=-=-=', 'x', '', 'x-=-=-=-=-=-=-='], dmp.test_diff_halfMatch('x-=-=-=-=-=-=-=-=-=-=-=-=', 'xx-=-=-=-=-=-=-='), 'diff_halfMatch: Multiple Matches #2.'); + Expect.listEquals( + ['', '-=-=-=-=-=', 'x', '', 'x-=-=-=-=-=-=-='], + dmp.test_diff_halfMatch('x-=-=-=-=-=-=-=-=-=-=-=-=', 'xx-=-=-=-=-=-=-=')!, + 'diff_halfMatch: Multiple Matches #2.'); - Expect.listEquals(['-=-=-=-=-=', '', '', 'y', '-=-=-=-=-=-=-=y'], dmp.test_diff_halfMatch('-=-=-=-=-=-=-=-=-=-=-=-=y', '-=-=-=-=-=-=-=yy'), 'diff_halfMatch: Multiple Matches #3.'); + Expect.listEquals( + ['-=-=-=-=-=', '', '', 'y', '-=-=-=-=-=-=-=y'], + dmp.test_diff_halfMatch('-=-=-=-=-=-=-=-=-=-=-=-=y', '-=-=-=-=-=-=-=yy')!, + 'diff_halfMatch: Multiple Matches #3.'); // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy - Expect.listEquals(['qHillo', 'w', 'x', 'Hulloy', 'HelloHe'], dmp.test_diff_halfMatch('qHilloHelloHew', 'xHelloHeHulloy'), 'diff_halfMatch: Non-optimal halfmatch.'); + Expect.listEquals(['qHillo', 'w', 'x', 'Hulloy', 'HelloHe'], + dmp.test_diff_halfMatch('qHilloHelloHew', 'xHelloHeHulloy')!, 'diff_halfMatch: Non-optimal halfmatch.'); dmp.Diff_Timeout = 0.0; Expect.isNull(dmp.test_diff_halfMatch('qHilloHelloHew', 'xHelloHeHulloy'), 'diff_halfMatch: Optimal no halfmatch.'); @@ -169,11 +179,23 @@ void testDiffLinesToChars() { } // Convert lines down to characters. - assertLinesToCharsResultEquals({'chars1': '\u0001\u0002\u0001', 'chars2': '\u0002\u0001\u0002', 'lineArray': ['', 'alpha\n', 'beta\n']}, dmp.test_diff_linesToChars('alpha\nbeta\nalpha\n', 'beta\nalpha\nbeta\n'), 'diff_linesToChars: Shared lines.'); - - assertLinesToCharsResultEquals({'chars1': '', 'chars2': '\u0001\u0002\u0003\u0003', 'lineArray': ['', 'alpha\r\n', 'beta\r\n', '\r\n']}, dmp.test_diff_linesToChars('', 'alpha\r\nbeta\r\n\r\n\r\n'), 'diff_linesToChars: Empty string and blank lines.'); - - assertLinesToCharsResultEquals({'chars1': '\u0001', 'chars2': '\u0002', 'lineArray': ['', 'a', 'b']}, dmp.test_diff_linesToChars('a', 'b'), 'diff_linesToChars: No linebreaks.'); + assertLinesToCharsResultEquals({ + 'chars1': '\u0001\u0002\u0001', + 'chars2': '\u0002\u0001\u0002', + 'lineArray': ['', 'alpha\n', 'beta\n'] + }, dmp.test_diff_linesToChars('alpha\nbeta\nalpha\n', 'beta\nalpha\nbeta\n'), 'diff_linesToChars: Shared lines.'); + + assertLinesToCharsResultEquals({ + 'chars1': '', + 'chars2': '\u0001\u0002\u0003\u0003', + 'lineArray': ['', 'alpha\r\n', 'beta\r\n', '\r\n'] + }, dmp.test_diff_linesToChars('', 'alpha\r\nbeta\r\n\r\n\r\n'), 'diff_linesToChars: Empty string and blank lines.'); + + assertLinesToCharsResultEquals({ + 'chars1': '\u0001', + 'chars2': '\u0002', + 'lineArray': ['', 'a', 'b'] + }, dmp.test_diff_linesToChars('a', 'b'), 'diff_linesToChars: No linebreaks.'); // More than 256 to reveal any 8-bit limitations. int n = 300; @@ -188,7 +210,8 @@ void testDiffLinesToChars() { String chars = charList.toString(); Expect.equals(n, chars.length, 'Test initialization fail #2.'); lineList.insert(0, ''); - assertLinesToCharsResultEquals({'chars1': chars, 'chars2': '', 'lineArray': lineList}, dmp.test_diff_linesToChars(lines, ''), 'diff_linesToChars: More than 256.'); + assertLinesToCharsResultEquals({'chars1': chars, 'chars2': '', 'lineArray': lineList}, + dmp.test_diff_linesToChars(lines, ''), 'diff_linesToChars: More than 256.'); } void testDiffCharsToLines() { @@ -198,9 +221,15 @@ void testDiffCharsToLines() { Expect.equals(new Diff(Operation.equal, 'a'), new Diff(Operation.equal, 'a'), 'diff_charsToLines: Equality #2.'); // Convert chars up to lines. - List diffs = [new Diff(Operation.equal, '\u0001\u0002\u0001'), new Diff(Operation.insert, '\u0002\u0001\u0002')]; + List diffs = [ + new Diff(Operation.equal, '\u0001\u0002\u0001'), + new Diff(Operation.insert, '\u0002\u0001\u0002') + ]; dmp.test_diff_charsToLines(diffs, ['', 'alpha\n', 'beta\n']); - Expect.listEquals([new Diff(Operation.equal, 'alpha\nbeta\nalpha\n'), new Diff(Operation.insert, 'beta\nalpha\nbeta\n')], diffs, 'diff_charsToLines: Shared lines.'); + Expect.listEquals( + [new Diff(Operation.equal, 'alpha\nbeta\nalpha\n'), new Diff(Operation.insert, 'beta\nalpha\nbeta\n')], + diffs, + 'diff_charsToLines: Shared lines.'); // More than 256 to reveal any 8-bit limitations. int n = 300; @@ -239,7 +268,8 @@ void testDiffCleanupMerge() { diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.delete, 'b'), new Diff(Operation.insert, 'c')]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.equal, 'a'), new Diff(Operation.delete, 'b'), new Diff(Operation.insert, 'c')], diffs, 'diff_cleanupMerge: No change case.'); + Expect.listEquals([new Diff(Operation.equal, 'a'), new Diff(Operation.delete, 'b'), new Diff(Operation.insert, 'c')], + diffs, 'diff_cleanupMerge: No change case.'); diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.equal, 'b'), new Diff(Operation.equal, 'c')]; dmp.diff_cleanupMerge(diffs); @@ -253,41 +283,85 @@ void testDiffCleanupMerge() { dmp.diff_cleanupMerge(diffs); Expect.listEquals([new Diff(Operation.insert, 'abc')], diffs, 'diff_cleanupMerge: Merge insertions.'); - diffs = [new Diff(Operation.delete, 'a'), new Diff(Operation.insert, 'b'), new Diff(Operation.delete, 'c'), new Diff(Operation.insert, 'd'), new Diff(Operation.equal, 'e'), new Diff(Operation.equal, 'f')]; + diffs = [ + new Diff(Operation.delete, 'a'), + new Diff(Operation.insert, 'b'), + new Diff(Operation.delete, 'c'), + new Diff(Operation.insert, 'd'), + new Diff(Operation.equal, 'e'), + new Diff(Operation.equal, 'f') + ]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.delete, 'ac'), new Diff(Operation.insert, 'bd'), new Diff(Operation.equal, 'ef')], diffs, 'diff_cleanupMerge: Merge interweave.'); + Expect.listEquals( + [new Diff(Operation.delete, 'ac'), new Diff(Operation.insert, 'bd'), new Diff(Operation.equal, 'ef')], + diffs, + 'diff_cleanupMerge: Merge interweave.'); diffs = [new Diff(Operation.delete, 'a'), new Diff(Operation.insert, 'abc'), new Diff(Operation.delete, 'dc')]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.equal, 'a'), new Diff(Operation.delete, 'd'), new Diff(Operation.insert, 'b'), new Diff(Operation.equal, 'c')], diffs, 'diff_cleanupMerge: Prefix and suffix detection.'); - - diffs = [new Diff(Operation.equal, 'x'), new Diff(Operation.delete, 'a'), new Diff(Operation.insert, 'abc'), new Diff(Operation.delete, 'dc'), new Diff(Operation.equal, 'y')]; + Expect.listEquals([ + new Diff(Operation.equal, 'a'), + new Diff(Operation.delete, 'd'), + new Diff(Operation.insert, 'b'), + new Diff(Operation.equal, 'c') + ], diffs, 'diff_cleanupMerge: Prefix and suffix detection.'); + + diffs = [ + new Diff(Operation.equal, 'x'), + new Diff(Operation.delete, 'a'), + new Diff(Operation.insert, 'abc'), + new Diff(Operation.delete, 'dc'), + new Diff(Operation.equal, 'y') + ]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.equal, 'xa'), new Diff(Operation.delete, 'd'), new Diff(Operation.insert, 'b'), new Diff(Operation.equal, 'cy')], diffs, 'diff_cleanupMerge: Prefix and suffix detection with equalities.'); + Expect.listEquals([ + new Diff(Operation.equal, 'xa'), + new Diff(Operation.delete, 'd'), + new Diff(Operation.insert, 'b'), + new Diff(Operation.equal, 'cy') + ], diffs, 'diff_cleanupMerge: Prefix and suffix detection with equalities.'); diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.insert, 'ba'), new Diff(Operation.equal, 'c')]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.insert, 'ab'), new Diff(Operation.equal, 'ac')], diffs, 'diff_cleanupMerge: Slide edit left.'); + Expect.listEquals([new Diff(Operation.insert, 'ab'), new Diff(Operation.equal, 'ac')], diffs, + 'diff_cleanupMerge: Slide edit left.'); diffs = [new Diff(Operation.equal, 'c'), new Diff(Operation.insert, 'ab'), new Diff(Operation.equal, 'a')]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.equal, 'ca'), new Diff(Operation.insert, 'ba')], diffs, 'diff_cleanupMerge: Slide edit right.'); - - diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.delete, 'b'), new Diff(Operation.equal, 'c'), new Diff(Operation.delete, 'ac'), new Diff(Operation.equal, 'x')]; + Expect.listEquals([new Diff(Operation.equal, 'ca'), new Diff(Operation.insert, 'ba')], diffs, + 'diff_cleanupMerge: Slide edit right.'); + + diffs = [ + new Diff(Operation.equal, 'a'), + new Diff(Operation.delete, 'b'), + new Diff(Operation.equal, 'c'), + new Diff(Operation.delete, 'ac'), + new Diff(Operation.equal, 'x') + ]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abc'), new Diff(Operation.equal, 'acx')], diffs, 'diff_cleanupMerge: Slide edit left recursive.'); - - diffs = [new Diff(Operation.equal, 'x'), new Diff(Operation.delete, 'ca'), new Diff(Operation.equal, 'c'), new Diff(Operation.delete, 'b'), new Diff(Operation.equal, 'a')]; + Expect.listEquals([new Diff(Operation.delete, 'abc'), new Diff(Operation.equal, 'acx')], diffs, + 'diff_cleanupMerge: Slide edit left recursive.'); + + diffs = [ + new Diff(Operation.equal, 'x'), + new Diff(Operation.delete, 'ca'), + new Diff(Operation.equal, 'c'), + new Diff(Operation.delete, 'b'), + new Diff(Operation.equal, 'a') + ]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.equal, 'xca'), new Diff(Operation.delete, 'cba')], diffs, 'diff_cleanupMerge: Slide edit right recursive.'); + Expect.listEquals([new Diff(Operation.equal, 'xca'), new Diff(Operation.delete, 'cba')], diffs, + 'diff_cleanupMerge: Slide edit right recursive.'); diffs = [new Diff(Operation.delete, 'b'), new Diff(Operation.insert, 'ab'), new Diff(Operation.equal, 'c')]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.insert, 'a'), new Diff(Operation.equal, 'bc')], diffs, 'diff_cleanupMerge: Empty merge.'); + Expect.listEquals( + [new Diff(Operation.insert, 'a'), new Diff(Operation.equal, 'bc')], diffs, 'diff_cleanupMerge: Empty merge.'); diffs = [new Diff(Operation.equal, ''), new Diff(Operation.insert, 'a'), new Diff(Operation.equal, 'b')]; dmp.diff_cleanupMerge(diffs); - Expect.listEquals([new Diff(Operation.insert, 'a'), new Diff(Operation.equal, 'b')], diffs, 'diff_cleanupMerge: Empty equality.'); + Expect.listEquals( + [new Diff(Operation.insert, 'a'), new Diff(Operation.equal, 'b')], diffs, 'diff_cleanupMerge: Empty equality.'); } void testDiffCleanupSemanticLossless() { @@ -296,33 +370,75 @@ void testDiffCleanupSemanticLossless() { dmp.test_diff_cleanupSemanticLossless(diffs); Expect.listEquals([], diffs, 'diff_cleanupSemanticLossless: Null case.'); - diffs = [new Diff(Operation.equal, 'AAA\r\n\r\nBBB'), new Diff(Operation.insert, '\r\nDDD\r\n\r\nBBB'), new Diff(Operation.equal, '\r\nEEE')]; + diffs = [ + new Diff(Operation.equal, 'AAA\r\n\r\nBBB'), + new Diff(Operation.insert, '\r\nDDD\r\n\r\nBBB'), + new Diff(Operation.equal, '\r\nEEE') + ]; dmp.test_diff_cleanupSemanticLossless(diffs); - Expect.listEquals([new Diff(Operation.equal, 'AAA\r\n\r\n'), new Diff(Operation.insert, 'BBB\r\nDDD\r\n\r\n'), new Diff(Operation.equal, 'BBB\r\nEEE')], diffs, 'diff_cleanupSemanticLossless: Blank lines.'); - - diffs = [new Diff(Operation.equal, 'AAA\r\nBBB'), new Diff(Operation.insert, ' DDD\r\nBBB'), new Diff(Operation.equal, ' EEE')]; + Expect.listEquals([ + new Diff(Operation.equal, 'AAA\r\n\r\n'), + new Diff(Operation.insert, 'BBB\r\nDDD\r\n\r\n'), + new Diff(Operation.equal, 'BBB\r\nEEE') + ], diffs, 'diff_cleanupSemanticLossless: Blank lines.'); + + diffs = [ + new Diff(Operation.equal, 'AAA\r\nBBB'), + new Diff(Operation.insert, ' DDD\r\nBBB'), + new Diff(Operation.equal, ' EEE') + ]; dmp.test_diff_cleanupSemanticLossless(diffs); - Expect.listEquals([new Diff(Operation.equal, 'AAA\r\n'), new Diff(Operation.insert, 'BBB DDD\r\n'), new Diff(Operation.equal, 'BBB EEE')], diffs, 'diff_cleanupSemanticLossless: Line boundaries.'); - - diffs = [new Diff(Operation.equal, 'The c'), new Diff(Operation.insert, 'ow and the c'), new Diff(Operation.equal, 'at.')]; + Expect.listEquals([ + new Diff(Operation.equal, 'AAA\r\n'), + new Diff(Operation.insert, 'BBB DDD\r\n'), + new Diff(Operation.equal, 'BBB EEE') + ], diffs, 'diff_cleanupSemanticLossless: Line boundaries.'); + + diffs = [ + new Diff(Operation.equal, 'The c'), + new Diff(Operation.insert, 'ow and the c'), + new Diff(Operation.equal, 'at.') + ]; dmp.test_diff_cleanupSemanticLossless(diffs); - Expect.listEquals([new Diff(Operation.equal, 'The '), new Diff(Operation.insert, 'cow and the '), new Diff(Operation.equal, 'cat.')], diffs, 'diff_cleanupSemanticLossless: Word boundaries.'); - - diffs = [new Diff(Operation.equal, 'The-c'), new Diff(Operation.insert, 'ow-and-the-c'), new Diff(Operation.equal, 'at.')]; + Expect.listEquals([ + new Diff(Operation.equal, 'The '), + new Diff(Operation.insert, 'cow and the '), + new Diff(Operation.equal, 'cat.') + ], diffs, 'diff_cleanupSemanticLossless: Word boundaries.'); + + diffs = [ + new Diff(Operation.equal, 'The-c'), + new Diff(Operation.insert, 'ow-and-the-c'), + new Diff(Operation.equal, 'at.') + ]; dmp.test_diff_cleanupSemanticLossless(diffs); - Expect.listEquals([new Diff(Operation.equal, 'The-'), new Diff(Operation.insert, 'cow-and-the-'), new Diff(Operation.equal, 'cat.')], diffs, 'diff_cleanupSemanticLossless: Alphanumeric boundaries.'); + Expect.listEquals([ + new Diff(Operation.equal, 'The-'), + new Diff(Operation.insert, 'cow-and-the-'), + new Diff(Operation.equal, 'cat.') + ], diffs, 'diff_cleanupSemanticLossless: Alphanumeric boundaries.'); diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.delete, 'a'), new Diff(Operation.equal, 'ax')]; dmp.test_diff_cleanupSemanticLossless(diffs); - Expect.listEquals([new Diff(Operation.delete, 'a'), new Diff(Operation.equal, 'aax')], diffs, 'diff_cleanupSemanticLossless: Hitting the start.'); + Expect.listEquals([new Diff(Operation.delete, 'a'), new Diff(Operation.equal, 'aax')], diffs, + 'diff_cleanupSemanticLossless: Hitting the start.'); diffs = [new Diff(Operation.equal, 'xa'), new Diff(Operation.delete, 'a'), new Diff(Operation.equal, 'a')]; dmp.test_diff_cleanupSemanticLossless(diffs); - Expect.listEquals([new Diff(Operation.equal, 'xaa'), new Diff(Operation.delete, 'a')], diffs, 'diff_cleanupSemanticLossless: Hitting the end.'); - - diffs = [new Diff(Operation.equal, 'The xxx. The '), new Diff(Operation.insert, 'zzz. The '), new Diff(Operation.equal, 'yyy.')]; + Expect.listEquals([new Diff(Operation.equal, 'xaa'), new Diff(Operation.delete, 'a')], diffs, + 'diff_cleanupSemanticLossless: Hitting the end.'); + + diffs = [ + new Diff(Operation.equal, 'The xxx. The '), + new Diff(Operation.insert, 'zzz. The '), + new Diff(Operation.equal, 'yyy.') + ]; dmp.test_diff_cleanupSemanticLossless(diffs); - Expect.listEquals([new Diff(Operation.equal, 'The xxx.'), new Diff(Operation.insert, ' The zzz.'), new Diff(Operation.equal, ' The yyy.')], diffs, 'diff_cleanupSemanticLossless: Sentence boundaries.'); + Expect.listEquals([ + new Diff(Operation.equal, 'The xxx.'), + new Diff(Operation.insert, ' The zzz.'), + new Diff(Operation.equal, ' The yyy.') + ], diffs, 'diff_cleanupSemanticLossless: Sentence boundaries.'); } void testDiffCleanupSemantic() { @@ -331,45 +447,113 @@ void testDiffCleanupSemantic() { dmp.diff_cleanupSemantic(diffs); Expect.listEquals([], diffs, 'diff_cleanupSemantic: Null case.'); - diffs = [new Diff(Operation.delete, 'ab'), new Diff(Operation.insert, 'cd'), new Diff(Operation.equal, '12'), new Diff(Operation.delete, 'e')]; + diffs = [ + new Diff(Operation.delete, 'ab'), + new Diff(Operation.insert, 'cd'), + new Diff(Operation.equal, '12'), + new Diff(Operation.delete, 'e') + ]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.delete, 'ab'), new Diff(Operation.insert, 'cd'), new Diff(Operation.equal, '12'), new Diff(Operation.delete, 'e')], diffs, 'diff_cleanupSemantic: No elimination #1.'); - - diffs = [new Diff(Operation.delete, 'abc'), new Diff(Operation.insert, 'ABC'), new Diff(Operation.equal, '1234'), new Diff(Operation.delete, 'wxyz')]; + Expect.listEquals([ + new Diff(Operation.delete, 'ab'), + new Diff(Operation.insert, 'cd'), + new Diff(Operation.equal, '12'), + new Diff(Operation.delete, 'e') + ], diffs, 'diff_cleanupSemantic: No elimination #1.'); + + diffs = [ + new Diff(Operation.delete, 'abc'), + new Diff(Operation.insert, 'ABC'), + new Diff(Operation.equal, '1234'), + new Diff(Operation.delete, 'wxyz') + ]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abc'), new Diff(Operation.insert, 'ABC'), new Diff(Operation.equal, '1234'), new Diff(Operation.delete, 'wxyz')], diffs, 'diff_cleanupSemantic: No elimination #2.'); + Expect.listEquals([ + new Diff(Operation.delete, 'abc'), + new Diff(Operation.insert, 'ABC'), + new Diff(Operation.equal, '1234'), + new Diff(Operation.delete, 'wxyz') + ], diffs, 'diff_cleanupSemantic: No elimination #2.'); diffs = [new Diff(Operation.delete, 'a'), new Diff(Operation.equal, 'b'), new Diff(Operation.delete, 'c')]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abc'), new Diff(Operation.insert, 'b')], diffs, 'diff_cleanupSemantic: Simple elimination.'); - - diffs = [new Diff(Operation.delete, 'ab'), new Diff(Operation.equal, 'cd'), new Diff(Operation.delete, 'e'), new Diff(Operation.equal, 'f'), new Diff(Operation.insert, 'g')]; + Expect.listEquals([new Diff(Operation.delete, 'abc'), new Diff(Operation.insert, 'b')], diffs, + 'diff_cleanupSemantic: Simple elimination.'); + + diffs = [ + new Diff(Operation.delete, 'ab'), + new Diff(Operation.equal, 'cd'), + new Diff(Operation.delete, 'e'), + new Diff(Operation.equal, 'f'), + new Diff(Operation.insert, 'g') + ]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abcdef'), new Diff(Operation.insert, 'cdfg')], diffs, 'diff_cleanupSemantic: Backpass elimination.'); - - diffs = [new Diff(Operation.insert, '1'), new Diff(Operation.equal, 'A'), new Diff(Operation.delete, 'B'), new Diff(Operation.insert, '2'), new Diff(Operation.equal, '_'), new Diff(Operation.insert, '1'), new Diff(Operation.equal, 'A'), new Diff(Operation.delete, 'B'), new Diff(Operation.insert, '2')]; + Expect.listEquals([new Diff(Operation.delete, 'abcdef'), new Diff(Operation.insert, 'cdfg')], diffs, + 'diff_cleanupSemantic: Backpass elimination.'); + + diffs = [ + new Diff(Operation.insert, '1'), + new Diff(Operation.equal, 'A'), + new Diff(Operation.delete, 'B'), + new Diff(Operation.insert, '2'), + new Diff(Operation.equal, '_'), + new Diff(Operation.insert, '1'), + new Diff(Operation.equal, 'A'), + new Diff(Operation.delete, 'B'), + new Diff(Operation.insert, '2') + ]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.delete, 'AB_AB'), new Diff(Operation.insert, '1A2_1A2')], diffs, 'diff_cleanupSemantic: Multiple elimination.'); - - diffs = [new Diff(Operation.equal, 'The c'), new Diff(Operation.delete, 'ow and the c'), new Diff(Operation.equal, 'at.')]; + Expect.listEquals([new Diff(Operation.delete, 'AB_AB'), new Diff(Operation.insert, '1A2_1A2')], diffs, + 'diff_cleanupSemantic: Multiple elimination.'); + + diffs = [ + new Diff(Operation.equal, 'The c'), + new Diff(Operation.delete, 'ow and the c'), + new Diff(Operation.equal, 'at.') + ]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.equal, 'The '), new Diff(Operation.delete, 'cow and the '), new Diff(Operation.equal, 'cat.')], diffs, 'diff_cleanupSemantic: Word boundaries.'); + Expect.listEquals([ + new Diff(Operation.equal, 'The '), + new Diff(Operation.delete, 'cow and the '), + new Diff(Operation.equal, 'cat.') + ], diffs, 'diff_cleanupSemantic: Word boundaries.'); diffs = [new Diff(Operation.delete, 'abcxx'), new Diff(Operation.insert, 'xxdef')]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abcxx'), new Diff(Operation.insert, 'xxdef')], diffs, 'diff_cleanupSemantic: No overlap elimination.'); + Expect.listEquals([new Diff(Operation.delete, 'abcxx'), new Diff(Operation.insert, 'xxdef')], diffs, + 'diff_cleanupSemantic: No overlap elimination.'); diffs = [new Diff(Operation.delete, 'abcxxx'), new Diff(Operation.insert, 'xxxdef')]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abc'), new Diff(Operation.equal, 'xxx'), new Diff(Operation.insert, 'def')], diffs, 'diff_cleanupSemantic: Overlap elimination.'); + Expect.listEquals( + [new Diff(Operation.delete, 'abc'), new Diff(Operation.equal, 'xxx'), new Diff(Operation.insert, 'def')], + diffs, + 'diff_cleanupSemantic: Overlap elimination.'); diffs = [new Diff(Operation.delete, 'xxxabc'), new Diff(Operation.insert, 'defxxx')]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.insert, 'def'), new Diff(Operation.equal, 'xxx'), new Diff(Operation.delete, 'abc')], diffs, 'diff_cleanupSemantic: Reverse overlap elimination.'); - - diffs = [new Diff(Operation.delete, 'abcd1212'), new Diff(Operation.insert, '1212efghi'), new Diff(Operation.equal, '----'), new Diff(Operation.delete, 'A3'), new Diff(Operation.insert, '3BC')]; + Expect.listEquals( + [new Diff(Operation.insert, 'def'), new Diff(Operation.equal, 'xxx'), new Diff(Operation.delete, 'abc')], + diffs, + 'diff_cleanupSemantic: Reverse overlap elimination.'); + + diffs = [ + new Diff(Operation.delete, 'abcd1212'), + new Diff(Operation.insert, '1212efghi'), + new Diff(Operation.equal, '----'), + new Diff(Operation.delete, 'A3'), + new Diff(Operation.insert, '3BC') + ]; dmp.diff_cleanupSemantic(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abcd'), new Diff(Operation.equal, '1212'), new Diff(Operation.insert, 'efghi'), new Diff(Operation.equal, '----'), new Diff(Operation.delete, 'A'), new Diff(Operation.equal, '3'), new Diff(Operation.insert, 'BC')], diffs, 'diff_cleanupSemantic: Two overlap eliminations.'); + Expect.listEquals([ + new Diff(Operation.delete, 'abcd'), + new Diff(Operation.equal, '1212'), + new Diff(Operation.insert, 'efghi'), + new Diff(Operation.equal, '----'), + new Diff(Operation.delete, 'A'), + new Diff(Operation.equal, '3'), + new Diff(Operation.insert, 'BC') + ], diffs, 'diff_cleanupSemantic: Two overlap eliminations.'); } void testDiffCleanupEfficiency() { @@ -379,45 +563,110 @@ void testDiffCleanupEfficiency() { dmp.diff_cleanupEfficiency(diffs); Expect.listEquals([], diffs, 'diff_cleanupEfficiency: Null case.'); - diffs = [new Diff(Operation.delete, 'ab'), new Diff(Operation.insert, '12'), new Diff(Operation.equal, 'wxyz'), new Diff(Operation.delete, 'cd'), new Diff(Operation.insert, '34')]; + diffs = [ + new Diff(Operation.delete, 'ab'), + new Diff(Operation.insert, '12'), + new Diff(Operation.equal, 'wxyz'), + new Diff(Operation.delete, 'cd'), + new Diff(Operation.insert, '34') + ]; dmp.diff_cleanupEfficiency(diffs); - Expect.listEquals([new Diff(Operation.delete, 'ab'), new Diff(Operation.insert, '12'), new Diff(Operation.equal, 'wxyz'), new Diff(Operation.delete, 'cd'), new Diff(Operation.insert, '34')], diffs, 'diff_cleanupEfficiency: No elimination.'); - - diffs = [new Diff(Operation.delete, 'ab'), new Diff(Operation.insert, '12'), new Diff(Operation.equal, 'xyz'), new Diff(Operation.delete, 'cd'), new Diff(Operation.insert, '34')]; + Expect.listEquals([ + new Diff(Operation.delete, 'ab'), + new Diff(Operation.insert, '12'), + new Diff(Operation.equal, 'wxyz'), + new Diff(Operation.delete, 'cd'), + new Diff(Operation.insert, '34') + ], diffs, 'diff_cleanupEfficiency: No elimination.'); + + diffs = [ + new Diff(Operation.delete, 'ab'), + new Diff(Operation.insert, '12'), + new Diff(Operation.equal, 'xyz'), + new Diff(Operation.delete, 'cd'), + new Diff(Operation.insert, '34') + ]; dmp.diff_cleanupEfficiency(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abxyzcd'), new Diff(Operation.insert, '12xyz34')], diffs, 'diff_cleanupEfficiency: Four-edit elimination.'); - - diffs = [new Diff(Operation.insert, '12'), new Diff(Operation.equal, 'x'), new Diff(Operation.delete, 'cd'), new Diff(Operation.insert, '34')]; + Expect.listEquals([new Diff(Operation.delete, 'abxyzcd'), new Diff(Operation.insert, '12xyz34')], diffs, + 'diff_cleanupEfficiency: Four-edit elimination.'); + + diffs = [ + new Diff(Operation.insert, '12'), + new Diff(Operation.equal, 'x'), + new Diff(Operation.delete, 'cd'), + new Diff(Operation.insert, '34') + ]; dmp.diff_cleanupEfficiency(diffs); - Expect.listEquals([new Diff(Operation.delete, 'xcd'), new Diff(Operation.insert, '12x34')], diffs, 'diff_cleanupEfficiency: Three-edit elimination.'); - - diffs = [new Diff(Operation.delete, 'ab'), new Diff(Operation.insert, '12'), new Diff(Operation.equal, 'xy'), new Diff(Operation.insert, '34'), new Diff(Operation.equal, 'z'), new Diff(Operation.delete, 'cd'), new Diff(Operation.insert, '56')]; + Expect.listEquals([new Diff(Operation.delete, 'xcd'), new Diff(Operation.insert, '12x34')], diffs, + 'diff_cleanupEfficiency: Three-edit elimination.'); + + diffs = [ + new Diff(Operation.delete, 'ab'), + new Diff(Operation.insert, '12'), + new Diff(Operation.equal, 'xy'), + new Diff(Operation.insert, '34'), + new Diff(Operation.equal, 'z'), + new Diff(Operation.delete, 'cd'), + new Diff(Operation.insert, '56') + ]; dmp.diff_cleanupEfficiency(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abxyzcd'), new Diff(Operation.insert, '12xy34z56')], diffs, 'diff_cleanupEfficiency: Backpass elimination.'); + Expect.listEquals([new Diff(Operation.delete, 'abxyzcd'), new Diff(Operation.insert, '12xy34z56')], diffs, + 'diff_cleanupEfficiency: Backpass elimination.'); dmp.Diff_EditCost = 5; - diffs = [new Diff(Operation.delete, 'ab'), new Diff(Operation.insert, '12'), new Diff(Operation.equal, 'wxyz'), new Diff(Operation.delete, 'cd'), new Diff(Operation.insert, '34')]; + diffs = [ + new Diff(Operation.delete, 'ab'), + new Diff(Operation.insert, '12'), + new Diff(Operation.equal, 'wxyz'), + new Diff(Operation.delete, 'cd'), + new Diff(Operation.insert, '34') + ]; dmp.diff_cleanupEfficiency(diffs); - Expect.listEquals([new Diff(Operation.delete, 'abwxyzcd'), new Diff(Operation.insert, '12wxyz34')], diffs, 'diff_cleanupEfficiency: High cost elimination.'); + Expect.listEquals([new Diff(Operation.delete, 'abwxyzcd'), new Diff(Operation.insert, '12wxyz34')], diffs, + 'diff_cleanupEfficiency: High cost elimination.'); dmp.Diff_EditCost = 4; } void testDiffPrettyHtml() { // Pretty print. - List diffs = [new Diff(Operation.equal, 'a\n'), new Diff(Operation.delete, 'b'), new Diff(Operation.insert, 'c&d')]; - Expect.equals('
<B>b</B>c&d', dmp.diff_prettyHtml(diffs), 'diff_prettyHtml:'); + List diffs = [ + new Diff(Operation.equal, 'a\n'), + new Diff(Operation.delete, 'b'), + new Diff(Operation.insert, 'c&d') + ]; + Expect.equals( + '
<B>b</B>c&d', + dmp.diff_prettyHtml(diffs), + 'diff_prettyHtml:'); } void testDiffText() { // Compute the source and destination texts. - List diffs = [new Diff(Operation.equal, 'jump'), new Diff(Operation.delete, 's'), new Diff(Operation.insert, 'ed'), new Diff(Operation.equal, ' over '), new Diff(Operation.delete, 'the'), new Diff(Operation.insert, 'a'), new Diff(Operation.equal, ' lazy')]; + List diffs = [ + new Diff(Operation.equal, 'jump'), + new Diff(Operation.delete, 's'), + new Diff(Operation.insert, 'ed'), + new Diff(Operation.equal, ' over '), + new Diff(Operation.delete, 'the'), + new Diff(Operation.insert, 'a'), + new Diff(Operation.equal, ' lazy') + ]; Expect.equals('jumps over the lazy', dmp.diff_text1(diffs), 'diff_text1:'); Expect.equals('jumped over a lazy', dmp.diff_text2(diffs), 'diff_text2:'); } void testDiffDelta() { // Convert a diff into delta string. - List diffs = [new Diff(Operation.equal, 'jump'), new Diff(Operation.delete, 's'), new Diff(Operation.insert, 'ed'), new Diff(Operation.equal, ' over '), new Diff(Operation.delete, 'the'), new Diff(Operation.insert, 'a'), new Diff(Operation.equal, ' lazy'), new Diff(Operation.insert, 'old dog')]; + List diffs = [ + new Diff(Operation.equal, 'jump'), + new Diff(Operation.delete, 's'), + new Diff(Operation.insert, 'ed'), + new Diff(Operation.equal, ' over '), + new Diff(Operation.delete, 'the'), + new Diff(Operation.insert, 'a'), + new Diff(Operation.equal, ' lazy'), + new Diff(Operation.insert, 'old dog') + ]; String text1 = dmp.diff_text1(diffs); Expect.equals('jumps over the lazy', text1, 'diff_text1: Base text.'); @@ -437,7 +686,11 @@ void testDiffDelta() { Expect.throws(() => dmp.diff_fromDelta('', '+%c3%xy'), 'diff_fromDelta: Invalid character.'); // Test deltas with special characters. - diffs = [new Diff(Operation.equal, '\u0680 \x00 \t %'), new Diff(Operation.delete, '\u0681 \x01 \n ^'), new Diff(Operation.insert, '\u0682 \x02 \\ |')]; + diffs = [ + new Diff(Operation.equal, '\u0680 \x00 \t %'), + new Diff(Operation.delete, '\u0681 \x01 \n ^'), + new Diff(Operation.insert, '\u0682 \x02 \\ |') + ]; text1 = dmp.diff_text1(diffs); Expect.equals('\u0680 \x00 \t %\u0681 \x01 \n ^', text1, 'diff_text1: Unicode text.'); @@ -452,7 +705,8 @@ void testDiffDelta() { Expect.equals('A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + \$ , # ', text2, 'diff_text2: Unchanged characters.'); delta = dmp.diff_toDelta(diffs); - Expect.equals('+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + \$ , # ', delta, 'diff_toDelta: Unchanged characters.'); + Expect.equals( + '+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + \$ , # ', delta, 'diff_toDelta: Unchanged characters.'); // Convert delta string into a diff. Expect.listEquals(diffs, dmp.diff_fromDelta('', delta), 'diff_fromDelta: Unchanged characters.'); @@ -472,7 +726,11 @@ void testDiffDelta() { void testDiffXIndex() { // Translate a location in text1 to text2. - List diffs = [new Diff(Operation.delete, 'a'), new Diff(Operation.insert, '1234'), new Diff(Operation.equal, 'xyz')]; + List diffs = [ + new Diff(Operation.delete, 'a'), + new Diff(Operation.insert, '1234'), + new Diff(Operation.equal, 'xyz') + ]; Expect.equals(5, dmp.diff_xIndex(diffs, 2), 'diff_xIndex: Translation on equality.'); diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.delete, '1234'), new Diff(Operation.equal, 'xyz')]; @@ -480,7 +738,11 @@ void testDiffXIndex() { } void testDiffLevenshtein() { - List diffs = [new Diff(Operation.delete, 'abc'), new Diff(Operation.insert, '1234'), new Diff(Operation.equal, 'xyz')]; + List diffs = [ + new Diff(Operation.delete, 'abc'), + new Diff(Operation.insert, '1234'), + new Diff(Operation.equal, 'xyz') + ]; Expect.equals(4, dmp.diff_levenshtein(diffs), 'Levenshtein with trailing equality.'); diffs = [new Diff(Operation.equal, 'xyz'), new Diff(Operation.delete, 'abc'), new Diff(Operation.insert, '1234')]; @@ -497,15 +759,21 @@ void testDiffBisect() { // Since the resulting diff hasn't been normalized, it would be ok if // the insertion and deletion pairs are swapped. // If the order changes, tweak this test as required. - List diffs = [new Diff(Operation.delete, 'c'), new Diff(Operation.insert, 'm'), new Diff(Operation.equal, 'a'), new Diff(Operation.delete, 't'), new Diff(Operation.insert, 'p')]; + List diffs = [ + new Diff(Operation.delete, 'c'), + new Diff(Operation.insert, 'm'), + new Diff(Operation.equal, 'a'), + new Diff(Operation.delete, 't'), + new Diff(Operation.insert, 'p') + ]; // One year should be sufficient. - DateTime deadline = new DateTime.now().add(new Duration(days : 365)); + DateTime deadline = new DateTime.now().add(new Duration(days: 365)); Expect.listEquals(diffs, dmp.test_diff_bisect(a, b, deadline), 'diff_bisect: Normal.'); // Timeout. diffs = [new Diff(Operation.delete, 'cat'), new Diff(Operation.insert, 'map')]; // Set deadline to one year ago. - deadline = new DateTime.now().subtract(new Duration(days : 365)); + deadline = new DateTime.now().subtract(new Duration(days: 365)); Expect.listEquals(diffs, dmp.test_diff_bisect(a, b, deadline), 'diff_bisect: Timeout.'); } @@ -523,10 +791,22 @@ void testDiffMain() { diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.delete, '123'), new Diff(Operation.equal, 'bc')]; Expect.listEquals(diffs, dmp.diff_main('a123bc', 'abc', false), 'diff_main: Simple deletion.'); - diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.insert, '123'), new Diff(Operation.equal, 'b'), new Diff(Operation.insert, '456'), new Diff(Operation.equal, 'c')]; + diffs = [ + new Diff(Operation.equal, 'a'), + new Diff(Operation.insert, '123'), + new Diff(Operation.equal, 'b'), + new Diff(Operation.insert, '456'), + new Diff(Operation.equal, 'c') + ]; Expect.listEquals(diffs, dmp.diff_main('abc', 'a123b456c', false), 'diff_main: Two insertions.'); - diffs = [new Diff(Operation.equal, 'a'), new Diff(Operation.delete, '123'), new Diff(Operation.equal, 'b'), new Diff(Operation.delete, '456'), new Diff(Operation.equal, 'c')]; + diffs = [ + new Diff(Operation.equal, 'a'), + new Diff(Operation.delete, '123'), + new Diff(Operation.equal, 'b'), + new Diff(Operation.delete, '456'), + new Diff(Operation.equal, 'c') + ]; Expect.listEquals(diffs, dmp.diff_main('a123b456c', 'abc', false), 'diff_main: Two deletions.'); // Perform a real diff. @@ -535,27 +815,67 @@ void testDiffMain() { diffs = [new Diff(Operation.delete, 'a'), new Diff(Operation.insert, 'b')]; Expect.listEquals(diffs, dmp.diff_main('a', 'b', false), 'diff_main: Simple case #1.'); - diffs = [new Diff(Operation.delete, 'Apple'), new Diff(Operation.insert, 'Banana'), new Diff(Operation.equal, 's are a'), new Diff(Operation.insert, 'lso'), new Diff(Operation.equal, ' fruit.')]; - Expect.listEquals(diffs, dmp.diff_main('Apples are a fruit.', 'Bananas are also fruit.', false), 'diff_main: Simple case #2.'); - - diffs = [new Diff(Operation.delete, 'a'), new Diff(Operation.insert, '\u0680'), new Diff(Operation.equal, 'x'), new Diff(Operation.delete, '\t'), new Diff(Operation.insert, '\000')]; + diffs = [ + new Diff(Operation.delete, 'Apple'), + new Diff(Operation.insert, 'Banana'), + new Diff(Operation.equal, 's are a'), + new Diff(Operation.insert, 'lso'), + new Diff(Operation.equal, ' fruit.') + ]; + Expect.listEquals( + diffs, dmp.diff_main('Apples are a fruit.', 'Bananas are also fruit.', false), 'diff_main: Simple case #2.'); + + diffs = [ + new Diff(Operation.delete, 'a'), + new Diff(Operation.insert, '\u0680'), + new Diff(Operation.equal, 'x'), + new Diff(Operation.delete, '\t'), + new Diff(Operation.insert, '\000') + ]; Expect.listEquals(diffs, dmp.diff_main('ax\t', '\u0680x\000', false), 'diff_main: Simple case #3.'); - diffs = [new Diff(Operation.delete, '1'), new Diff(Operation.equal, 'a'), new Diff(Operation.delete, 'y'), new Diff(Operation.equal, 'b'), new Diff(Operation.delete, '2'), new Diff(Operation.insert, 'xab')]; + diffs = [ + new Diff(Operation.delete, '1'), + new Diff(Operation.equal, 'a'), + new Diff(Operation.delete, 'y'), + new Diff(Operation.equal, 'b'), + new Diff(Operation.delete, '2'), + new Diff(Operation.insert, 'xab') + ]; Expect.listEquals(diffs, dmp.diff_main('1ayb2', 'abxab', false), 'diff_main: Overlap #1.'); diffs = [new Diff(Operation.insert, 'xaxcx'), new Diff(Operation.equal, 'abc'), new Diff(Operation.delete, 'y')]; Expect.listEquals(diffs, dmp.diff_main('abcy', 'xaxcxabc', false), 'diff_main: Overlap #2.'); - diffs = [new Diff(Operation.delete, 'ABCD'), new Diff(Operation.equal, 'a'), new Diff(Operation.delete, '='), new Diff(Operation.insert, '-'), new Diff(Operation.equal, 'bcd'), new Diff(Operation.delete, '='), new Diff(Operation.insert, '-'), new Diff(Operation.equal, 'efghijklmnopqrs'), new Diff(Operation.delete, 'EFGHIJKLMNOefg')]; - Expect.listEquals(diffs, dmp.diff_main('ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg', 'a-bcd-efghijklmnopqrs', false), 'diff_main: Overlap #3.'); - - diffs = [new Diff(Operation.insert, ' '), new Diff(Operation.equal, 'a'), new Diff(Operation.insert, 'nd'), new Diff(Operation.equal, ' [[Pennsylvania]]'), new Diff(Operation.delete, ' and [[New')]; - Expect.listEquals(diffs, dmp.diff_main('a [[Pennsylvania]] and [[New', ' and [[Pennsylvania]]', false), 'diff_main: Large equality.'); - - dmp.Diff_Timeout = 0.1; // 100ms - String 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'; - String 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'; + diffs = [ + new Diff(Operation.delete, 'ABCD'), + new Diff(Operation.equal, 'a'), + new Diff(Operation.delete, '='), + new Diff(Operation.insert, '-'), + new Diff(Operation.equal, 'bcd'), + new Diff(Operation.delete, '='), + new Diff(Operation.insert, '-'), + new Diff(Operation.equal, 'efghijklmnopqrs'), + new Diff(Operation.delete, 'EFGHIJKLMNOefg') + ]; + Expect.listEquals(diffs, dmp.diff_main('ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg', 'a-bcd-efghijklmnopqrs', false), + 'diff_main: Overlap #3.'); + + diffs = [ + new Diff(Operation.insert, ' '), + new Diff(Operation.equal, 'a'), + new Diff(Operation.insert, 'nd'), + new Diff(Operation.equal, ' [[Pennsylvania]]'), + new Diff(Operation.delete, ' and [[New') + ]; + Expect.listEquals(diffs, dmp.diff_main('a [[Pennsylvania]] and [[New', ' and [[Pennsylvania]]', false), + 'diff_main: Large equality.'); + + dmp.Diff_Timeout = 0.1; // 100ms + String 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'; + String 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'; // Increase the text lengths by 1024 times to ensure a timeout. for (int i = 0; i < 10; i++) { a += a; @@ -593,7 +913,6 @@ void testDiffMain() { Expect.throws(() => dmp.diff_main(null, null), 'diff_main: Null inputs.'); } - // MATCH TEST FUNCTIONS void testMatchAlphabet() { @@ -641,12 +960,14 @@ void testMatchBitap() { Expect.equals(8, dmp.test_match_bitap('abcdexyzabcde', 'abccde', 5), 'match_bitap: Multiple select #2.'); - dmp.Match_Distance = 10; // Strict location. - Expect.equals(-1, dmp.test_match_bitap('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24), 'match_bitap: Distance test #1.'); + dmp.Match_Distance = 10; // Strict location. + Expect.equals( + -1, dmp.test_match_bitap('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24), 'match_bitap: Distance test #1.'); - Expect.equals(0, dmp.test_match_bitap('abcdefghijklmnopqrstuvwxyz', 'abcdxxefg', 1), 'match_bitap: Distance test #2.'); + Expect.equals( + 0, dmp.test_match_bitap('abcdefghijklmnopqrstuvwxyz', 'abcdxxefg', 1), 'match_bitap: Distance test #2.'); - dmp.Match_Distance = 1000; // Loose location. + dmp.Match_Distance = 1000; // Loose location. Expect.equals(0, dmp.test_match_bitap('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24), 'match_bitap: Distance test #3.'); } @@ -665,17 +986,16 @@ void testMatchMain() { Expect.equals(0, dmp.match_main('abcdef', 'abcdefy', 0), 'match_main: Oversized pattern.'); dmp.Match_Threshold = 0.7; - Expect.equals(4, dmp.match_main('I am the very model of a modern major general.', ' that berry ', 5), 'match_main: Complex match.'); + Expect.equals(4, dmp.match_main('I am the very model of a modern major general.', ' that berry ', 5), + 'match_main: Complex match.'); dmp.Match_Threshold = 0.5; // Test null inputs. Expect.throws(() => dmp.match_main(null, null, 0), 'match_main: Null inputs.'); } - // PATCH TEST FUNCTIONS - void testPatchObj() { // Patch Object. Patch p = new Patch(); @@ -683,7 +1003,15 @@ void testPatchObj() { p.start2 = 21; p.length1 = 18; p.length2 = 17; - p.diffs = [new Diff(Operation.equal, 'jump'), new Diff(Operation.delete, 's'), new Diff(Operation.insert, 'ed'), new Diff(Operation.equal, ' over '), new Diff(Operation.delete, 'the'), new Diff(Operation.insert, 'a'), new Diff(Operation.equal, '\nlaz')]; + p.diffs = [ + new Diff(Operation.equal, 'jump'), + new Diff(Operation.delete, 's'), + new Diff(Operation.insert, 'ed'), + new Diff(Operation.equal, ' over '), + new Diff(Operation.delete, 'the'), + new Diff(Operation.insert, 'a'), + new Diff(Operation.equal, '\nlaz') + ]; String strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n'; Expect.equals(strp, p.toString(), 'Patch: toString.'); } @@ -694,11 +1022,14 @@ void testPatchFromText() { String strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n'; Expect.equals(strp, dmp.patch_fromText(strp)[0].toString(), 'patch_fromText: #1.'); - Expect.equals('@@ -1 +1 @@\n-a\n+b\n', dmp.patch_fromText('@@ -1 +1 @@\n-a\n+b\n')[0].toString(), 'patch_fromText: #2.'); + Expect.equals( + '@@ -1 +1 @@\n-a\n+b\n', dmp.patch_fromText('@@ -1 +1 @@\n-a\n+b\n')[0].toString(), 'patch_fromText: #2.'); - Expect.equals('@@ -1,3 +0,0 @@\n-abc\n', dmp.patch_fromText('@@ -1,3 +0,0 @@\n-abc\n')[0].toString(), 'patch_fromText: #3.'); + Expect.equals( + '@@ -1,3 +0,0 @@\n-abc\n', dmp.patch_fromText('@@ -1,3 +0,0 @@\n-abc\n')[0].toString(), 'patch_fromText: #3.'); - Expect.equals('@@ -0,0 +1,3 @@\n+abc\n', dmp.patch_fromText('@@ -0,0 +1,3 @@\n+abc\n')[0].toString(), 'patch_fromText: #4.'); + Expect.equals( + '@@ -0,0 +1,3 @@\n+abc\n', dmp.patch_fromText('@@ -0,0 +1,3 @@\n+abc\n')[0].toString(), 'patch_fromText: #4.'); // Generates error. Expect.throws(() => dmp.patch_fromText('Bad\nPatch\n'), 'patch_fromText: #5.'); @@ -720,19 +1051,23 @@ void testPatchAddContext() { Patch p; p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0]; dmp.test_patch_addContext(p, 'The quick brown fox jumps over the lazy dog.'); - Expect.equals('@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n', p.toString(), 'patch_addContext: Simple case.'); + Expect.equals( + '@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n', p.toString(), 'patch_addContext: Simple case.'); p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0]; dmp.test_patch_addContext(p, 'The quick brown fox jumps.'); - Expect.equals('@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n', p.toString(), 'patch_addContext: Not enough trailing context.'); + Expect.equals('@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n', p.toString(), + 'patch_addContext: Not enough trailing context.'); p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0]; dmp.test_patch_addContext(p, 'The quick brown fox jumps.'); - Expect.equals('@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n', p.toString(), 'patch_addContext: Not enough leading context.'); + Expect.equals( + '@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n', p.toString(), 'patch_addContext: Not enough leading context.'); p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0]; dmp.test_patch_addContext(p, 'The quick brown fox jumps. The quick brown fox crashes.'); - Expect.equals('@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n', p.toString(), 'patch_addContext: Ambiguity.'); + Expect.equals( + '@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n', p.toString(), 'patch_addContext: Ambiguity.'); } void testPatchMake() { @@ -742,12 +1077,14 @@ void testPatchMake() { String text1 = 'The quick brown fox jumps over the lazy dog.'; String text2 = 'That quick brown fox jumped over a lazy dog.'; - String 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'; + String 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'; // The second patch must be '-21,17 +21,18', not '-22,17 +21,18' due to rolling context. patches = dmp.patch_make(text2, text1); Expect.equals(expectedPatch, dmp.patch_toText(patches), 'patch_make: Text2+Text1 inputs.'); - 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'; + 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'; patches = dmp.patch_make(text1, text2); Expect.equals(expectedPatch, dmp.patch_toText(patches), 'patch_make: Text1+Text2 inputs.'); @@ -762,10 +1099,17 @@ void testPatchMake() { Expect.equals(expectedPatch, dmp.patch_toText(patches), 'patch_make: Text1+Text2+Diff inputs (deprecated).'); patches = dmp.patch_make('`1234567890-=[]\\;\',./', '~!@#\$%^&*()_+{}|:"<>?'); - Expect.equals('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#\$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n', dmp.patch_toText(patches), 'patch_toText: Character encoding.'); + Expect.equals('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#\$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n', + dmp.patch_toText(patches), 'patch_toText: Character encoding.'); diffs = [new Diff(Operation.delete, '`1234567890-=[]\\;\',./'), new Diff(Operation.insert, '~!@#\$%^&*()_+{}|:"<>?')]; - Expect.listEquals(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, 'patch_fromText: Character decoding.'); + Expect.listEquals( + 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, + 'patch_fromText: Character decoding.'); final sb = new StringBuffer(); for (int x = 0; x < 100; x++) { @@ -784,22 +1128,34 @@ void testPatchMake() { void testPatchSplitMax() { // Assumes that Match_MaxBits is 32. List patches; - patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz01234567890', 'XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0'); + patches = dmp.patch_make( + 'abcdefghijklmnopqrstuvwxyz01234567890', 'XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0'); dmp.patch_splitMax(patches); - Expect.equals('@@ -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), 'patch_splitMax: #1.'); + Expect.equals( + '@@ -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), + 'patch_splitMax: #1.'); - patches = dmp.patch_make('abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz', 'abcdefuvwxyz'); + patches = dmp.patch_make( + 'abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz', 'abcdefuvwxyz'); String oldToText = dmp.patch_toText(patches); dmp.patch_splitMax(patches); Expect.equals(oldToText, dmp.patch_toText(patches), 'patch_splitMax: #2.'); patches = dmp.patch_make('1234567890123456789012345678901234567890123456789012345678901234567890', 'abc'); dmp.patch_splitMax(patches); - Expect.equals('@@ -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), 'patch_splitMax: #3.'); + Expect.equals( + '@@ -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), + 'patch_splitMax: #3.'); - 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'); + 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'); dmp.patch_splitMax(patches); - Expect.equals('@@ -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), 'patch_splitMax: #4.'); + Expect.equals( + '@@ -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), + 'patch_splitMax: #4.'); } void testPatchAddPadding() { @@ -807,17 +1163,21 @@ void testPatchAddPadding() { patches = dmp.patch_make('', 'test'); Expect.equals('@@ -0,0 +1,4 @@\n+test\n', dmp.patch_toText(patches), 'patch_addPadding: Both edges full.'); dmp.patch_addPadding(patches); - Expect.equals('@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n', dmp.patch_toText(patches), 'patch_addPadding: Both edges full.'); + Expect.equals('@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n', dmp.patch_toText(patches), + 'patch_addPadding: Both edges full.'); patches = dmp.patch_make('XY', 'XtestY'); Expect.equals('@@ -1,2 +1,6 @@\n X\n+test\n Y\n', dmp.patch_toText(patches), 'patch_addPadding: Both edges partial.'); dmp.patch_addPadding(patches); - Expect.equals('@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n', dmp.patch_toText(patches), 'patch_addPadding: Both edges partial.'); + Expect.equals('@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n', dmp.patch_toText(patches), + 'patch_addPadding: Both edges partial.'); patches = dmp.patch_make('XXXXYYYY', 'XXXXtestYYYY'); - Expect.equals('@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches), 'patch_addPadding: Both edges none.'); + Expect.equals( + '@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches), 'patch_addPadding: Both edges none.'); dmp.patch_addPadding(patches); - Expect.equals('@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches), 'patch_addPadding: Both edges none.'); + Expect.equals( + '@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches), 'patch_addPadding: Both edges none.'); } void testPatchApply() { @@ -831,7 +1191,8 @@ void testPatchApply() { String resultStr = '${results[0]}\t${boolArray.length}'; Expect.equals('Hello world.\t0', resultStr, 'patch_apply: Null case.'); - patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'That quick brown fox jumped over a lazy dog.'); + patches = + dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'That quick brown fox jumped over a lazy dog.'); results = dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.'); boolArray = results[1]; resultStr = '${results[0]}\t${boolArray[0]}\t${boolArray[1]}'; @@ -840,28 +1201,34 @@ void testPatchApply() { results = dmp.patch_apply(patches, 'The quick red rabbit jumps over the tired tiger.'); boolArray = results[1]; resultStr = '${results[0]}\t${boolArray[0]}\t${boolArray[1]}'; - Expect.equals('That quick red rabbit jumped over a tired tiger.\ttrue\ttrue', resultStr, 'patch_apply: Partial match.'); + Expect.equals( + 'That quick red rabbit jumped over a tired tiger.\ttrue\ttrue', resultStr, 'patch_apply: Partial match.'); results = dmp.patch_apply(patches, 'I am the very model of a modern major general.'); boolArray = results[1]; resultStr = '${results[0]}\t${boolArray[0]}\t${boolArray[1]}'; - Expect.equals('I am the very model of a modern major general.\tfalse\tfalse', resultStr, 'patch_apply: Failed match.'); + Expect.equals( + 'I am the very model of a modern major general.\tfalse\tfalse', resultStr, 'patch_apply: Failed match.'); patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy'); - results = dmp.patch_apply(patches, 'x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y'); + results = + dmp.patch_apply(patches, 'x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y'); boolArray = results[1]; resultStr = '${results[0]}\t${boolArray[0]}\t${boolArray[1]}'; Expect.equals('xabcy\ttrue\ttrue', resultStr, 'patch_apply: Big delete, small change.'); patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy'); - results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y'); + results = + dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y'); boolArray = results[1]; resultStr = '${results[0]}\t${boolArray[0]}\t${boolArray[1]}'; - Expect.equals('xabc12345678901234567890---------------++++++++++---------------12345678901234567890y\tfalse\ttrue', resultStr, 'patch_apply: Big delete, big change 1.'); + Expect.equals('xabc12345678901234567890---------------++++++++++---------------12345678901234567890y\tfalse\ttrue', + resultStr, 'patch_apply: Big delete, big change 1.'); dmp.Patch_DeleteThreshold = 0.6; patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy'); - results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y'); + results = + dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y'); boolArray = results[1]; resultStr = '${results[0]}\t${boolArray[0]}\t${boolArray[1]}'; Expect.equals('xabcy\ttrue\ttrue', resultStr, 'patch_apply: Big delete, big change 2.'); @@ -870,11 +1237,13 @@ void testPatchApply() { // Compensate for failed patch. dmp.Match_Threshold = 0.0; dmp.Match_Distance = 0; - patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz--------------------1234567890', 'abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890'); + patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz--------------------1234567890', + 'abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890'); results = dmp.patch_apply(patches, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890'); boolArray = results[1]; resultStr = '${results[0]}\t${boolArray[0]}\t${boolArray[1]}'; - Expect.equals('ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890\tfalse\ttrue', resultStr, 'patch_apply: Compensate for failed patch.'); + Expect.equals('ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890\tfalse\ttrue', resultStr, + 'patch_apply: Compensate for failed patch.'); dmp.Match_Threshold = 0.5; dmp.Match_Distance = 1000; diff --git a/dart/tests/Speedtest.dart b/dart/tests/Speedtest.dart index 7fb565ae..7008f7ed 100644 --- a/dart/tests/Speedtest.dart +++ b/dart/tests/Speedtest.dart @@ -5,10 +5,10 @@ import '../DiffMatchPatch.dart'; // dart2js -O4 --out=Speedtest.dart.js Speedtest.dart void launch(Event e) { - HtmlElement input1 = document.getElementById('text1'); - HtmlElement input2 = document.getElementById('text2'); - String text1 = input1.text; - String text2 = input2.text; + Element? input1 = document.getElementById('text1'); + Element? input2 = document.getElementById('text2'); + String? text1 = input1!.text; + String? text2 = input2!.text; DiffMatchPatch dmp = new DiffMatchPatch(); dmp.Diff_Timeout = 0.0; @@ -19,20 +19,18 @@ void launch(Event e) { DateTime date_end = new DateTime.now(); var ds = dmp.diff_prettyHtml(d); - document.getElementById('outputdiv').setInnerHtml( - '$ds
Time: ${date_end.difference(date_start)} (h:mm:ss.mmm)', + document.getElementById('outputdiv')!.setInnerHtml('$ds
Time: ${date_end.difference(date_start)} (h:mm:ss.mmm)', validator: new TrustedNodeValidator()); } void main() { - document.getElementById('launch').addEventListener('click', launch); - document.getElementById('outputdiv').setInnerHtml(''); + document.getElementById('launch')!.addEventListener('click', launch); + document.getElementById('outputdiv')!.setInnerHtml(''); } /// A NodeValidator which allows any contents. /// The default validator strips 'style' attributes. class TrustedNodeValidator implements NodeValidator { bool allowsElement(Element element) => true; - bool allowsAttribute(Element element, String attributeName, String value) - => true; + bool allowsAttribute(Element element, String attributeName, String value) => true; }