From 6f2e00c1cec7a86ef820f567b4ecbd990f0470bb Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Wed, 14 Feb 2018 09:38:00 -0800 Subject: [PATCH 01/10] Add java related entries to .gitignore --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 41779de8..684d232a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,10 @@ xcuserdata dart/tests/Speedtest.dart.js.deps dart/tests/Speedtest.dart.js.map + +#Java Related +.settings/ +.classpath +.project +.metadata +target/ From ffe5affd98c5402ea58911c1713ee69988070b66 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Wed, 14 Feb 2018 09:42:05 -0800 Subject: [PATCH 02/10] Convert Java project to Maven --- java/pom.xml | 181 ++++++++++++++++++ .../neil/plaintext/diff_match_patch.java | 0 .../name/fraser/neil/plaintext/Speedtest.java | 0 .../name/fraser/neil/plaintext/Speedtest1.txt | 0 .../name/fraser/neil/plaintext/Speedtest2.txt | 0 .../neil/plaintext/diff_match_patch_test.java | 0 6 files changed, 181 insertions(+) create mode 100644 java/pom.xml rename java/src/{ => main/java}/name/fraser/neil/plaintext/diff_match_patch.java (100%) rename java/{tests => src/test/java}/name/fraser/neil/plaintext/Speedtest.java (100%) rename java/{tests => src/test/java}/name/fraser/neil/plaintext/Speedtest1.txt (100%) rename java/{tests => src/test/java}/name/fraser/neil/plaintext/Speedtest2.txt (100%) rename java/{tests => src/test/java}/name/fraser/neil/plaintext/diff_match_patch_test.java (100%) diff --git a/java/pom.xml b/java/pom.xml new file mode 100644 index 00000000..0d68ff90 --- /dev/null +++ b/java/pom.xml @@ -0,0 +1,181 @@ + + 4.0.0 + + org.sonatype.oss + oss-parent + 9 + + + com.google + diff-match-patch + 1.0.0 + jar + + + 1.6 + 4.11 + UTF-8 + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh + https://oss.sonatype.org/ + true + + + + + maven-compiler-plugin + 3.6.2 + + ${java-version} + ${java-version} + true + true + + + + + maven-source-plugin + 3.0.1 + + + + jar + + + + + + + maven-javadoc-plugin + 2.10.4 + + *.internal.* + false + -Xdoclint:none + + + + + jar + + true + + + + + + maven-jar-plugin + 2.6 + + true + + true + + true + true + + + + + + + maven-surefire-plugin + 2.20 + + false + + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + + + + + + junit + junit + ${junit.version} + test + + + Google Diff Match and Patch + https://github.com/google/diff-match-patch + Diff Match Patch is a high-performance library in multiple languages that manipulates plain text. + XXXX + + http://www.google.com + Google Inc + + + https://github.com/google/diff-match-patch + scm:git:git@github.com:google/diff-match-patch + scm:git:git@github.com:google/diff-match-patch + google-analytics-java-1.1.2 + + + github.com + https://github.com/google/diff-match-patch/issues + + + + Neil Fraser + http://www.google.com + http://www.google.com + + Initiator + Commiter + + neil at google.com + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + \ No newline at end of file diff --git a/java/src/name/fraser/neil/plaintext/diff_match_patch.java b/java/src/main/java/name/fraser/neil/plaintext/diff_match_patch.java similarity index 100% rename from java/src/name/fraser/neil/plaintext/diff_match_patch.java rename to java/src/main/java/name/fraser/neil/plaintext/diff_match_patch.java diff --git a/java/tests/name/fraser/neil/plaintext/Speedtest.java b/java/src/test/java/name/fraser/neil/plaintext/Speedtest.java similarity index 100% rename from java/tests/name/fraser/neil/plaintext/Speedtest.java rename to java/src/test/java/name/fraser/neil/plaintext/Speedtest.java diff --git a/java/tests/name/fraser/neil/plaintext/Speedtest1.txt b/java/src/test/java/name/fraser/neil/plaintext/Speedtest1.txt similarity index 100% rename from java/tests/name/fraser/neil/plaintext/Speedtest1.txt rename to java/src/test/java/name/fraser/neil/plaintext/Speedtest1.txt diff --git a/java/tests/name/fraser/neil/plaintext/Speedtest2.txt b/java/src/test/java/name/fraser/neil/plaintext/Speedtest2.txt similarity index 100% rename from java/tests/name/fraser/neil/plaintext/Speedtest2.txt rename to java/src/test/java/name/fraser/neil/plaintext/Speedtest2.txt diff --git a/java/tests/name/fraser/neil/plaintext/diff_match_patch_test.java b/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java similarity index 100% rename from java/tests/name/fraser/neil/plaintext/diff_match_patch_test.java rename to java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java From cb6cbb704d997b27a4e36b8e61090f11a9d14577 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Thu, 15 Feb 2018 14:22:38 -0800 Subject: [PATCH 03/10] Fix PR comments regd formatting and typos --- java/pom.xml | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index 0d68ff90..fbb68844 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -1,4 +1,4 @@ - + 4.0.0 org.sonatype.oss @@ -20,15 +20,15 @@ - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.8 - true - - ossrh - https://oss.sonatype.org/ - true - + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh + https://oss.sonatype.org/ + true + @@ -98,7 +98,7 @@ org.apache.maven.plugins maven-release-plugin - 2.5.3 + 2.5.3 @@ -114,17 +114,16 @@ Google Diff Match and Patch https://github.com/google/diff-match-patch Diff Match Patch is a high-performance library in multiple languages that manipulates plain text. - XXXX + 2006 - http://www.google.com + https://www.google.com Google Inc https://github.com/google/diff-match-patch scm:git:git@github.com:google/diff-match-patch scm:git:git@github.com:google/diff-match-patch - google-analytics-java-1.1.2 - + github.com https://github.com/google/diff-match-patch/issues @@ -132,8 +131,8 @@ Neil Fraser - http://www.google.com - http://www.google.com + https://www.google.com + https://www.google.com Initiator Commiter @@ -144,7 +143,7 @@ The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt + https://www.apache.org/licenses/LICENSE-2.0.txt repo From be9666d7d311a109c039d45f8b86be06aca79948 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Thu, 15 Feb 2018 14:23:47 -0800 Subject: [PATCH 04/10] Remove the junit dependency as it is not used --- java/pom.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index fbb68844..a28b366c 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -13,7 +13,6 @@ 1.6 - 4.11 UTF-8 @@ -103,14 +102,6 @@ - - - junit - junit - ${junit.version} - test - - Google Diff Match and Patch https://github.com/google/diff-match-patch Diff Match Patch is a high-performance library in multiple languages that manipulates plain text. From 192175ac18211d2fb5c55be0650e0235917d23a1 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Thu, 15 Feb 2018 14:28:47 -0800 Subject: [PATCH 05/10] Fix author email --- java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/pom.xml b/java/pom.xml index a28b366c..22db880b 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -128,7 +128,7 @@ Initiator Commiter - neil at google.com + fraser at google.com From 24a6bcd10ce0d2b34e664a3cb3a919d12d024cc1 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Thu, 15 Feb 2018 14:28:59 -0800 Subject: [PATCH 06/10] Fix paths in the file header --- .../name/fraser/neil/plaintext/diff_match_patch_test.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java b/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java index a6f64a1c..f83852d2 100644 --- a/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java +++ b/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java @@ -18,9 +18,11 @@ /** * Compile from diff-match-patch/java with: - * javac -d classes src/name/fraser/neil/plaintext/diff_match_patch.java tests/name/fraser/neil/plaintext/diff_match_patch_test.java + * javac -d target/classes src/main/java/name/fraser/neil/plaintext/diff_match_patch.java + * javac -classpath target/classes -d target/test-classes src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java + * * Execute with: - * java -classpath classes name/fraser/neil/plaintext/diff_match_patch_test + * java -classpath target/classes:target/test-classes name/fraser/neil/plaintext/diff_match_patch_test */ package name.fraser.neil.plaintext; From 168ebf7dd4d68b62196f81120ed9b124328dcaec Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Thu, 15 Feb 2018 15:57:37 -0800 Subject: [PATCH 07/10] Convert tests to Junit Tests --- java/pom.xml | 10 + .../neil/plaintext/DiffMatchPatchTest.java | 1005 +++++++++++++++++ .../name/fraser/neil/plaintext/SpeedTest.java | 57 + .../name/fraser/neil/plaintext/Speedtest.java | 61 - .../neil/plaintext/diff_match_patch_test.java | 973 ---------------- 5 files changed, 1072 insertions(+), 1034 deletions(-) create mode 100644 java/src/test/java/name/fraser/neil/plaintext/DiffMatchPatchTest.java create mode 100644 java/src/test/java/name/fraser/neil/plaintext/SpeedTest.java delete mode 100644 java/src/test/java/name/fraser/neil/plaintext/Speedtest.java delete mode 100644 java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java diff --git a/java/pom.xml b/java/pom.xml index 22db880b..06216d38 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -14,8 +14,18 @@ 1.6 UTF-8 + 4.11 + + + junit + junit + ${junit.version} + test + + + diff --git a/java/src/test/java/name/fraser/neil/plaintext/DiffMatchPatchTest.java b/java/src/test/java/name/fraser/neil/plaintext/DiffMatchPatchTest.java new file mode 100644 index 00000000..3b595a1b --- /dev/null +++ b/java/src/test/java/name/fraser/neil/plaintext/DiffMatchPatchTest.java @@ -0,0 +1,1005 @@ +/* + * Diff Match and Patch -- Test harness Copyright 2018 The diff-match-patch Authors. + * https://github.com/google/diff-match-patch + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package name.fraser.neil.plaintext; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import name.fraser.neil.plaintext.diff_match_patch.Diff; +import name.fraser.neil.plaintext.diff_match_patch.LinesToCharsResult; +import name.fraser.neil.plaintext.diff_match_patch.Patch; + +public class DiffMatchPatchTest { + + private static diff_match_patch dmp = new diff_match_patch(); + private static diff_match_patch.Operation DELETE = diff_match_patch.Operation.DELETE; + private static diff_match_patch.Operation EQUAL = diff_match_patch.Operation.EQUAL; + private static diff_match_patch.Operation INSERT = diff_match_patch.Operation.INSERT; + + // DIFF TEST FUNCTIONS + + @Test + public void testDiffCommonPrefix() { + // Detect any common prefix. + assertEquals("diff_commonPrefix: Null case.", 0, dmp.diff_commonPrefix("abc", "xyz")); + + assertEquals("diff_commonPrefix: Non-null case.", 4, dmp.diff_commonPrefix("1234abcdef", "1234xyz")); + + assertEquals("diff_commonPrefix: Whole case.", 4, dmp.diff_commonPrefix("1234", "1234xyz")); + } + + @Test + public void testDiffCommonSuffix() { + // Detect any common suffix. + assertEquals("diff_commonSuffix: Null case.", 0, dmp.diff_commonSuffix("abc", "xyz")); + + assertEquals("diff_commonSuffix: Non-null case.", 4, dmp.diff_commonSuffix("abcdef1234", "xyz1234")); + + assertEquals("diff_commonSuffix: Whole case.", 4, dmp.diff_commonSuffix("1234", "xyz1234")); + } + + @Test + public void testDiffCommonOverlap() { + // Detect any suffix/prefix overlap. + assertEquals("diff_commonOverlap: Null case.", 0, dmp.diff_commonOverlap("", "abcd")); + + assertEquals("diff_commonOverlap: Whole case.", 3, dmp.diff_commonOverlap("abc", "abcd")); + + assertEquals("diff_commonOverlap: No overlap.", 0, dmp.diff_commonOverlap("123456", "abcd")); + + assertEquals("diff_commonOverlap: Overlap.", 3, dmp.diff_commonOverlap("123456xxx", "xxxabcd")); + + // Some overly clever languages (C#) may treat ligatures as equal to their + // component letters. E.g. U+FB01 == 'fi' + assertEquals("diff_commonOverlap: Unicode.", 0, dmp.diff_commonOverlap("fi", "\ufb01i")); + } + + @Test + public void testDiffHalfmatch() { + // Detect a halfmatch. + dmp.Diff_Timeout = 1; + assertNull("diff_halfMatch: No match #1.", dmp.diff_halfMatch("1234567890", "abcdef")); + + assertNull("diff_halfMatch: No match #2.", dmp.diff_halfMatch("12345", "23")); + + assertArrayEquals("diff_halfMatch: Single Match #1.", new String[] { "12", "90", "a", "z", "345678" }, + dmp.diff_halfMatch("1234567890", "a345678z")); + + assertArrayEquals("diff_halfMatch: Single Match #2.", new String[] { "a", "z", "12", "90", "345678" }, + dmp.diff_halfMatch("a345678z", "1234567890")); + + assertArrayEquals("diff_halfMatch: Single Match #3.", new String[] { "abc", "z", "1234", "0", "56789" }, + dmp.diff_halfMatch("abc56789z", "1234567890")); + + assertArrayEquals("diff_halfMatch: Single Match #4.", new String[] { "a", "xyz", "1", "7890", "23456" }, + dmp.diff_halfMatch("a23456xyz", "1234567890")); + + assertArrayEquals("diff_halfMatch: Multiple Matches #1.", new String[] { "12123", "123121", "a", "z", "1234123451234" }, + dmp.diff_halfMatch("121231234123451234123121", "a1234123451234z")); + + assertArrayEquals("diff_halfMatch: Multiple Matches #2.", new String[] { "", "-=-=-=-=-=", "x", "", "x-=-=-=-=-=-=-=" }, + dmp.diff_halfMatch("x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-=")); + + assertArrayEquals("diff_halfMatch: Multiple Matches #3.", new String[] { "-=-=-=-=-=", "", "", "y", "-=-=-=-=-=-=-=y" }, + dmp.diff_halfMatch("-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy")); + + // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy + assertArrayEquals("diff_halfMatch: Non-optimal halfmatch.", new String[] { "qHillo", "w", "x", "Hulloy", "HelloHe" }, + dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy")); + + dmp.Diff_Timeout = 0; + assertNull("diff_halfMatch: Optimal no halfmatch.", dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy")); + } + + @Test + public void testDiffLinesToChars() { + // Convert lines down to characters. + ArrayList tmpVector = new ArrayList(); + tmpVector.add(""); + tmpVector.add("alpha\n"); + tmpVector.add("beta\n"); + assertLinesToCharsResultEquals("diff_linesToChars: Shared lines.", + new LinesToCharsResult("\u0001\u0002\u0001", "\u0002\u0001\u0002", tmpVector), + dmp.diff_linesToChars("alpha\nbeta\nalpha\n", "beta\nalpha\nbeta\n")); + + tmpVector.clear(); + tmpVector.add(""); + tmpVector.add("alpha\r\n"); + tmpVector.add("beta\r\n"); + tmpVector.add("\r\n"); + assertLinesToCharsResultEquals("diff_linesToChars: Empty string and blank lines.", + new LinesToCharsResult("", "\u0001\u0002\u0003\u0003", tmpVector), dmp.diff_linesToChars("", "alpha\r\nbeta\r\n\r\n\r\n")); + + tmpVector.clear(); + tmpVector.add(""); + tmpVector.add("a"); + tmpVector.add("b"); + assertLinesToCharsResultEquals("diff_linesToChars: No linebreaks.", new LinesToCharsResult("\u0001", "\u0002", tmpVector), + dmp.diff_linesToChars("a", "b")); + + // More than 256 to reveal any 8-bit limitations. + int n = 300; + tmpVector.clear(); + StringBuilder lineList = new StringBuilder(); + StringBuilder charList = new StringBuilder(); + for (int x = 1; x < n + 1; x++) { + tmpVector.add(x + "\n"); + lineList.append(x + "\n"); + charList.append(String.valueOf((char) x)); + } + assertEquals("Test initialization fail #1.", n, tmpVector.size()); + String lines = lineList.toString(); + String chars = charList.toString(); + assertEquals("Test initialization fail #2.", n, chars.length()); + tmpVector.add(0, ""); + assertLinesToCharsResultEquals("diff_linesToChars: More than 256.", new LinesToCharsResult(chars, "", tmpVector), + dmp.diff_linesToChars(lines, "")); + } + + @Test + public void testDiffCharsToLines() { + // First check that Diff equality works. + assertTrue("diff_charsToLines: Equality #1.", new Diff(EQUAL, "a").equals(new Diff(EQUAL, "a"))); + + assertEquals("diff_charsToLines: Equality #2.", new Diff(EQUAL, "a"), new Diff(EQUAL, "a")); + + // Convert chars up to lines. + LinkedList diffs = diffList(new Diff(EQUAL, "\u0001\u0002\u0001"), new Diff(INSERT, "\u0002\u0001\u0002")); + ArrayList tmpVector = new ArrayList(); + tmpVector.add(""); + tmpVector.add("alpha\n"); + tmpVector.add("beta\n"); + dmp.diff_charsToLines(diffs, tmpVector); + assertEquals("diff_charsToLines: Shared lines.", diffList(new Diff(EQUAL, "alpha\nbeta\nalpha\n"), new Diff(INSERT, "beta\nalpha\nbeta\n")), + diffs); + + // More than 256 to reveal any 8-bit limitations. + int n = 300; + tmpVector.clear(); + StringBuilder lineList = new StringBuilder(); + StringBuilder charList = new StringBuilder(); + for (int x = 1; x < n + 1; x++) { + tmpVector.add(x + "\n"); + lineList.append(x + "\n"); + charList.append(String.valueOf((char) x)); + } + assertEquals("Test initialization fail #3.", n, tmpVector.size()); + String lines = lineList.toString(); + String chars = charList.toString(); + assertEquals("Test initialization fail #4.", n, chars.length()); + tmpVector.add(0, ""); + diffs = diffList(new Diff(DELETE, chars)); + dmp.diff_charsToLines(diffs, tmpVector); + assertEquals("diff_charsToLines: More than 256.", diffList(new Diff(DELETE, lines)), diffs); + } + + @Test + public void testDiffCleanupMerge() { + // Cleanup a messy diff. + LinkedList diffs = diffList(); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Null case.", diffList(), diffs); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(INSERT, "c")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: No change case.", diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(INSERT, "c")), diffs); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(EQUAL, "b"), new Diff(EQUAL, "c")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Merge equalities.", diffList(new Diff(EQUAL, "abc")), diffs); + + diffs = diffList(new Diff(DELETE, "a"), new Diff(DELETE, "b"), new Diff(DELETE, "c")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Merge deletions.", diffList(new Diff(DELETE, "abc")), diffs); + + diffs = diffList(new Diff(INSERT, "a"), new Diff(INSERT, "b"), new Diff(INSERT, "c")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Merge insertions.", diffList(new Diff(INSERT, "abc")), diffs); + + diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "b"), new Diff(DELETE, "c"), new Diff(INSERT, "d"), new Diff(EQUAL, "e"), + new Diff(EQUAL, "f")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Merge interweave.", diffList(new Diff(DELETE, "ac"), new Diff(INSERT, "bd"), new Diff(EQUAL, "ef")), diffs); + + diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "abc"), new Diff(DELETE, "dc")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Prefix and suffix detection.", + diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "d"), new Diff(INSERT, "b"), new Diff(EQUAL, "c")), diffs); + + diffs = diffList(new Diff(EQUAL, "x"), new Diff(DELETE, "a"), new Diff(INSERT, "abc"), new Diff(DELETE, "dc"), new Diff(EQUAL, "y")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Prefix and suffix detection with equalities.", + diffList(new Diff(EQUAL, "xa"), new Diff(DELETE, "d"), new Diff(INSERT, "b"), new Diff(EQUAL, "cy")), diffs); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(INSERT, "ba"), new Diff(EQUAL, "c")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Slide edit left.", diffList(new Diff(INSERT, "ab"), new Diff(EQUAL, "ac")), diffs); + + diffs = diffList(new Diff(EQUAL, "c"), new Diff(INSERT, "ab"), new Diff(EQUAL, "a")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Slide edit right.", diffList(new Diff(EQUAL, "ca"), new Diff(INSERT, "ba")), diffs); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(EQUAL, "c"), new Diff(DELETE, "ac"), new Diff(EQUAL, "x")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Slide edit left recursive.", diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "acx")), diffs); + + diffs = diffList(new Diff(EQUAL, "x"), new Diff(DELETE, "ca"), new Diff(EQUAL, "c"), new Diff(DELETE, "b"), new Diff(EQUAL, "a")); + dmp.diff_cleanupMerge(diffs); + assertEquals("diff_cleanupMerge: Slide edit right recursive.", diffList(new Diff(EQUAL, "xca"), new Diff(DELETE, "cba")), diffs); + } + + @Test + public void testDiffCleanupSemanticLossless() { + // Slide diffs to match logical boundaries. + LinkedList diffs = diffList(); + dmp.diff_cleanupSemanticLossless(diffs); + assertEquals("diff_cleanupSemanticLossless: Null case.", diffList(), diffs); + + diffs = diffList(new Diff(EQUAL, "AAA\r\n\r\nBBB"), new Diff(INSERT, "\r\nDDD\r\n\r\nBBB"), new Diff(EQUAL, "\r\nEEE")); + dmp.diff_cleanupSemanticLossless(diffs); + assertEquals("diff_cleanupSemanticLossless: Blank lines.", + diffList(new Diff(EQUAL, "AAA\r\n\r\n"), new Diff(INSERT, "BBB\r\nDDD\r\n\r\n"), new Diff(EQUAL, "BBB\r\nEEE")), diffs); + + diffs = diffList(new Diff(EQUAL, "AAA\r\nBBB"), new Diff(INSERT, " DDD\r\nBBB"), new Diff(EQUAL, " EEE")); + dmp.diff_cleanupSemanticLossless(diffs); + assertEquals("diff_cleanupSemanticLossless: Line boundaries.", + diffList(new Diff(EQUAL, "AAA\r\n"), new Diff(INSERT, "BBB DDD\r\n"), new Diff(EQUAL, "BBB EEE")), diffs); + + diffs = diffList(new Diff(EQUAL, "The c"), new Diff(INSERT, "ow and the c"), new Diff(EQUAL, "at.")); + dmp.diff_cleanupSemanticLossless(diffs); + assertEquals("diff_cleanupSemanticLossless: Word boundaries.", + diffList(new Diff(EQUAL, "The "), new Diff(INSERT, "cow and the "), new Diff(EQUAL, "cat.")), diffs); + + diffs = diffList(new Diff(EQUAL, "The-c"), new Diff(INSERT, "ow-and-the-c"), new Diff(EQUAL, "at.")); + dmp.diff_cleanupSemanticLossless(diffs); + assertEquals("diff_cleanupSemanticLossless: Alphanumeric boundaries.", + diffList(new Diff(EQUAL, "The-"), new Diff(INSERT, "cow-and-the-"), new Diff(EQUAL, "cat.")), diffs); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "a"), new Diff(EQUAL, "ax")); + dmp.diff_cleanupSemanticLossless(diffs); + assertEquals("diff_cleanupSemanticLossless: Hitting the start.", diffList(new Diff(DELETE, "a"), new Diff(EQUAL, "aax")), diffs); + + diffs = diffList(new Diff(EQUAL, "xa"), new Diff(DELETE, "a"), new Diff(EQUAL, "a")); + dmp.diff_cleanupSemanticLossless(diffs); + assertEquals("diff_cleanupSemanticLossless: Hitting the end.", diffList(new Diff(EQUAL, "xaa"), new Diff(DELETE, "a")), diffs); + + diffs = diffList(new Diff(EQUAL, "The xxx. The "), new Diff(INSERT, "zzz. The "), new Diff(EQUAL, "yyy.")); + dmp.diff_cleanupSemanticLossless(diffs); + assertEquals("diff_cleanupSemanticLossless: Sentence boundaries.", + diffList(new Diff(EQUAL, "The xxx."), new Diff(INSERT, " The zzz."), new Diff(EQUAL, " The yyy.")), diffs); + } + + @Test + public void testDiffCleanupSemantic() { + // Cleanup semantically trivial equalities. + LinkedList diffs = diffList(); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: Null case.", diffList(), diffs); + + diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "cd"), new Diff(EQUAL, "12"), new Diff(DELETE, "e")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: No elimination #1.", + diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "cd"), new Diff(EQUAL, "12"), new Diff(DELETE, "e")), diffs); + + diffs = diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "ABC"), new Diff(EQUAL, "1234"), new Diff(DELETE, "wxyz")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: No elimination #2.", + diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "ABC"), new Diff(EQUAL, "1234"), new Diff(DELETE, "wxyz")), diffs); + + diffs = diffList(new Diff(DELETE, "a"), new Diff(EQUAL, "b"), new Diff(DELETE, "c")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: Simple elimination.", diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "b")), diffs); + + diffs = diffList(new Diff(DELETE, "ab"), new Diff(EQUAL, "cd"), new Diff(DELETE, "e"), new Diff(EQUAL, "f"), new Diff(INSERT, "g")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: Backpass elimination.", diffList(new Diff(DELETE, "abcdef"), new Diff(INSERT, "cdfg")), diffs); + + diffs = diffList(new Diff(INSERT, "1"), new Diff(EQUAL, "A"), new Diff(DELETE, "B"), new Diff(INSERT, "2"), new Diff(EQUAL, "_"), + new Diff(INSERT, "1"), new Diff(EQUAL, "A"), new Diff(DELETE, "B"), new Diff(INSERT, "2")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: Multiple elimination.", diffList(new Diff(DELETE, "AB_AB"), new Diff(INSERT, "1A2_1A2")), diffs); + + diffs = diffList(new Diff(EQUAL, "The c"), new Diff(DELETE, "ow and the c"), new Diff(EQUAL, "at.")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: Word boundaries.", + diffList(new Diff(EQUAL, "The "), new Diff(DELETE, "cow and the "), new Diff(EQUAL, "cat.")), diffs); + + diffs = diffList(new Diff(DELETE, "abcxx"), new Diff(INSERT, "xxdef")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: No overlap elimination.", diffList(new Diff(DELETE, "abcxx"), new Diff(INSERT, "xxdef")), diffs); + + diffs = diffList(new Diff(DELETE, "abcxxx"), new Diff(INSERT, "xxxdef")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: Overlap elimination.", diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "xxx"), new Diff(INSERT, "def")), + diffs); + + diffs = diffList(new Diff(DELETE, "xxxabc"), new Diff(INSERT, "defxxx")); + dmp.diff_cleanupSemantic(diffs); + assertEquals("diff_cleanupSemantic: Reverse overlap elimination.", + diffList(new Diff(INSERT, "def"), new Diff(EQUAL, "xxx"), new Diff(DELETE, "abc")), diffs); + + diffs = diffList(new Diff(DELETE, "abcd1212"), new Diff(INSERT, "1212efghi"), new Diff(EQUAL, "----"), new Diff(DELETE, "A3"), + new Diff(INSERT, "3BC")); + dmp.diff_cleanupSemantic(diffs); + assertEquals( + "diff_cleanupSemantic: Two overlap eliminations.", diffList(new Diff(DELETE, "abcd"), new Diff(EQUAL, "1212"), + new Diff(INSERT, "efghi"), new Diff(EQUAL, "----"), new Diff(DELETE, "A"), new Diff(EQUAL, "3"), new Diff(INSERT, "BC")), + diffs); + } + + @Test + public void testDiffCleanupEfficiency() { + // Cleanup operationally trivial equalities. + dmp.Diff_EditCost = 4; + LinkedList diffs = diffList(); + dmp.diff_cleanupEfficiency(diffs); + assertEquals("diff_cleanupEfficiency: Null case.", diffList(), diffs); + + diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); + dmp.diff_cleanupEfficiency(diffs); + assertEquals("diff_cleanupEfficiency: No elimination.", + diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")), + diffs); + + diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "xyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); + dmp.diff_cleanupEfficiency(diffs); + assertEquals("diff_cleanupEfficiency: Four-edit elimination.", diffList(new Diff(DELETE, "abxyzcd"), new Diff(INSERT, "12xyz34")), diffs); + + diffs = diffList(new Diff(INSERT, "12"), new Diff(EQUAL, "x"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); + dmp.diff_cleanupEfficiency(diffs); + assertEquals("diff_cleanupEfficiency: Three-edit elimination.", diffList(new Diff(DELETE, "xcd"), new Diff(INSERT, "12x34")), diffs); + + diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "xy"), new Diff(INSERT, "34"), new Diff(EQUAL, "z"), + new Diff(DELETE, "cd"), new Diff(INSERT, "56")); + dmp.diff_cleanupEfficiency(diffs); + assertEquals("diff_cleanupEfficiency: Backpass elimination.", diffList(new Diff(DELETE, "abxyzcd"), new Diff(INSERT, "12xy34z56")), diffs); + + dmp.Diff_EditCost = 5; + diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); + dmp.diff_cleanupEfficiency(diffs); + assertEquals("diff_cleanupEfficiency: High cost elimination.", diffList(new Diff(DELETE, "abwxyzcd"), new Diff(INSERT, "12wxyz34")), diffs); + dmp.Diff_EditCost = 4; + } + + @Test + public void testDiffPrettyHtml() { + // Pretty print. + LinkedList diffs = diffList(new Diff(EQUAL, "a\n"), new Diff(DELETE, "b"), new Diff(INSERT, "c&d")); + assertEquals("diff_prettyHtml:", + "
<B>b</B>c&d", + dmp.diff_prettyHtml(diffs)); + } + + @Test + public void testDiffText() { + // Compute the source and destination texts. + LinkedList diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), + new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, " lazy")); + assertEquals("diff_text1:", "jumps over the lazy", dmp.diff_text1(diffs)); + assertEquals("diff_text2:", "jumped over a lazy", dmp.diff_text2(diffs)); + } + + @Test + public void testDiffDelta() { + // Convert a diff into delta string. + LinkedList diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), + new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, " lazy"), new Diff(INSERT, "old dog")); + String text1 = dmp.diff_text1(diffs); + assertEquals("diff_text1: Base text.", "jumps over the lazy", text1); + + String delta = dmp.diff_toDelta(diffs); + assertEquals("diff_toDelta:", "=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog", delta); + + // Convert delta string into a diff. + assertEquals("diff_fromDelta: Normal.", diffs, dmp.diff_fromDelta(text1, delta)); + + // Generates error (19 < 20). + try { + dmp.diff_fromDelta(text1 + "x", delta); + fail("diff_fromDelta: Too long."); + } catch (IllegalArgumentException ex) { + // Exception expected. + } + + // Generates error (19 > 18). + try { + dmp.diff_fromDelta(text1.substring(1), delta); + fail("diff_fromDelta: Too short."); + } catch (IllegalArgumentException ex) { + // Exception expected. + } + + // Generates error (%c3%xy invalid Unicode). + try { + dmp.diff_fromDelta("", "+%c3%xy"); + fail("diff_fromDelta: Invalid character."); + } catch (IllegalArgumentException ex) { + // Exception expected. + } + + // Test deltas with special characters. + diffs = diffList(new Diff(EQUAL, "\u0680 \000 \t %"), new Diff(DELETE, "\u0681 \001 \n ^"), new Diff(INSERT, "\u0682 \002 \\ |")); + text1 = dmp.diff_text1(diffs); + assertEquals("diff_text1: Unicode text.", "\u0680 \000 \t %\u0681 \001 \n ^", text1); + + delta = dmp.diff_toDelta(diffs); + assertEquals("diff_toDelta: Unicode.", "=7\t-7\t+%DA%82 %02 %5C %7C", delta); + + assertEquals("diff_fromDelta: Unicode.", diffs, dmp.diff_fromDelta(text1, delta)); + + // Verify pool of unchanged characters. + diffs = diffList(new Diff(INSERT, "A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # ")); + String text2 = dmp.diff_text2(diffs); + assertEquals("diff_text2: Unchanged characters.", "A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ", text2); + + delta = dmp.diff_toDelta(diffs); + assertEquals("diff_toDelta: Unchanged characters.", "+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ", delta); + + // Convert delta string into a diff. + assertEquals("diff_fromDelta: Unchanged characters.", diffs, dmp.diff_fromDelta("", delta)); + } + + @Test + public void testDiffXIndex() { + // Translate a location in text1 to text2. + LinkedList diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz")); + assertEquals("diff_xIndex: Translation on equality.", 5, dmp.diff_xIndex(diffs, 2)); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "1234"), new Diff(EQUAL, "xyz")); + assertEquals("diff_xIndex: Translation on deletion.", 1, dmp.diff_xIndex(diffs, 3)); + } + + @Test + public void testDiffLevenshtein() { + LinkedList diffs = diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz")); + assertEquals("diff_levenshtein: Levenshtein with trailing equality.", 4, dmp.diff_levenshtein(diffs)); + + diffs = diffList(new Diff(EQUAL, "xyz"), new Diff(DELETE, "abc"), new Diff(INSERT, "1234")); + assertEquals("diff_levenshtein: Levenshtein with leading equality.", 4, dmp.diff_levenshtein(diffs)); + + diffs = diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "xyz"), new Diff(INSERT, "1234")); + assertEquals("diff_levenshtein: Levenshtein with middle equality.", 7, dmp.diff_levenshtein(diffs)); + } + + @Test + public void testDiffBisect() { + // Normal. + String a = "cat"; + String b = "map"; + // 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. + LinkedList diffs = diffList(new Diff(DELETE, "c"), new Diff(INSERT, "m"), new Diff(EQUAL, "a"), new Diff(DELETE, "t"), + new Diff(INSERT, "p")); + assertEquals("diff_bisect: Normal.", diffs, dmp.diff_bisect(a, b, Long.MAX_VALUE)); + + // Timeout. + diffs = diffList(new Diff(DELETE, "cat"), new Diff(INSERT, "map")); + assertEquals("diff_bisect: Timeout.", diffs, dmp.diff_bisect(a, b, 0)); + } + + @Test + public void testDiffMain() { + // Perform a trivial diff. + LinkedList diffs = diffList(); + assertEquals("diff_main: Null case.", diffs, dmp.diff_main("", "", false)); + + diffs = diffList(new Diff(EQUAL, "abc")); + assertEquals("diff_main: Equality.", diffs, dmp.diff_main("abc", "abc", false)); + + diffs = diffList(new Diff(EQUAL, "ab"), new Diff(INSERT, "123"), new Diff(EQUAL, "c")); + assertEquals("diff_main: Simple insertion.", diffs, dmp.diff_main("abc", "ab123c", false)); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "123"), new Diff(EQUAL, "bc")); + assertEquals("diff_main: Simple deletion.", diffs, dmp.diff_main("a123bc", "abc", false)); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(INSERT, "123"), new Diff(EQUAL, "b"), new Diff(INSERT, "456"), new Diff(EQUAL, "c")); + assertEquals("diff_main: Two insertions.", diffs, dmp.diff_main("abc", "a123b456c", false)); + + diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "123"), new Diff(EQUAL, "b"), new Diff(DELETE, "456"), new Diff(EQUAL, "c")); + assertEquals("diff_main: Two deletions.", diffs, dmp.diff_main("a123b456c", "abc", false)); + + // Perform a real diff. + // Switch off the timeout. + dmp.Diff_Timeout = 0; + diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "b")); + assertEquals("diff_main: Simple case #1.", diffs, dmp.diff_main("a", "b", false)); + + diffs = diffList(new Diff(DELETE, "Apple"), new Diff(INSERT, "Banana"), new Diff(EQUAL, "s are a"), new Diff(INSERT, "lso"), + new Diff(EQUAL, " fruit.")); + assertEquals("diff_main: Simple case #2.", diffs, dmp.diff_main("Apples are a fruit.", "Bananas are also fruit.", false)); + + diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "\u0680"), new Diff(EQUAL, "x"), new Diff(DELETE, "\t"), new Diff(INSERT, "\000")); + assertEquals("diff_main: Simple case #3.", diffs, dmp.diff_main("ax\t", "\u0680x\000", false)); + + diffs = diffList(new Diff(DELETE, "1"), new Diff(EQUAL, "a"), new Diff(DELETE, "y"), new Diff(EQUAL, "b"), new Diff(DELETE, "2"), + new Diff(INSERT, "xab")); + assertEquals("diff_main: Overlap #1.", diffs, dmp.diff_main("1ayb2", "abxab", false)); + + diffs = diffList(new Diff(INSERT, "xaxcx"), new Diff(EQUAL, "abc"), new Diff(DELETE, "y")); + assertEquals("diff_main: Overlap #2.", diffs, dmp.diff_main("abcy", "xaxcxabc", false)); + + diffs = diffList(new Diff(DELETE, "ABCD"), new Diff(EQUAL, "a"), new Diff(DELETE, "="), new Diff(INSERT, "-"), new Diff(EQUAL, "bcd"), + new Diff(DELETE, "="), new Diff(INSERT, "-"), new Diff(EQUAL, "efghijklmnopqrs"), new Diff(DELETE, "EFGHIJKLMNOefg")); + assertEquals("diff_main: Overlap #3.", diffs, dmp.diff_main("ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg", "a-bcd-efghijklmnopqrs", false)); + + diffs = diffList(new Diff(INSERT, " "), new Diff(EQUAL, "a"), new Diff(INSERT, "nd"), new Diff(EQUAL, " [[Pennsylvania]]"), + new Diff(DELETE, " and [[New")); + assertEquals("diff_main: Large equality.", diffs, dmp.diff_main("a [[Pennsylvania]] and [[New", " and [[Pennsylvania]]", false)); + + dmp.Diff_Timeout = 0.1f; // 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 x = 0; x < 10; x++) { + a = a + a; + b = b + b; + } + long startTime = System.currentTimeMillis(); + dmp.diff_main(a, b); + long endTime = System.currentTimeMillis(); + // Test that we took at least the timeout period. + assertTrue("diff_main: Timeout min.", dmp.Diff_Timeout * 1000 <= endTime - startTime); + // Test that we didn't take forever (be forgiving). + // Theoretically this test could fail very occasionally if the + // OS task swaps or locks up for a second at the wrong moment. + assertTrue("diff_main: Timeout max.", dmp.Diff_Timeout * 1000 * 2 > endTime - startTime); + dmp.Diff_Timeout = 0; + + // Test the linemode speedup. + // Must be long to pass the 100 char cutoff. + a = "1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n"; + b = "abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n"; + assertEquals("diff_main: Simple line-mode.", dmp.diff_main(a, b, true), dmp.diff_main(a, b, false)); + + a = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; + b = "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"; + assertEquals("diff_main: Single line-mode.", dmp.diff_main(a, b, true), dmp.diff_main(a, b, false)); + + a = "1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n"; + b = "abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n"; + String[] texts_linemode = diff_rebuildtexts(dmp.diff_main(a, b, true)); + String[] texts_textmode = diff_rebuildtexts(dmp.diff_main(a, b, false)); + assertArrayEquals("diff_main: Overlap line-mode.", texts_textmode, texts_linemode); + + // Test null inputs. + try { + dmp.diff_main(null, null); + fail("diff_main: Null inputs."); + } catch (IllegalArgumentException ex) { + // Error expected. + } + } + + // MATCH TEST FUNCTIONS + + @Test + public void testMatchAlphabet() { + // Initialise the bitmasks for Bitap. + Map bitmask; + bitmask = new HashMap(); + bitmask.put('a', 4); + bitmask.put('b', 2); + bitmask.put('c', 1); + assertEquals("match_alphabet: Unique.", bitmask, dmp.match_alphabet("abc")); + + bitmask = new HashMap(); + bitmask.put('a', 37); + bitmask.put('b', 18); + bitmask.put('c', 8); + assertEquals("match_alphabet: Duplicates.", bitmask, dmp.match_alphabet("abcaba")); + } + + @Test + public void testMatchBitap() { + // Bitap algorithm. + dmp.Match_Distance = 100; + dmp.Match_Threshold = 0.5f; + assertEquals("match_bitap: Exact match #1.", 5, dmp.match_bitap("abcdefghijk", "fgh", 5)); + + assertEquals("match_bitap: Exact match #2.", 5, dmp.match_bitap("abcdefghijk", "fgh", 0)); + + assertEquals("match_bitap: Fuzzy match #1.", 4, dmp.match_bitap("abcdefghijk", "efxhi", 0)); + + assertEquals("match_bitap: Fuzzy match #2.", 2, dmp.match_bitap("abcdefghijk", "cdefxyhijk", 5)); + + assertEquals("match_bitap: Fuzzy match #3.", -1, dmp.match_bitap("abcdefghijk", "bxy", 1)); + + assertEquals("match_bitap: Overflow.", 2, dmp.match_bitap("123456789xx0", "3456789x0", 2)); + + assertEquals("match_bitap: Before start match.", 0, dmp.match_bitap("abcdef", "xxabc", 4)); + + assertEquals("match_bitap: Beyond end match.", 3, dmp.match_bitap("abcdef", "defyy", 4)); + + assertEquals("match_bitap: Oversized pattern.", 0, dmp.match_bitap("abcdef", "xabcdefy", 0)); + + dmp.Match_Threshold = 0.4f; + assertEquals("match_bitap: Threshold #1.", 4, dmp.match_bitap("abcdefghijk", "efxyhi", 1)); + + dmp.Match_Threshold = 0.3f; + assertEquals("match_bitap: Threshold #2.", -1, dmp.match_bitap("abcdefghijk", "efxyhi", 1)); + + dmp.Match_Threshold = 0.0f; + assertEquals("match_bitap: Threshold #3.", 1, dmp.match_bitap("abcdefghijk", "bcdef", 1)); + + dmp.Match_Threshold = 0.5f; + assertEquals("match_bitap: Multiple select #1.", 0, dmp.match_bitap("abcdexyzabcde", "abccde", 3)); + + assertEquals("match_bitap: Multiple select #2.", 8, dmp.match_bitap("abcdexyzabcde", "abccde", 5)); + + dmp.Match_Distance = 10; // Strict location. + assertEquals("match_bitap: Distance test #1.", -1, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24)); + + assertEquals("match_bitap: Distance test #2.", 0, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdxxefg", 1)); + + dmp.Match_Distance = 1000; // Loose location. + assertEquals("match_bitap: Distance test #3.", 0, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24)); + } + + @Test + public void testMatchMain() { + // Full match. + assertEquals("match_main: Equality.", 0, dmp.match_main("abcdef", "abcdef", 1000)); + + assertEquals("match_main: Null text.", -1, dmp.match_main("", "abcdef", 1)); + + assertEquals("match_main: Null pattern.", 3, dmp.match_main("abcdef", "", 3)); + + assertEquals("match_main: Exact match.", 3, dmp.match_main("abcdef", "de", 3)); + + assertEquals("match_main: Beyond end match.", 3, dmp.match_main("abcdef", "defy", 4)); + + assertEquals("match_main: Oversized pattern.", 0, dmp.match_main("abcdef", "abcdefy", 0)); + + dmp.Match_Threshold = 0.7f; + assertEquals("match_main: Complex match.", 4, dmp.match_main("I am the very model of a modern major general.", " that berry ", 5)); + dmp.Match_Threshold = 0.5f; + + // Test null inputs. + try { + dmp.match_main(null, null, 0); + fail("match_main: Null inputs."); + } catch (IllegalArgumentException ex) { + // Error expected. + } + } + + // PATCH TEST FUNCTIONS + + @Test + public void testPatchObj() { + // Patch Object. + Patch p = new Patch(); + p.start1 = 20; + p.start2 = 21; + p.length1 = 18; + p.length2 = 17; + p.diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), new Diff(DELETE, "the"), + new Diff(INSERT, "a"), new Diff(EQUAL, "\nlaz")); + String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n"; + assertEquals("Patch: toString.", strp, p.toString()); + } + + @Test + public void testPatchFromText() { + assertTrue("patch_fromText: #0.", dmp.patch_fromText("").isEmpty()); + + String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n"; + assertEquals("patch_fromText: #1.", strp, dmp.patch_fromText(strp).get(0).toString()); + + assertEquals("patch_fromText: #2.", "@@ -1 +1 @@\n-a\n+b\n", dmp.patch_fromText("@@ -1 +1 @@\n-a\n+b\n").get(0).toString()); + + assertEquals("patch_fromText: #3.", "@@ -1,3 +0,0 @@\n-abc\n", dmp.patch_fromText("@@ -1,3 +0,0 @@\n-abc\n").get(0).toString()); + + assertEquals("patch_fromText: #4.", "@@ -0,0 +1,3 @@\n+abc\n", dmp.patch_fromText("@@ -0,0 +1,3 @@\n+abc\n").get(0).toString()); + + // Generates error. + try { + dmp.patch_fromText("Bad\nPatch\n"); + fail("patch_fromText: #5."); + } catch (IllegalArgumentException ex) { + // Exception expected. + } + } + + @Test + public void testPatchToText() { + String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n"; + List patches; + patches = dmp.patch_fromText(strp); + assertEquals("patch_toText: Single.", strp, dmp.patch_toText(patches)); + + strp = "@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n"; + patches = dmp.patch_fromText(strp); + assertEquals("patch_toText: Dual.", strp, dmp.patch_toText(patches)); + } + + @Test + public void testPatchAddContext() { + dmp.Patch_Margin = 4; + Patch p; + p = dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n").get(0); + dmp.patch_addContext(p, "The quick brown fox jumps over the lazy dog."); + assertEquals("patch_addContext: Simple case.", "@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n", p.toString()); + + p = dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n").get(0); + dmp.patch_addContext(p, "The quick brown fox jumps."); + assertEquals("patch_addContext: Not enough trailing context.", "@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n", p.toString()); + + p = dmp.patch_fromText("@@ -3 +3,2 @@\n-e\n+at\n").get(0); + dmp.patch_addContext(p, "The quick brown fox jumps."); + assertEquals("patch_addContext: Not enough leading context.", "@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n", p.toString()); + + p = dmp.patch_fromText("@@ -3 +3,2 @@\n-e\n+at\n").get(0); + dmp.patch_addContext(p, "The quick brown fox jumps. The quick brown fox crashes."); + assertEquals("patch_addContext: Ambiguity.", "@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n", p.toString()); + } + + @SuppressWarnings("deprecation") + @Test + public void testPatchMake() { + LinkedList patches; + patches = dmp.patch_make("", ""); + assertEquals("patch_make: Null case.", "", dmp.patch_toText(patches)); + + 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"; + // The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context. + patches = dmp.patch_make(text2, text1); + assertEquals("patch_make: Text2+Text1 inputs.", expectedPatch, dmp.patch_toText(patches)); + + 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); + assertEquals("patch_make: Text1+Text2 inputs.", expectedPatch, dmp.patch_toText(patches)); + + LinkedList diffs = dmp.diff_main(text1, text2, false); + patches = dmp.patch_make(diffs); + assertEquals("patch_make: Diff input.", expectedPatch, dmp.patch_toText(patches)); + + patches = dmp.patch_make(text1, diffs); + assertEquals("patch_make: Text1+Diff inputs.", expectedPatch, dmp.patch_toText(patches)); + + patches = dmp.patch_make(text1, text2, diffs); + assertEquals("patch_make: Text1+Text2+Diff inputs (deprecated).", expectedPatch, dmp.patch_toText(patches)); + + patches = dmp.patch_make("`1234567890-=[]\\;',./", "~!@#$%^&*()_+{}|:\"<>?"); + assertEquals("patch_toText: Character encoding.", + "@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n", dmp.patch_toText(patches)); + + diffs = diffList(new Diff(DELETE, "`1234567890-=[]\\;',./"), new Diff(INSERT, "~!@#$%^&*()_+{}|:\"<>?")); + assertEquals("patch_fromText: Character decoding.", diffs, + dmp.patch_fromText("@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n").get(0).diffs); + + text1 = ""; + for (int x = 0; x < 100; x++) { + text1 += "abcdef"; + } + text2 = text1 + "123"; + expectedPatch = "@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n"; + patches = dmp.patch_make(text1, text2); + assertEquals("patch_make: Long string with repeats.", expectedPatch, dmp.patch_toText(patches)); + + // Test null inputs. + try { + dmp.patch_make(null); + fail("patch_make: Null inputs."); + } catch (IllegalArgumentException ex) { + // Error expected. + } + } + + @Test + public void testPatchSplitMax() { + // Assumes that Match_MaxBits is 32. + LinkedList patches; + patches = dmp.patch_make("abcdefghijklmnopqrstuvwxyz01234567890", "XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0"); + dmp.patch_splitMax(patches); + assertEquals("patch_splitMax: #1.", + "@@ -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)); + + patches = dmp.patch_make("abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz", "abcdefuvwxyz"); + String oldToText = dmp.patch_toText(patches); + dmp.patch_splitMax(patches); + assertEquals("patch_splitMax: #2.", oldToText, dmp.patch_toText(patches)); + + patches = dmp.patch_make("1234567890123456789012345678901234567890123456789012345678901234567890", "abc"); + dmp.patch_splitMax(patches); + assertEquals("patch_splitMax: #3.", + "@@ -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)); + + 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); + assertEquals("patch_splitMax: #4.", + "@@ -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)); + } + + @Test + public void testPatchAddPadding() { + LinkedList patches; + patches = dmp.patch_make("", "test"); + assertEquals("patch_addPadding: Both edges full.", "@@ -0,0 +1,4 @@\n+test\n", dmp.patch_toText(patches)); + dmp.patch_addPadding(patches); + assertEquals("patch_addPadding: Both edges full.", "@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n", dmp.patch_toText(patches)); + + patches = dmp.patch_make("XY", "XtestY"); + assertEquals("patch_addPadding: Both edges partial.", "@@ -1,2 +1,6 @@\n X\n+test\n Y\n", dmp.patch_toText(patches)); + dmp.patch_addPadding(patches); + assertEquals("patch_addPadding: Both edges partial.", "@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n", dmp.patch_toText(patches)); + + patches = dmp.patch_make("XXXXYYYY", "XXXXtestYYYY"); + assertEquals("patch_addPadding: Both edges none.", "@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n", dmp.patch_toText(patches)); + dmp.patch_addPadding(patches); + assertEquals("patch_addPadding: Both edges none.", "@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n", dmp.patch_toText(patches)); + } + + @Test + public void testPatchApply() { + dmp.Match_Distance = 1000; + dmp.Match_Threshold = 0.5f; + dmp.Patch_DeleteThreshold = 0.5f; + LinkedList patches; + patches = dmp.patch_make("", ""); + Object[] results = dmp.patch_apply(patches, "Hello world."); + boolean[] boolArray = (boolean[]) results[1]; + String resultStr = results[0] + "\t" + boolArray.length; + assertEquals("patch_apply: Null case.", "Hello world.\t0", resultStr); + + 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 = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; + assertEquals("patch_apply: Exact match.", "That quick brown fox jumped over a lazy dog.\ttrue\ttrue", resultStr); + + results = dmp.patch_apply(patches, "The quick red rabbit jumps over the tired tiger."); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; + assertEquals("patch_apply: Partial match.", "That quick red rabbit jumped over a tired tiger.\ttrue\ttrue", resultStr); + + results = dmp.patch_apply(patches, "I am the very model of a modern major general."); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; + assertEquals("patch_apply: Failed match.", "I am the very model of a modern major general.\tfalse\tfalse", resultStr); + + patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); + results = dmp.patch_apply(patches, "x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y"); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; + assertEquals("patch_apply: Big delete, small change.", "xabcy\ttrue\ttrue", resultStr); + + patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); + results = dmp.patch_apply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y"); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; + assertEquals("patch_apply: Big delete, big change 1.", + "xabc12345678901234567890---------------++++++++++---------------12345678901234567890y\tfalse\ttrue", resultStr); + + dmp.Patch_DeleteThreshold = 0.6f; + patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); + results = dmp.patch_apply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y"); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; + assertEquals("patch_apply: Big delete, big change 2.", "xabcy\ttrue\ttrue", resultStr); + dmp.Patch_DeleteThreshold = 0.5f; + + // Compensate for failed patch. + dmp.Match_Threshold = 0.0f; + dmp.Match_Distance = 0; + patches = dmp.patch_make("abcdefghijklmnopqrstuvwxyz--------------------1234567890", + "abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890"); + results = dmp.patch_apply(patches, "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890"); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; + assertEquals("patch_apply: Compensate for failed patch.", "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890\tfalse\ttrue", + resultStr); + dmp.Match_Threshold = 0.5f; + dmp.Match_Distance = 1000; + + patches = dmp.patch_make("", "test"); + String patchStr = dmp.patch_toText(patches); + dmp.patch_apply(patches, ""); + assertEquals("patch_apply: No side effects.", patchStr, dmp.patch_toText(patches)); + + patches = dmp.patch_make("The quick brown fox jumps over the lazy dog.", "Woof"); + patchStr = dmp.patch_toText(patches); + dmp.patch_apply(patches, "The quick brown fox jumps over the lazy dog."); + assertEquals("patch_apply: No side effects with major delete.", patchStr, dmp.patch_toText(patches)); + + patches = dmp.patch_make("", "test"); + results = dmp.patch_apply(patches, ""); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0]; + assertEquals("patch_apply: Edge exact match.", "test\ttrue", resultStr); + + patches = dmp.patch_make("XY", "XtestY"); + results = dmp.patch_apply(patches, "XY"); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0]; + assertEquals("patch_apply: Near edge exact match.", "XtestY\ttrue", resultStr); + + patches = dmp.patch_make("y", "y123"); + results = dmp.patch_apply(patches, "x"); + boolArray = (boolean[]) results[1]; + resultStr = results[0] + "\t" + boolArray[0]; + assertEquals("patch_apply: Edge partial match.", "x123\ttrue", resultStr); + } + + private static void assertEquals(String error_msg, Object a, Object b) { + if (!a.toString().equals(b.toString())) { + throw new Error("assertEquals fail:\n Expected: " + a + "\n Actual: " + b + "\n" + error_msg); + } + } + + private static void assertTrue(String error_msg, boolean a) { + if (!a) { + throw new Error("assertTrue fail: " + error_msg); + } + } + + private static void assertNull(String error_msg, Object n) { + if (n != null) { + throw new Error("assertNull fail: " + error_msg); + } + } + + private static void fail(String error_msg) { + throw new Error("Fail: " + error_msg); + } + + private static void assertArrayEquals(String error_msg, Object[] a, Object[] b) { + List list_a = Arrays.asList(a); + List list_b = Arrays.asList(b); + assertEquals(error_msg, list_a, list_b); + } + + private static void assertLinesToCharsResultEquals(String error_msg, LinesToCharsResult a, LinesToCharsResult b) { + assertEquals(error_msg, a.chars1, b.chars1); + assertEquals(error_msg, a.chars2, b.chars2); + assertEquals(error_msg, a.lineArray, b.lineArray); + } + + // Construct the two texts which made up the diff originally. + private static String[] diff_rebuildtexts(LinkedList diffs) { + String[] text = { "", "" }; + for (Diff myDiff : diffs) { + if (myDiff.operation != diff_match_patch.Operation.INSERT) { + text[0] += myDiff.text; + } + if (myDiff.operation != diff_match_patch.Operation.DELETE) { + text[1] += myDiff.text; + } + } + return text; + } + + // Private function for quickly building lists of diffs. + private static LinkedList diffList(Diff... diffs) { + LinkedList myDiffList = new LinkedList(); + for (Diff myDiff : diffs) { + myDiffList.add(myDiff); + } + return myDiffList; + } +} diff --git a/java/src/test/java/name/fraser/neil/plaintext/SpeedTest.java b/java/src/test/java/name/fraser/neil/plaintext/SpeedTest.java new file mode 100644 index 00000000..24bc722f --- /dev/null +++ b/java/src/test/java/name/fraser/neil/plaintext/SpeedTest.java @@ -0,0 +1,57 @@ +// Copyright 2010 Google Inc. All Rights Reserved. + +/** + * Diff Speed Test + * + * @author fraser@google.com (Neil Fraser) + */ + +package name.fraser.neil.plaintext; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +import org.junit.Test; + +public class SpeedTest { + + @Test + public void testSpeed() throws Exception { + String text1 = readFile("src/test/java/name/fraser/neil/plaintext/Speedtest1.txt"); + String text2 = readFile("src/test/java/name/fraser/neil/plaintext/Speedtest2.txt"); + + diff_match_patch dmp = new diff_match_patch(); + dmp.Diff_Timeout = 0; + + // Execute one reverse diff as a warmup. + dmp.diff_main(text2, text1, false); + System.gc(); + + long start_time = System.currentTimeMillis(); + dmp.diff_main(text1, text2, false); + long end_time = System.currentTimeMillis(); + System.out.printf("Elapsed time: %f\n", ((end_time - start_time) / 1000.0)); + } + + private static String readFile(String filename) { + // Read a file from disk and return the text contents. + StringBuffer strbuf = new StringBuffer(); + try { + FileReader input = new FileReader(filename); + BufferedReader bufRead = new BufferedReader(input); + String line = bufRead.readLine(); + while (line != null) { + strbuf.append(line); + strbuf.append('\n'); + line = bufRead.readLine(); + } + + bufRead.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + return strbuf.toString(); + } +} diff --git a/java/src/test/java/name/fraser/neil/plaintext/Speedtest.java b/java/src/test/java/name/fraser/neil/plaintext/Speedtest.java deleted file mode 100644 index 5c0ef034..00000000 --- a/java/src/test/java/name/fraser/neil/plaintext/Speedtest.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2010 Google Inc. All Rights Reserved. - -/** - * Diff Speed Test - * - * Compile from diff-match-patch/java with: - * javac -d classes src/name/fraser/neil/plaintext/diff_match_patch.java tests/name/fraser/neil/plaintext/Speedtest.java - * Execute with: - * java -classpath classes name/fraser/neil/plaintext/Speedtest - * - * @author fraser@google.com (Neil Fraser) - */ - -package name.fraser.neil.plaintext; - -import name.fraser.neil.plaintext.diff_match_patch; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; - -public class Speedtest { - - public static void main(String args[]) { - String text1 = readFile("tests/name/fraser/neil/plaintext/Speedtest1.txt"); - String text2 = readFile("tests/name/fraser/neil/plaintext/Speedtest2.txt"); - - diff_match_patch dmp = new diff_match_patch(); - dmp.Diff_Timeout = 0; - - // Execute one reverse diff as a warmup. - dmp.diff_main(text2, text1, false); - System.gc(); - - long start_time = System.currentTimeMillis(); - dmp.diff_main(text1, text2, false); - long end_time = System.currentTimeMillis(); - System.out.printf("Elapsed time: %f\n", ((end_time - start_time) / 1000.0)); - } - - private static String readFile(String filename) { - // Read a file from disk and return the text contents. - StringBuffer strbuf = new StringBuffer(); - try { - FileReader input = new FileReader(filename); - BufferedReader bufRead = new BufferedReader(input); - String line = bufRead.readLine(); - while (line != null) { - strbuf.append(line); - strbuf.append('\n'); - line = bufRead.readLine(); - } - - bufRead.close(); - - } catch (IOException e) { - e.printStackTrace(); - } - return strbuf.toString(); - } -} diff --git a/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java b/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java deleted file mode 100644 index f83852d2..00000000 --- a/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java +++ /dev/null @@ -1,973 +0,0 @@ -/* - * Diff Match and Patch -- Test harness - * Copyright 2018 The diff-match-patch Authors. - * https://github.com/google/diff-match-patch - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Compile from diff-match-patch/java with: - * javac -d target/classes src/main/java/name/fraser/neil/plaintext/diff_match_patch.java - * javac -classpath target/classes -d target/test-classes src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java - * - * Execute with: - * java -classpath target/classes:target/test-classes name/fraser/neil/plaintext/diff_match_patch_test - */ - -package name.fraser.neil.plaintext; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import name.fraser.neil.plaintext.diff_match_patch; -import name.fraser.neil.plaintext.diff_match_patch.Diff; -import name.fraser.neil.plaintext.diff_match_patch.LinesToCharsResult; -import name.fraser.neil.plaintext.diff_match_patch.Patch; - -public class diff_match_patch_test { - - private static diff_match_patch dmp; - private static diff_match_patch.Operation DELETE = diff_match_patch.Operation.DELETE; - private static diff_match_patch.Operation EQUAL = diff_match_patch.Operation.EQUAL; - private static diff_match_patch.Operation INSERT = diff_match_patch.Operation.INSERT; - - - // DIFF TEST FUNCTIONS - - - public static void testDiffCommonPrefix() { - // Detect any common prefix. - assertEquals("diff_commonPrefix: Null case.", 0, dmp.diff_commonPrefix("abc", "xyz")); - - assertEquals("diff_commonPrefix: Non-null case.", 4, dmp.diff_commonPrefix("1234abcdef", "1234xyz")); - - assertEquals("diff_commonPrefix: Whole case.", 4, dmp.diff_commonPrefix("1234", "1234xyz")); - } - - public static void testDiffCommonSuffix() { - // Detect any common suffix. - assertEquals("diff_commonSuffix: Null case.", 0, dmp.diff_commonSuffix("abc", "xyz")); - - assertEquals("diff_commonSuffix: Non-null case.", 4, dmp.diff_commonSuffix("abcdef1234", "xyz1234")); - - assertEquals("diff_commonSuffix: Whole case.", 4, dmp.diff_commonSuffix("1234", "xyz1234")); - } - - public static void testDiffCommonOverlap() { - // Detect any suffix/prefix overlap. - assertEquals("diff_commonOverlap: Null case.", 0, dmp.diff_commonOverlap("", "abcd")); - - assertEquals("diff_commonOverlap: Whole case.", 3, dmp.diff_commonOverlap("abc", "abcd")); - - assertEquals("diff_commonOverlap: No overlap.", 0, dmp.diff_commonOverlap("123456", "abcd")); - - assertEquals("diff_commonOverlap: Overlap.", 3, dmp.diff_commonOverlap("123456xxx", "xxxabcd")); - - // Some overly clever languages (C#) may treat ligatures as equal to their - // component letters. E.g. U+FB01 == 'fi' - assertEquals("diff_commonOverlap: Unicode.", 0, dmp.diff_commonOverlap("fi", "\ufb01i")); - } - - public static void testDiffHalfmatch() { - // Detect a halfmatch. - dmp.Diff_Timeout = 1; - assertNull("diff_halfMatch: No match #1.", dmp.diff_halfMatch("1234567890", "abcdef")); - - assertNull("diff_halfMatch: No match #2.", dmp.diff_halfMatch("12345", "23")); - - assertArrayEquals("diff_halfMatch: Single Match #1.", new String[]{"12", "90", "a", "z", "345678"}, dmp.diff_halfMatch("1234567890", "a345678z")); - - assertArrayEquals("diff_halfMatch: Single Match #2.", new String[]{"a", "z", "12", "90", "345678"}, dmp.diff_halfMatch("a345678z", "1234567890")); - - assertArrayEquals("diff_halfMatch: Single Match #3.", new String[]{"abc", "z", "1234", "0", "56789"}, dmp.diff_halfMatch("abc56789z", "1234567890")); - - assertArrayEquals("diff_halfMatch: Single Match #4.", new String[]{"a", "xyz", "1", "7890", "23456"}, dmp.diff_halfMatch("a23456xyz", "1234567890")); - - assertArrayEquals("diff_halfMatch: Multiple Matches #1.", new String[]{"12123", "123121", "a", "z", "1234123451234"}, dmp.diff_halfMatch("121231234123451234123121", "a1234123451234z")); - - assertArrayEquals("diff_halfMatch: Multiple Matches #2.", new String[]{"", "-=-=-=-=-=", "x", "", "x-=-=-=-=-=-=-="}, dmp.diff_halfMatch("x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-=")); - - assertArrayEquals("diff_halfMatch: Multiple Matches #3.", new String[]{"-=-=-=-=-=", "", "", "y", "-=-=-=-=-=-=-=y"}, dmp.diff_halfMatch("-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy")); - - // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy - assertArrayEquals("diff_halfMatch: Non-optimal halfmatch.", new String[]{"qHillo", "w", "x", "Hulloy", "HelloHe"}, dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy")); - - dmp.Diff_Timeout = 0; - assertNull("diff_halfMatch: Optimal no halfmatch.", dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy")); - } - - public static void testDiffLinesToChars() { - // Convert lines down to characters. - ArrayList tmpVector = new ArrayList(); - tmpVector.add(""); - tmpVector.add("alpha\n"); - tmpVector.add("beta\n"); - assertLinesToCharsResultEquals("diff_linesToChars: Shared lines.", new LinesToCharsResult("\u0001\u0002\u0001", "\u0002\u0001\u0002", tmpVector), dmp.diff_linesToChars("alpha\nbeta\nalpha\n", "beta\nalpha\nbeta\n")); - - tmpVector.clear(); - tmpVector.add(""); - tmpVector.add("alpha\r\n"); - tmpVector.add("beta\r\n"); - tmpVector.add("\r\n"); - assertLinesToCharsResultEquals("diff_linesToChars: Empty string and blank lines.", new LinesToCharsResult("", "\u0001\u0002\u0003\u0003", tmpVector), dmp.diff_linesToChars("", "alpha\r\nbeta\r\n\r\n\r\n")); - - tmpVector.clear(); - tmpVector.add(""); - tmpVector.add("a"); - tmpVector.add("b"); - assertLinesToCharsResultEquals("diff_linesToChars: No linebreaks.", new LinesToCharsResult("\u0001", "\u0002", tmpVector), dmp.diff_linesToChars("a", "b")); - - // More than 256 to reveal any 8-bit limitations. - int n = 300; - tmpVector.clear(); - StringBuilder lineList = new StringBuilder(); - StringBuilder charList = new StringBuilder(); - for (int x = 1; x < n + 1; x++) { - tmpVector.add(x + "\n"); - lineList.append(x + "\n"); - charList.append(String.valueOf((char) x)); - } - assertEquals("Test initialization fail #1.", n, tmpVector.size()); - String lines = lineList.toString(); - String chars = charList.toString(); - assertEquals("Test initialization fail #2.", n, chars.length()); - tmpVector.add(0, ""); - assertLinesToCharsResultEquals("diff_linesToChars: More than 256.", new LinesToCharsResult(chars, "", tmpVector), dmp.diff_linesToChars(lines, "")); - } - - public static void testDiffCharsToLines() { - // First check that Diff equality works. - assertTrue("diff_charsToLines: Equality #1.", new Diff(EQUAL, "a").equals(new Diff(EQUAL, "a"))); - - assertEquals("diff_charsToLines: Equality #2.", new Diff(EQUAL, "a"), new Diff(EQUAL, "a")); - - // Convert chars up to lines. - LinkedList diffs = diffList(new Diff(EQUAL, "\u0001\u0002\u0001"), new Diff(INSERT, "\u0002\u0001\u0002")); - ArrayList tmpVector = new ArrayList(); - tmpVector.add(""); - tmpVector.add("alpha\n"); - tmpVector.add("beta\n"); - dmp.diff_charsToLines(diffs, tmpVector); - assertEquals("diff_charsToLines: Shared lines.", diffList(new Diff(EQUAL, "alpha\nbeta\nalpha\n"), new Diff(INSERT, "beta\nalpha\nbeta\n")), diffs); - - // More than 256 to reveal any 8-bit limitations. - int n = 300; - tmpVector.clear(); - StringBuilder lineList = new StringBuilder(); - StringBuilder charList = new StringBuilder(); - for (int x = 1; x < n + 1; x++) { - tmpVector.add(x + "\n"); - lineList.append(x + "\n"); - charList.append(String.valueOf((char) x)); - } - assertEquals("Test initialization fail #3.", n, tmpVector.size()); - String lines = lineList.toString(); - String chars = charList.toString(); - assertEquals("Test initialization fail #4.", n, chars.length()); - tmpVector.add(0, ""); - diffs = diffList(new Diff(DELETE, chars)); - dmp.diff_charsToLines(diffs, tmpVector); - assertEquals("diff_charsToLines: More than 256.", diffList(new Diff(DELETE, lines)), diffs); - } - - public static void testDiffCleanupMerge() { - // Cleanup a messy diff. - LinkedList diffs = diffList(); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Null case.", diffList(), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(INSERT, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: No change case.", diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(INSERT, "c")), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(EQUAL, "b"), new Diff(EQUAL, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Merge equalities.", diffList(new Diff(EQUAL, "abc")), diffs); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(DELETE, "b"), new Diff(DELETE, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Merge deletions.", diffList(new Diff(DELETE, "abc")), diffs); - - diffs = diffList(new Diff(INSERT, "a"), new Diff(INSERT, "b"), new Diff(INSERT, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Merge insertions.", diffList(new Diff(INSERT, "abc")), diffs); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "b"), new Diff(DELETE, "c"), new Diff(INSERT, "d"), new Diff(EQUAL, "e"), new Diff(EQUAL, "f")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Merge interweave.", diffList(new Diff(DELETE, "ac"), new Diff(INSERT, "bd"), new Diff(EQUAL, "ef")), diffs); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "abc"), new Diff(DELETE, "dc")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Prefix and suffix detection.", diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "d"), new Diff(INSERT, "b"), new Diff(EQUAL, "c")), diffs); - - diffs = diffList(new Diff(EQUAL, "x"), new Diff(DELETE, "a"), new Diff(INSERT, "abc"), new Diff(DELETE, "dc"), new Diff(EQUAL, "y")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Prefix and suffix detection with equalities.", diffList(new Diff(EQUAL, "xa"), new Diff(DELETE, "d"), new Diff(INSERT, "b"), new Diff(EQUAL, "cy")), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(INSERT, "ba"), new Diff(EQUAL, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Slide edit left.", diffList(new Diff(INSERT, "ab"), new Diff(EQUAL, "ac")), diffs); - - diffs = diffList(new Diff(EQUAL, "c"), new Diff(INSERT, "ab"), new Diff(EQUAL, "a")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Slide edit right.", diffList(new Diff(EQUAL, "ca"), new Diff(INSERT, "ba")), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(EQUAL, "c"), new Diff(DELETE, "ac"), new Diff(EQUAL, "x")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Slide edit left recursive.", diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "acx")), diffs); - - diffs = diffList(new Diff(EQUAL, "x"), new Diff(DELETE, "ca"), new Diff(EQUAL, "c"), new Diff(DELETE, "b"), new Diff(EQUAL, "a")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Slide edit right recursive.", diffList(new Diff(EQUAL, "xca"), new Diff(DELETE, "cba")), diffs); - } - - public static void testDiffCleanupSemanticLossless() { - // Slide diffs to match logical boundaries. - LinkedList diffs = diffList(); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Null case.", diffList(), diffs); - - diffs = diffList(new Diff(EQUAL, "AAA\r\n\r\nBBB"), new Diff(INSERT, "\r\nDDD\r\n\r\nBBB"), new Diff(EQUAL, "\r\nEEE")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Blank lines.", diffList(new Diff(EQUAL, "AAA\r\n\r\n"), new Diff(INSERT, "BBB\r\nDDD\r\n\r\n"), new Diff(EQUAL, "BBB\r\nEEE")), diffs); - - diffs = diffList(new Diff(EQUAL, "AAA\r\nBBB"), new Diff(INSERT, " DDD\r\nBBB"), new Diff(EQUAL, " EEE")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Line boundaries.", diffList(new Diff(EQUAL, "AAA\r\n"), new Diff(INSERT, "BBB DDD\r\n"), new Diff(EQUAL, "BBB EEE")), diffs); - - diffs = diffList(new Diff(EQUAL, "The c"), new Diff(INSERT, "ow and the c"), new Diff(EQUAL, "at.")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Word boundaries.", diffList(new Diff(EQUAL, "The "), new Diff(INSERT, "cow and the "), new Diff(EQUAL, "cat.")), diffs); - - diffs = diffList(new Diff(EQUAL, "The-c"), new Diff(INSERT, "ow-and-the-c"), new Diff(EQUAL, "at.")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Alphanumeric boundaries.", diffList(new Diff(EQUAL, "The-"), new Diff(INSERT, "cow-and-the-"), new Diff(EQUAL, "cat.")), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "a"), new Diff(EQUAL, "ax")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Hitting the start.", diffList(new Diff(DELETE, "a"), new Diff(EQUAL, "aax")), diffs); - - diffs = diffList(new Diff(EQUAL, "xa"), new Diff(DELETE, "a"), new Diff(EQUAL, "a")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Hitting the end.", diffList(new Diff(EQUAL, "xaa"), new Diff(DELETE, "a")), diffs); - - diffs = diffList(new Diff(EQUAL, "The xxx. The "), new Diff(INSERT, "zzz. The "), new Diff(EQUAL, "yyy.")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Sentence boundaries.", diffList(new Diff(EQUAL, "The xxx."), new Diff(INSERT, " The zzz."), new Diff(EQUAL, " The yyy.")), diffs); - } - - public static void testDiffCleanupSemantic() { - // Cleanup semantically trivial equalities. - LinkedList diffs = diffList(); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Null case.", diffList(), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "cd"), new Diff(EQUAL, "12"), new Diff(DELETE, "e")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: No elimination #1.", diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "cd"), new Diff(EQUAL, "12"), new Diff(DELETE, "e")), diffs); - - diffs = diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "ABC"), new Diff(EQUAL, "1234"), new Diff(DELETE, "wxyz")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: No elimination #2.", diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "ABC"), new Diff(EQUAL, "1234"), new Diff(DELETE, "wxyz")), diffs); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(EQUAL, "b"), new Diff(DELETE, "c")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Simple elimination.", diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "b")), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(EQUAL, "cd"), new Diff(DELETE, "e"), new Diff(EQUAL, "f"), new Diff(INSERT, "g")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Backpass elimination.", diffList(new Diff(DELETE, "abcdef"), new Diff(INSERT, "cdfg")), diffs); - - diffs = diffList(new Diff(INSERT, "1"), new Diff(EQUAL, "A"), new Diff(DELETE, "B"), new Diff(INSERT, "2"), new Diff(EQUAL, "_"), new Diff(INSERT, "1"), new Diff(EQUAL, "A"), new Diff(DELETE, "B"), new Diff(INSERT, "2")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Multiple elimination.", diffList(new Diff(DELETE, "AB_AB"), new Diff(INSERT, "1A2_1A2")), diffs); - - diffs = diffList(new Diff(EQUAL, "The c"), new Diff(DELETE, "ow and the c"), new Diff(EQUAL, "at.")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Word boundaries.", diffList(new Diff(EQUAL, "The "), new Diff(DELETE, "cow and the "), new Diff(EQUAL, "cat.")), diffs); - - diffs = diffList(new Diff(DELETE, "abcxx"), new Diff(INSERT, "xxdef")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: No overlap elimination.", diffList(new Diff(DELETE, "abcxx"), new Diff(INSERT, "xxdef")), diffs); - - diffs = diffList(new Diff(DELETE, "abcxxx"), new Diff(INSERT, "xxxdef")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Overlap elimination.", diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "xxx"), new Diff(INSERT, "def")), diffs); - - diffs = diffList(new Diff(DELETE, "xxxabc"), new Diff(INSERT, "defxxx")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Reverse overlap elimination.", diffList(new Diff(INSERT, "def"), new Diff(EQUAL, "xxx"), new Diff(DELETE, "abc")), diffs); - - diffs = diffList(new Diff(DELETE, "abcd1212"), new Diff(INSERT, "1212efghi"), new Diff(EQUAL, "----"), new Diff(DELETE, "A3"), new Diff(INSERT, "3BC")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Two overlap eliminations.", diffList(new Diff(DELETE, "abcd"), new Diff(EQUAL, "1212"), new Diff(INSERT, "efghi"), new Diff(EQUAL, "----"), new Diff(DELETE, "A"), new Diff(EQUAL, "3"), new Diff(INSERT, "BC")), diffs); - } - - public static void testDiffCleanupEfficiency() { - // Cleanup operationally trivial equalities. - dmp.Diff_EditCost = 4; - LinkedList diffs = diffList(); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: Null case.", diffList(), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: No elimination.", diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "xyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: Four-edit elimination.", diffList(new Diff(DELETE, "abxyzcd"), new Diff(INSERT, "12xyz34")), diffs); - - diffs = diffList(new Diff(INSERT, "12"), new Diff(EQUAL, "x"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: Three-edit elimination.", diffList(new Diff(DELETE, "xcd"), new Diff(INSERT, "12x34")), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "xy"), new Diff(INSERT, "34"), new Diff(EQUAL, "z"), new Diff(DELETE, "cd"), new Diff(INSERT, "56")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: Backpass elimination.", diffList(new Diff(DELETE, "abxyzcd"), new Diff(INSERT, "12xy34z56")), diffs); - - dmp.Diff_EditCost = 5; - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: High cost elimination.", diffList(new Diff(DELETE, "abwxyzcd"), new Diff(INSERT, "12wxyz34")), diffs); - dmp.Diff_EditCost = 4; - } - - public static void testDiffPrettyHtml() { - // Pretty print. - LinkedList diffs = diffList(new Diff(EQUAL, "a\n"), new Diff(DELETE, "b"), new Diff(INSERT, "c&d")); - assertEquals("diff_prettyHtml:", "
<B>b</B>c&d", dmp.diff_prettyHtml(diffs)); - } - - public static void testDiffText() { - // Compute the source and destination texts. - LinkedList diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, " lazy")); - assertEquals("diff_text1:", "jumps over the lazy", dmp.diff_text1(diffs)); - assertEquals("diff_text2:", "jumped over a lazy", dmp.diff_text2(diffs)); - } - - public static void testDiffDelta() { - // Convert a diff into delta string. - LinkedList diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, " lazy"), new Diff(INSERT, "old dog")); - String text1 = dmp.diff_text1(diffs); - assertEquals("diff_text1: Base text.", "jumps over the lazy", text1); - - String delta = dmp.diff_toDelta(diffs); - assertEquals("diff_toDelta:", "=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog", delta); - - // Convert delta string into a diff. - assertEquals("diff_fromDelta: Normal.", diffs, dmp.diff_fromDelta(text1, delta)); - - // Generates error (19 < 20). - try { - dmp.diff_fromDelta(text1 + "x", delta); - fail("diff_fromDelta: Too long."); - } catch (IllegalArgumentException ex) { - // Exception expected. - } - - // Generates error (19 > 18). - try { - dmp.diff_fromDelta(text1.substring(1), delta); - fail("diff_fromDelta: Too short."); - } catch (IllegalArgumentException ex) { - // Exception expected. - } - - // Generates error (%c3%xy invalid Unicode). - try { - dmp.diff_fromDelta("", "+%c3%xy"); - fail("diff_fromDelta: Invalid character."); - } catch (IllegalArgumentException ex) { - // Exception expected. - } - - // Test deltas with special characters. - diffs = diffList(new Diff(EQUAL, "\u0680 \000 \t %"), new Diff(DELETE, "\u0681 \001 \n ^"), new Diff(INSERT, "\u0682 \002 \\ |")); - text1 = dmp.diff_text1(diffs); - assertEquals("diff_text1: Unicode text.", "\u0680 \000 \t %\u0681 \001 \n ^", text1); - - delta = dmp.diff_toDelta(diffs); - assertEquals("diff_toDelta: Unicode.", "=7\t-7\t+%DA%82 %02 %5C %7C", delta); - - assertEquals("diff_fromDelta: Unicode.", diffs, dmp.diff_fromDelta(text1, delta)); - - // Verify pool of unchanged characters. - diffs = diffList(new Diff(INSERT, "A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # ")); - String text2 = dmp.diff_text2(diffs); - assertEquals("diff_text2: Unchanged characters.", "A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ", text2); - - delta = dmp.diff_toDelta(diffs); - assertEquals("diff_toDelta: Unchanged characters.", "+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ", delta); - - // Convert delta string into a diff. - assertEquals("diff_fromDelta: Unchanged characters.", diffs, dmp.diff_fromDelta("", delta)); - } - - public static void testDiffXIndex() { - // Translate a location in text1 to text2. - LinkedList diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz")); - assertEquals("diff_xIndex: Translation on equality.", 5, dmp.diff_xIndex(diffs, 2)); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "1234"), new Diff(EQUAL, "xyz")); - assertEquals("diff_xIndex: Translation on deletion.", 1, dmp.diff_xIndex(diffs, 3)); - } - - public static void testDiffLevenshtein() { - LinkedList diffs = diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz")); - assertEquals("diff_levenshtein: Levenshtein with trailing equality.", 4, dmp.diff_levenshtein(diffs)); - - diffs = diffList(new Diff(EQUAL, "xyz"), new Diff(DELETE, "abc"), new Diff(INSERT, "1234")); - assertEquals("diff_levenshtein: Levenshtein with leading equality.", 4, dmp.diff_levenshtein(diffs)); - - diffs = diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "xyz"), new Diff(INSERT, "1234")); - assertEquals("diff_levenshtein: Levenshtein with middle equality.", 7, dmp.diff_levenshtein(diffs)); - } - - public static void testDiffBisect() { - // Normal. - String a = "cat"; - String b = "map"; - // 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. - LinkedList diffs = diffList(new Diff(DELETE, "c"), new Diff(INSERT, "m"), new Diff(EQUAL, "a"), new Diff(DELETE, "t"), new Diff(INSERT, "p")); - assertEquals("diff_bisect: Normal.", diffs, dmp.diff_bisect(a, b, Long.MAX_VALUE)); - - // Timeout. - diffs = diffList(new Diff(DELETE, "cat"), new Diff(INSERT, "map")); - assertEquals("diff_bisect: Timeout.", diffs, dmp.diff_bisect(a, b, 0)); - } - - public static void testDiffMain() { - // Perform a trivial diff. - LinkedList diffs = diffList(); - assertEquals("diff_main: Null case.", diffs, dmp.diff_main("", "", false)); - - diffs = diffList(new Diff(EQUAL, "abc")); - assertEquals("diff_main: Equality.", diffs, dmp.diff_main("abc", "abc", false)); - - diffs = diffList(new Diff(EQUAL, "ab"), new Diff(INSERT, "123"), new Diff(EQUAL, "c")); - assertEquals("diff_main: Simple insertion.", diffs, dmp.diff_main("abc", "ab123c", false)); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "123"), new Diff(EQUAL, "bc")); - assertEquals("diff_main: Simple deletion.", diffs, dmp.diff_main("a123bc", "abc", false)); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(INSERT, "123"), new Diff(EQUAL, "b"), new Diff(INSERT, "456"), new Diff(EQUAL, "c")); - assertEquals("diff_main: Two insertions.", diffs, dmp.diff_main("abc", "a123b456c", false)); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "123"), new Diff(EQUAL, "b"), new Diff(DELETE, "456"), new Diff(EQUAL, "c")); - assertEquals("diff_main: Two deletions.", diffs, dmp.diff_main("a123b456c", "abc", false)); - - // Perform a real diff. - // Switch off the timeout. - dmp.Diff_Timeout = 0; - diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "b")); - assertEquals("diff_main: Simple case #1.", diffs, dmp.diff_main("a", "b", false)); - - diffs = diffList(new Diff(DELETE, "Apple"), new Diff(INSERT, "Banana"), new Diff(EQUAL, "s are a"), new Diff(INSERT, "lso"), new Diff(EQUAL, " fruit.")); - assertEquals("diff_main: Simple case #2.", diffs, dmp.diff_main("Apples are a fruit.", "Bananas are also fruit.", false)); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "\u0680"), new Diff(EQUAL, "x"), new Diff(DELETE, "\t"), new Diff(INSERT, "\000")); - assertEquals("diff_main: Simple case #3.", diffs, dmp.diff_main("ax\t", "\u0680x\000", false)); - - diffs = diffList(new Diff(DELETE, "1"), new Diff(EQUAL, "a"), new Diff(DELETE, "y"), new Diff(EQUAL, "b"), new Diff(DELETE, "2"), new Diff(INSERT, "xab")); - assertEquals("diff_main: Overlap #1.", diffs, dmp.diff_main("1ayb2", "abxab", false)); - - diffs = diffList(new Diff(INSERT, "xaxcx"), new Diff(EQUAL, "abc"), new Diff(DELETE, "y")); - assertEquals("diff_main: Overlap #2.", diffs, dmp.diff_main("abcy", "xaxcxabc", false)); - - diffs = diffList(new Diff(DELETE, "ABCD"), new Diff(EQUAL, "a"), new Diff(DELETE, "="), new Diff(INSERT, "-"), new Diff(EQUAL, "bcd"), new Diff(DELETE, "="), new Diff(INSERT, "-"), new Diff(EQUAL, "efghijklmnopqrs"), new Diff(DELETE, "EFGHIJKLMNOefg")); - assertEquals("diff_main: Overlap #3.", diffs, dmp.diff_main("ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg", "a-bcd-efghijklmnopqrs", false)); - - diffs = diffList(new Diff(INSERT, " "), new Diff(EQUAL, "a"), new Diff(INSERT, "nd"), new Diff(EQUAL, " [[Pennsylvania]]"), new Diff(DELETE, " and [[New")); - assertEquals("diff_main: Large equality.", diffs, dmp.diff_main("a [[Pennsylvania]] and [[New", " and [[Pennsylvania]]", false)); - - dmp.Diff_Timeout = 0.1f; // 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 x = 0; x < 10; x++) { - a = a + a; - b = b + b; - } - long startTime = System.currentTimeMillis(); - dmp.diff_main(a, b); - long endTime = System.currentTimeMillis(); - // Test that we took at least the timeout period. - assertTrue("diff_main: Timeout min.", dmp.Diff_Timeout * 1000 <= endTime - startTime); - // Test that we didn't take forever (be forgiving). - // Theoretically this test could fail very occasionally if the - // OS task swaps or locks up for a second at the wrong moment. - assertTrue("diff_main: Timeout max.", dmp.Diff_Timeout * 1000 * 2 > endTime - startTime); - dmp.Diff_Timeout = 0; - - // Test the linemode speedup. - // Must be long to pass the 100 char cutoff. - a = "1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n"; - b = "abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n"; - assertEquals("diff_main: Simple line-mode.", dmp.diff_main(a, b, true), dmp.diff_main(a, b, false)); - - a = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; - b = "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"; - assertEquals("diff_main: Single line-mode.", dmp.diff_main(a, b, true), dmp.diff_main(a, b, false)); - - a = "1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n"; - b = "abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n"; - String[] texts_linemode = diff_rebuildtexts(dmp.diff_main(a, b, true)); - String[] texts_textmode = diff_rebuildtexts(dmp.diff_main(a, b, false)); - assertArrayEquals("diff_main: Overlap line-mode.", texts_textmode, texts_linemode); - - // Test null inputs. - try { - dmp.diff_main(null, null); - fail("diff_main: Null inputs."); - } catch (IllegalArgumentException ex) { - // Error expected. - } - } - - - // MATCH TEST FUNCTIONS - - - public static void testMatchAlphabet() { - // Initialise the bitmasks for Bitap. - Map bitmask; - bitmask = new HashMap(); - bitmask.put('a', 4); bitmask.put('b', 2); bitmask.put('c', 1); - assertEquals("match_alphabet: Unique.", bitmask, dmp.match_alphabet("abc")); - - bitmask = new HashMap(); - bitmask.put('a', 37); bitmask.put('b', 18); bitmask.put('c', 8); - assertEquals("match_alphabet: Duplicates.", bitmask, dmp.match_alphabet("abcaba")); - } - - public static void testMatchBitap() { - // Bitap algorithm. - dmp.Match_Distance = 100; - dmp.Match_Threshold = 0.5f; - assertEquals("match_bitap: Exact match #1.", 5, dmp.match_bitap("abcdefghijk", "fgh", 5)); - - assertEquals("match_bitap: Exact match #2.", 5, dmp.match_bitap("abcdefghijk", "fgh", 0)); - - assertEquals("match_bitap: Fuzzy match #1.", 4, dmp.match_bitap("abcdefghijk", "efxhi", 0)); - - assertEquals("match_bitap: Fuzzy match #2.", 2, dmp.match_bitap("abcdefghijk", "cdefxyhijk", 5)); - - assertEquals("match_bitap: Fuzzy match #3.", -1, dmp.match_bitap("abcdefghijk", "bxy", 1)); - - assertEquals("match_bitap: Overflow.", 2, dmp.match_bitap("123456789xx0", "3456789x0", 2)); - - assertEquals("match_bitap: Before start match.", 0, dmp.match_bitap("abcdef", "xxabc", 4)); - - assertEquals("match_bitap: Beyond end match.", 3, dmp.match_bitap("abcdef", "defyy", 4)); - - assertEquals("match_bitap: Oversized pattern.", 0, dmp.match_bitap("abcdef", "xabcdefy", 0)); - - dmp.Match_Threshold = 0.4f; - assertEquals("match_bitap: Threshold #1.", 4, dmp.match_bitap("abcdefghijk", "efxyhi", 1)); - - dmp.Match_Threshold = 0.3f; - assertEquals("match_bitap: Threshold #2.", -1, dmp.match_bitap("abcdefghijk", "efxyhi", 1)); - - dmp.Match_Threshold = 0.0f; - assertEquals("match_bitap: Threshold #3.", 1, dmp.match_bitap("abcdefghijk", "bcdef", 1)); - - dmp.Match_Threshold = 0.5f; - assertEquals("match_bitap: Multiple select #1.", 0, dmp.match_bitap("abcdexyzabcde", "abccde", 3)); - - assertEquals("match_bitap: Multiple select #2.", 8, dmp.match_bitap("abcdexyzabcde", "abccde", 5)); - - dmp.Match_Distance = 10; // Strict location. - assertEquals("match_bitap: Distance test #1.", -1, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24)); - - assertEquals("match_bitap: Distance test #2.", 0, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdxxefg", 1)); - - dmp.Match_Distance = 1000; // Loose location. - assertEquals("match_bitap: Distance test #3.", 0, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24)); - } - - public static void testMatchMain() { - // Full match. - assertEquals("match_main: Equality.", 0, dmp.match_main("abcdef", "abcdef", 1000)); - - assertEquals("match_main: Null text.", -1, dmp.match_main("", "abcdef", 1)); - - assertEquals("match_main: Null pattern.", 3, dmp.match_main("abcdef", "", 3)); - - assertEquals("match_main: Exact match.", 3, dmp.match_main("abcdef", "de", 3)); - - assertEquals("match_main: Beyond end match.", 3, dmp.match_main("abcdef", "defy", 4)); - - assertEquals("match_main: Oversized pattern.", 0, dmp.match_main("abcdef", "abcdefy", 0)); - - dmp.Match_Threshold = 0.7f; - assertEquals("match_main: Complex match.", 4, dmp.match_main("I am the very model of a modern major general.", " that berry ", 5)); - dmp.Match_Threshold = 0.5f; - - // Test null inputs. - try { - dmp.match_main(null, null, 0); - fail("match_main: Null inputs."); - } catch (IllegalArgumentException ex) { - // Error expected. - } - } - - - // PATCH TEST FUNCTIONS - - - public static void testPatchObj() { - // Patch Object. - Patch p = new Patch(); - p.start1 = 20; - p.start2 = 21; - p.length1 = 18; - p.length2 = 17; - p.diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, "\nlaz")); - String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n"; - assertEquals("Patch: toString.", strp, p.toString()); - } - - public static void testPatchFromText() { - assertTrue("patch_fromText: #0.", dmp.patch_fromText("").isEmpty()); - - String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n"; - assertEquals("patch_fromText: #1.", strp, dmp.patch_fromText(strp).get(0).toString()); - - assertEquals("patch_fromText: #2.", "@@ -1 +1 @@\n-a\n+b\n", dmp.patch_fromText("@@ -1 +1 @@\n-a\n+b\n").get(0).toString()); - - assertEquals("patch_fromText: #3.", "@@ -1,3 +0,0 @@\n-abc\n", dmp.patch_fromText("@@ -1,3 +0,0 @@\n-abc\n").get(0).toString()); - - assertEquals("patch_fromText: #4.", "@@ -0,0 +1,3 @@\n+abc\n", dmp.patch_fromText("@@ -0,0 +1,3 @@\n+abc\n").get(0).toString()); - - // Generates error. - try { - dmp.patch_fromText("Bad\nPatch\n"); - fail("patch_fromText: #5."); - } catch (IllegalArgumentException ex) { - // Exception expected. - } - } - - public static void testPatchToText() { - String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n"; - List patches; - patches = dmp.patch_fromText(strp); - assertEquals("patch_toText: Single.", strp, dmp.patch_toText(patches)); - - strp = "@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n"; - patches = dmp.patch_fromText(strp); - assertEquals("patch_toText: Dual.", strp, dmp.patch_toText(patches)); - } - - public static void testPatchAddContext() { - dmp.Patch_Margin = 4; - Patch p; - p = dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n").get(0); - dmp.patch_addContext(p, "The quick brown fox jumps over the lazy dog."); - assertEquals("patch_addContext: Simple case.", "@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n", p.toString()); - - p = dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n").get(0); - dmp.patch_addContext(p, "The quick brown fox jumps."); - assertEquals("patch_addContext: Not enough trailing context.", "@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n", p.toString()); - - p = dmp.patch_fromText("@@ -3 +3,2 @@\n-e\n+at\n").get(0); - dmp.patch_addContext(p, "The quick brown fox jumps."); - assertEquals("patch_addContext: Not enough leading context.", "@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n", p.toString()); - - p = dmp.patch_fromText("@@ -3 +3,2 @@\n-e\n+at\n").get(0); - dmp.patch_addContext(p, "The quick brown fox jumps. The quick brown fox crashes."); - assertEquals("patch_addContext: Ambiguity.", "@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n", p.toString()); - } - - @SuppressWarnings("deprecation") - public static void testPatchMake() { - LinkedList patches; - patches = dmp.patch_make("", ""); - assertEquals("patch_make: Null case.", "", dmp.patch_toText(patches)); - - 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"; - // The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context. - patches = dmp.patch_make(text2, text1); - assertEquals("patch_make: Text2+Text1 inputs.", expectedPatch, dmp.patch_toText(patches)); - - 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); - assertEquals("patch_make: Text1+Text2 inputs.", expectedPatch, dmp.patch_toText(patches)); - - LinkedList diffs = dmp.diff_main(text1, text2, false); - patches = dmp.patch_make(diffs); - assertEquals("patch_make: Diff input.", expectedPatch, dmp.patch_toText(patches)); - - patches = dmp.patch_make(text1, diffs); - assertEquals("patch_make: Text1+Diff inputs.", expectedPatch, dmp.patch_toText(patches)); - - patches = dmp.patch_make(text1, text2, diffs); - assertEquals("patch_make: Text1+Text2+Diff inputs (deprecated).", expectedPatch, dmp.patch_toText(patches)); - - patches = dmp.patch_make("`1234567890-=[]\\;',./", "~!@#$%^&*()_+{}|:\"<>?"); - assertEquals("patch_toText: Character encoding.", "@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n", dmp.patch_toText(patches)); - - diffs = diffList(new Diff(DELETE, "`1234567890-=[]\\;',./"), new Diff(INSERT, "~!@#$%^&*()_+{}|:\"<>?")); - assertEquals("patch_fromText: Character decoding.", diffs, dmp.patch_fromText("@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n").get(0).diffs); - - text1 = ""; - for (int x = 0; x < 100; x++) { - text1 += "abcdef"; - } - text2 = text1 + "123"; - expectedPatch = "@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n"; - patches = dmp.patch_make(text1, text2); - assertEquals("patch_make: Long string with repeats.", expectedPatch, dmp.patch_toText(patches)); - - // Test null inputs. - try { - dmp.patch_make(null); - fail("patch_make: Null inputs."); - } catch (IllegalArgumentException ex) { - // Error expected. - } - } - - public static void testPatchSplitMax() { - // Assumes that Match_MaxBits is 32. - LinkedList patches; - patches = dmp.patch_make("abcdefghijklmnopqrstuvwxyz01234567890", "XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0"); - dmp.patch_splitMax(patches); - assertEquals("patch_splitMax: #1.", "@@ -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)); - - patches = dmp.patch_make("abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz", "abcdefuvwxyz"); - String oldToText = dmp.patch_toText(patches); - dmp.patch_splitMax(patches); - assertEquals("patch_splitMax: #2.", oldToText, dmp.patch_toText(patches)); - - patches = dmp.patch_make("1234567890123456789012345678901234567890123456789012345678901234567890", "abc"); - dmp.patch_splitMax(patches); - assertEquals("patch_splitMax: #3.", "@@ -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)); - - 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); - assertEquals("patch_splitMax: #4.", "@@ -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)); - } - - public static void testPatchAddPadding() { - LinkedList patches; - patches = dmp.patch_make("", "test"); - assertEquals("patch_addPadding: Both edges full.", "@@ -0,0 +1,4 @@\n+test\n", dmp.patch_toText(patches)); - dmp.patch_addPadding(patches); - assertEquals("patch_addPadding: Both edges full.", "@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n", dmp.patch_toText(patches)); - - patches = dmp.patch_make("XY", "XtestY"); - assertEquals("patch_addPadding: Both edges partial.", "@@ -1,2 +1,6 @@\n X\n+test\n Y\n", dmp.patch_toText(patches)); - dmp.patch_addPadding(patches); - assertEquals("patch_addPadding: Both edges partial.", "@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n", dmp.patch_toText(patches)); - - patches = dmp.patch_make("XXXXYYYY", "XXXXtestYYYY"); - assertEquals("patch_addPadding: Both edges none.", "@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n", dmp.patch_toText(patches)); - dmp.patch_addPadding(patches); - assertEquals("patch_addPadding: Both edges none.", "@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n", dmp.patch_toText(patches)); - } - - public static void testPatchApply() { - dmp.Match_Distance = 1000; - dmp.Match_Threshold = 0.5f; - dmp.Patch_DeleteThreshold = 0.5f; - LinkedList patches; - patches = dmp.patch_make("", ""); - Object[] results = dmp.patch_apply(patches, "Hello world."); - boolean[] boolArray = (boolean[]) results[1]; - String resultStr = results[0] + "\t" + boolArray.length; - assertEquals("patch_apply: Null case.", "Hello world.\t0", resultStr); - - 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 = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Exact match.", "That quick brown fox jumped over a lazy dog.\ttrue\ttrue", resultStr); - - results = dmp.patch_apply(patches, "The quick red rabbit jumps over the tired tiger."); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Partial match.", "That quick red rabbit jumped over a tired tiger.\ttrue\ttrue", resultStr); - - results = dmp.patch_apply(patches, "I am the very model of a modern major general."); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Failed match.", "I am the very model of a modern major general.\tfalse\tfalse", resultStr); - - patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); - results = dmp.patch_apply(patches, "x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Big delete, small change.", "xabcy\ttrue\ttrue", resultStr); - - patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); - results = dmp.patch_apply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Big delete, big change 1.", "xabc12345678901234567890---------------++++++++++---------------12345678901234567890y\tfalse\ttrue", resultStr); - - dmp.Patch_DeleteThreshold = 0.6f; - patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); - results = dmp.patch_apply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Big delete, big change 2.", "xabcy\ttrue\ttrue", resultStr); - dmp.Patch_DeleteThreshold = 0.5f; - - // Compensate for failed patch. - dmp.Match_Threshold = 0.0f; - dmp.Match_Distance = 0; - patches = dmp.patch_make("abcdefghijklmnopqrstuvwxyz--------------------1234567890", "abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890"); - results = dmp.patch_apply(patches, "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Compensate for failed patch.", "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890\tfalse\ttrue", resultStr); - dmp.Match_Threshold = 0.5f; - dmp.Match_Distance = 1000; - - patches = dmp.patch_make("", "test"); - String patchStr = dmp.patch_toText(patches); - dmp.patch_apply(patches, ""); - assertEquals("patch_apply: No side effects.", patchStr, dmp.patch_toText(patches)); - - patches = dmp.patch_make("The quick brown fox jumps over the lazy dog.", "Woof"); - patchStr = dmp.patch_toText(patches); - dmp.patch_apply(patches, "The quick brown fox jumps over the lazy dog."); - assertEquals("patch_apply: No side effects with major delete.", patchStr, dmp.patch_toText(patches)); - - patches = dmp.patch_make("", "test"); - results = dmp.patch_apply(patches, ""); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0]; - assertEquals("patch_apply: Edge exact match.", "test\ttrue", resultStr); - - patches = dmp.patch_make("XY", "XtestY"); - results = dmp.patch_apply(patches, "XY"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0]; - assertEquals("patch_apply: Near edge exact match.", "XtestY\ttrue", resultStr); - - patches = dmp.patch_make("y", "y123"); - results = dmp.patch_apply(patches, "x"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0]; - assertEquals("patch_apply: Edge partial match.", "x123\ttrue", resultStr); - } - - private static void assertEquals(String error_msg, Object a, Object b) { - if (!a.toString().equals(b.toString())) { - throw new Error("assertEquals fail:\n Expected: " + a + "\n Actual: " + b - + "\n" + error_msg); - } - } - - private static void assertTrue(String error_msg, boolean a) { - if (!a) { - throw new Error("assertTrue fail: " + error_msg); - } - } - - private static void assertNull(String error_msg, Object n) { - if (n != null) { - throw new Error("assertNull fail: " + error_msg); - } - } - - private static void fail(String error_msg) { - throw new Error("Fail: " + error_msg); - } - - private static void assertArrayEquals(String error_msg, Object[] a, Object[] b) { - List list_a = Arrays.asList(a); - List list_b = Arrays.asList(b); - assertEquals(error_msg, list_a, list_b); - } - - private static void assertLinesToCharsResultEquals(String error_msg, - LinesToCharsResult a, LinesToCharsResult b) { - assertEquals(error_msg, a.chars1, b.chars1); - assertEquals(error_msg, a.chars2, b.chars2); - assertEquals(error_msg, a.lineArray, b.lineArray); - } - - // Construct the two texts which made up the diff originally. - private static String[] diff_rebuildtexts(LinkedList diffs) { - String[] text = {"", ""}; - for (Diff myDiff : diffs) { - if (myDiff.operation != diff_match_patch.Operation.INSERT) { - text[0] += myDiff.text; - } - if (myDiff.operation != diff_match_patch.Operation.DELETE) { - text[1] += myDiff.text; - } - } - return text; - } - - // Private function for quickly building lists of diffs. - private static LinkedList diffList(Diff... diffs) { - LinkedList myDiffList = new LinkedList(); - for (Diff myDiff : diffs) { - myDiffList.add(myDiff); - } - return myDiffList; - } - - public static void main(String args[]) { - dmp = new diff_match_patch(); - - testDiffCommonPrefix(); - testDiffCommonSuffix(); - testDiffCommonOverlap(); - testDiffHalfmatch(); - testDiffLinesToChars(); - testDiffCharsToLines(); - testDiffCleanupMerge(); - testDiffCleanupSemanticLossless(); - testDiffCleanupSemantic(); - testDiffCleanupEfficiency(); - testDiffPrettyHtml(); - testDiffText(); - testDiffDelta(); - testDiffXIndex(); - testDiffLevenshtein(); - testDiffBisect(); - testDiffMain(); - - testMatchAlphabet(); - testMatchBitap(); - testMatchMain(); - - testPatchObj(); - testPatchFromText(); - testPatchToText(); - testPatchAddContext(); - testPatchMake(); - testPatchSplitMax(); - testPatchAddPadding(); - testPatchApply(); - - System.out.println("All tests passed."); - } -} From 8abf49f88212ff69335aa1685fa0321cdc6bd7e8 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Wed, 23 May 2018 08:40:01 -0700 Subject: [PATCH 08/10] Remove nexus related configuration from pom.xml --- java/pom.xml | 56 +--------------------------------------------------- 1 file changed, 1 insertion(+), 55 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index 06216d38..1d017cf8 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -1,11 +1,5 @@ 4.0.0 - - org.sonatype.oss - oss-parent - 9 - - com.google diff-match-patch 1.0.0 @@ -28,18 +22,6 @@ - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.8 - true - - ossrh - https://oss.sonatype.org/ - true - - - maven-compiler-plugin 3.6.2 @@ -103,12 +85,6 @@ false - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - @@ -148,34 +124,4 @@ repo - - - - release-sign-artifacts - - - performRelease - true - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - - - - \ No newline at end of file + From abc6a750623c60f0c093abd13a0711a1898f37e4 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Wed, 23 May 2018 09:16:29 -0700 Subject: [PATCH 09/10] Get the latest test and conver to junit format --- java/pom.xml | 9 +- .../neil/plaintext/DiffMatchPatchTest.java | 1005 ----------------- .../neil/plaintext/diff_match_patch_test.java | 91 +- 3 files changed, 67 insertions(+), 1038 deletions(-) delete mode 100644 java/src/test/java/name/fraser/neil/plaintext/DiffMatchPatchTest.java rename java/{tests => src/test/java}/name/fraser/neil/plaintext/diff_match_patch_test.java (97%) diff --git a/java/pom.xml b/java/pom.xml index 1d017cf8..ee282238 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 com.google diff-match-patch @@ -80,9 +81,13 @@ maven-surefire-plugin - 2.20 + 2.21.0 false + + **/diff_match_patch_test.java + **/*Test + diff --git a/java/src/test/java/name/fraser/neil/plaintext/DiffMatchPatchTest.java b/java/src/test/java/name/fraser/neil/plaintext/DiffMatchPatchTest.java deleted file mode 100644 index 3b595a1b..00000000 --- a/java/src/test/java/name/fraser/neil/plaintext/DiffMatchPatchTest.java +++ /dev/null @@ -1,1005 +0,0 @@ -/* - * Diff Match and Patch -- Test harness Copyright 2018 The diff-match-patch Authors. - * https://github.com/google/diff-match-patch - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package name.fraser.neil.plaintext; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.junit.Test; - -import name.fraser.neil.plaintext.diff_match_patch.Diff; -import name.fraser.neil.plaintext.diff_match_patch.LinesToCharsResult; -import name.fraser.neil.plaintext.diff_match_patch.Patch; - -public class DiffMatchPatchTest { - - private static diff_match_patch dmp = new diff_match_patch(); - private static diff_match_patch.Operation DELETE = diff_match_patch.Operation.DELETE; - private static diff_match_patch.Operation EQUAL = diff_match_patch.Operation.EQUAL; - private static diff_match_patch.Operation INSERT = diff_match_patch.Operation.INSERT; - - // DIFF TEST FUNCTIONS - - @Test - public void testDiffCommonPrefix() { - // Detect any common prefix. - assertEquals("diff_commonPrefix: Null case.", 0, dmp.diff_commonPrefix("abc", "xyz")); - - assertEquals("diff_commonPrefix: Non-null case.", 4, dmp.diff_commonPrefix("1234abcdef", "1234xyz")); - - assertEquals("diff_commonPrefix: Whole case.", 4, dmp.diff_commonPrefix("1234", "1234xyz")); - } - - @Test - public void testDiffCommonSuffix() { - // Detect any common suffix. - assertEquals("diff_commonSuffix: Null case.", 0, dmp.diff_commonSuffix("abc", "xyz")); - - assertEquals("diff_commonSuffix: Non-null case.", 4, dmp.diff_commonSuffix("abcdef1234", "xyz1234")); - - assertEquals("diff_commonSuffix: Whole case.", 4, dmp.diff_commonSuffix("1234", "xyz1234")); - } - - @Test - public void testDiffCommonOverlap() { - // Detect any suffix/prefix overlap. - assertEquals("diff_commonOverlap: Null case.", 0, dmp.diff_commonOverlap("", "abcd")); - - assertEquals("diff_commonOverlap: Whole case.", 3, dmp.diff_commonOverlap("abc", "abcd")); - - assertEquals("diff_commonOverlap: No overlap.", 0, dmp.diff_commonOverlap("123456", "abcd")); - - assertEquals("diff_commonOverlap: Overlap.", 3, dmp.diff_commonOverlap("123456xxx", "xxxabcd")); - - // Some overly clever languages (C#) may treat ligatures as equal to their - // component letters. E.g. U+FB01 == 'fi' - assertEquals("diff_commonOverlap: Unicode.", 0, dmp.diff_commonOverlap("fi", "\ufb01i")); - } - - @Test - public void testDiffHalfmatch() { - // Detect a halfmatch. - dmp.Diff_Timeout = 1; - assertNull("diff_halfMatch: No match #1.", dmp.diff_halfMatch("1234567890", "abcdef")); - - assertNull("diff_halfMatch: No match #2.", dmp.diff_halfMatch("12345", "23")); - - assertArrayEquals("diff_halfMatch: Single Match #1.", new String[] { "12", "90", "a", "z", "345678" }, - dmp.diff_halfMatch("1234567890", "a345678z")); - - assertArrayEquals("diff_halfMatch: Single Match #2.", new String[] { "a", "z", "12", "90", "345678" }, - dmp.diff_halfMatch("a345678z", "1234567890")); - - assertArrayEquals("diff_halfMatch: Single Match #3.", new String[] { "abc", "z", "1234", "0", "56789" }, - dmp.diff_halfMatch("abc56789z", "1234567890")); - - assertArrayEquals("diff_halfMatch: Single Match #4.", new String[] { "a", "xyz", "1", "7890", "23456" }, - dmp.diff_halfMatch("a23456xyz", "1234567890")); - - assertArrayEquals("diff_halfMatch: Multiple Matches #1.", new String[] { "12123", "123121", "a", "z", "1234123451234" }, - dmp.diff_halfMatch("121231234123451234123121", "a1234123451234z")); - - assertArrayEquals("diff_halfMatch: Multiple Matches #2.", new String[] { "", "-=-=-=-=-=", "x", "", "x-=-=-=-=-=-=-=" }, - dmp.diff_halfMatch("x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-=")); - - assertArrayEquals("diff_halfMatch: Multiple Matches #3.", new String[] { "-=-=-=-=-=", "", "", "y", "-=-=-=-=-=-=-=y" }, - dmp.diff_halfMatch("-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy")); - - // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy - assertArrayEquals("diff_halfMatch: Non-optimal halfmatch.", new String[] { "qHillo", "w", "x", "Hulloy", "HelloHe" }, - dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy")); - - dmp.Diff_Timeout = 0; - assertNull("diff_halfMatch: Optimal no halfmatch.", dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy")); - } - - @Test - public void testDiffLinesToChars() { - // Convert lines down to characters. - ArrayList tmpVector = new ArrayList(); - tmpVector.add(""); - tmpVector.add("alpha\n"); - tmpVector.add("beta\n"); - assertLinesToCharsResultEquals("diff_linesToChars: Shared lines.", - new LinesToCharsResult("\u0001\u0002\u0001", "\u0002\u0001\u0002", tmpVector), - dmp.diff_linesToChars("alpha\nbeta\nalpha\n", "beta\nalpha\nbeta\n")); - - tmpVector.clear(); - tmpVector.add(""); - tmpVector.add("alpha\r\n"); - tmpVector.add("beta\r\n"); - tmpVector.add("\r\n"); - assertLinesToCharsResultEquals("diff_linesToChars: Empty string and blank lines.", - new LinesToCharsResult("", "\u0001\u0002\u0003\u0003", tmpVector), dmp.diff_linesToChars("", "alpha\r\nbeta\r\n\r\n\r\n")); - - tmpVector.clear(); - tmpVector.add(""); - tmpVector.add("a"); - tmpVector.add("b"); - assertLinesToCharsResultEquals("diff_linesToChars: No linebreaks.", new LinesToCharsResult("\u0001", "\u0002", tmpVector), - dmp.diff_linesToChars("a", "b")); - - // More than 256 to reveal any 8-bit limitations. - int n = 300; - tmpVector.clear(); - StringBuilder lineList = new StringBuilder(); - StringBuilder charList = new StringBuilder(); - for (int x = 1; x < n + 1; x++) { - tmpVector.add(x + "\n"); - lineList.append(x + "\n"); - charList.append(String.valueOf((char) x)); - } - assertEquals("Test initialization fail #1.", n, tmpVector.size()); - String lines = lineList.toString(); - String chars = charList.toString(); - assertEquals("Test initialization fail #2.", n, chars.length()); - tmpVector.add(0, ""); - assertLinesToCharsResultEquals("diff_linesToChars: More than 256.", new LinesToCharsResult(chars, "", tmpVector), - dmp.diff_linesToChars(lines, "")); - } - - @Test - public void testDiffCharsToLines() { - // First check that Diff equality works. - assertTrue("diff_charsToLines: Equality #1.", new Diff(EQUAL, "a").equals(new Diff(EQUAL, "a"))); - - assertEquals("diff_charsToLines: Equality #2.", new Diff(EQUAL, "a"), new Diff(EQUAL, "a")); - - // Convert chars up to lines. - LinkedList diffs = diffList(new Diff(EQUAL, "\u0001\u0002\u0001"), new Diff(INSERT, "\u0002\u0001\u0002")); - ArrayList tmpVector = new ArrayList(); - tmpVector.add(""); - tmpVector.add("alpha\n"); - tmpVector.add("beta\n"); - dmp.diff_charsToLines(diffs, tmpVector); - assertEquals("diff_charsToLines: Shared lines.", diffList(new Diff(EQUAL, "alpha\nbeta\nalpha\n"), new Diff(INSERT, "beta\nalpha\nbeta\n")), - diffs); - - // More than 256 to reveal any 8-bit limitations. - int n = 300; - tmpVector.clear(); - StringBuilder lineList = new StringBuilder(); - StringBuilder charList = new StringBuilder(); - for (int x = 1; x < n + 1; x++) { - tmpVector.add(x + "\n"); - lineList.append(x + "\n"); - charList.append(String.valueOf((char) x)); - } - assertEquals("Test initialization fail #3.", n, tmpVector.size()); - String lines = lineList.toString(); - String chars = charList.toString(); - assertEquals("Test initialization fail #4.", n, chars.length()); - tmpVector.add(0, ""); - diffs = diffList(new Diff(DELETE, chars)); - dmp.diff_charsToLines(diffs, tmpVector); - assertEquals("diff_charsToLines: More than 256.", diffList(new Diff(DELETE, lines)), diffs); - } - - @Test - public void testDiffCleanupMerge() { - // Cleanup a messy diff. - LinkedList diffs = diffList(); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Null case.", diffList(), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(INSERT, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: No change case.", diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(INSERT, "c")), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(EQUAL, "b"), new Diff(EQUAL, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Merge equalities.", diffList(new Diff(EQUAL, "abc")), diffs); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(DELETE, "b"), new Diff(DELETE, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Merge deletions.", diffList(new Diff(DELETE, "abc")), diffs); - - diffs = diffList(new Diff(INSERT, "a"), new Diff(INSERT, "b"), new Diff(INSERT, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Merge insertions.", diffList(new Diff(INSERT, "abc")), diffs); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "b"), new Diff(DELETE, "c"), new Diff(INSERT, "d"), new Diff(EQUAL, "e"), - new Diff(EQUAL, "f")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Merge interweave.", diffList(new Diff(DELETE, "ac"), new Diff(INSERT, "bd"), new Diff(EQUAL, "ef")), diffs); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "abc"), new Diff(DELETE, "dc")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Prefix and suffix detection.", - diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "d"), new Diff(INSERT, "b"), new Diff(EQUAL, "c")), diffs); - - diffs = diffList(new Diff(EQUAL, "x"), new Diff(DELETE, "a"), new Diff(INSERT, "abc"), new Diff(DELETE, "dc"), new Diff(EQUAL, "y")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Prefix and suffix detection with equalities.", - diffList(new Diff(EQUAL, "xa"), new Diff(DELETE, "d"), new Diff(INSERT, "b"), new Diff(EQUAL, "cy")), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(INSERT, "ba"), new Diff(EQUAL, "c")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Slide edit left.", diffList(new Diff(INSERT, "ab"), new Diff(EQUAL, "ac")), diffs); - - diffs = diffList(new Diff(EQUAL, "c"), new Diff(INSERT, "ab"), new Diff(EQUAL, "a")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Slide edit right.", diffList(new Diff(EQUAL, "ca"), new Diff(INSERT, "ba")), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "b"), new Diff(EQUAL, "c"), new Diff(DELETE, "ac"), new Diff(EQUAL, "x")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Slide edit left recursive.", diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "acx")), diffs); - - diffs = diffList(new Diff(EQUAL, "x"), new Diff(DELETE, "ca"), new Diff(EQUAL, "c"), new Diff(DELETE, "b"), new Diff(EQUAL, "a")); - dmp.diff_cleanupMerge(diffs); - assertEquals("diff_cleanupMerge: Slide edit right recursive.", diffList(new Diff(EQUAL, "xca"), new Diff(DELETE, "cba")), diffs); - } - - @Test - public void testDiffCleanupSemanticLossless() { - // Slide diffs to match logical boundaries. - LinkedList diffs = diffList(); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Null case.", diffList(), diffs); - - diffs = diffList(new Diff(EQUAL, "AAA\r\n\r\nBBB"), new Diff(INSERT, "\r\nDDD\r\n\r\nBBB"), new Diff(EQUAL, "\r\nEEE")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Blank lines.", - diffList(new Diff(EQUAL, "AAA\r\n\r\n"), new Diff(INSERT, "BBB\r\nDDD\r\n\r\n"), new Diff(EQUAL, "BBB\r\nEEE")), diffs); - - diffs = diffList(new Diff(EQUAL, "AAA\r\nBBB"), new Diff(INSERT, " DDD\r\nBBB"), new Diff(EQUAL, " EEE")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Line boundaries.", - diffList(new Diff(EQUAL, "AAA\r\n"), new Diff(INSERT, "BBB DDD\r\n"), new Diff(EQUAL, "BBB EEE")), diffs); - - diffs = diffList(new Diff(EQUAL, "The c"), new Diff(INSERT, "ow and the c"), new Diff(EQUAL, "at.")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Word boundaries.", - diffList(new Diff(EQUAL, "The "), new Diff(INSERT, "cow and the "), new Diff(EQUAL, "cat.")), diffs); - - diffs = diffList(new Diff(EQUAL, "The-c"), new Diff(INSERT, "ow-and-the-c"), new Diff(EQUAL, "at.")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Alphanumeric boundaries.", - diffList(new Diff(EQUAL, "The-"), new Diff(INSERT, "cow-and-the-"), new Diff(EQUAL, "cat.")), diffs); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "a"), new Diff(EQUAL, "ax")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Hitting the start.", diffList(new Diff(DELETE, "a"), new Diff(EQUAL, "aax")), diffs); - - diffs = diffList(new Diff(EQUAL, "xa"), new Diff(DELETE, "a"), new Diff(EQUAL, "a")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Hitting the end.", diffList(new Diff(EQUAL, "xaa"), new Diff(DELETE, "a")), diffs); - - diffs = diffList(new Diff(EQUAL, "The xxx. The "), new Diff(INSERT, "zzz. The "), new Diff(EQUAL, "yyy.")); - dmp.diff_cleanupSemanticLossless(diffs); - assertEquals("diff_cleanupSemanticLossless: Sentence boundaries.", - diffList(new Diff(EQUAL, "The xxx."), new Diff(INSERT, " The zzz."), new Diff(EQUAL, " The yyy.")), diffs); - } - - @Test - public void testDiffCleanupSemantic() { - // Cleanup semantically trivial equalities. - LinkedList diffs = diffList(); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Null case.", diffList(), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "cd"), new Diff(EQUAL, "12"), new Diff(DELETE, "e")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: No elimination #1.", - diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "cd"), new Diff(EQUAL, "12"), new Diff(DELETE, "e")), diffs); - - diffs = diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "ABC"), new Diff(EQUAL, "1234"), new Diff(DELETE, "wxyz")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: No elimination #2.", - diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "ABC"), new Diff(EQUAL, "1234"), new Diff(DELETE, "wxyz")), diffs); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(EQUAL, "b"), new Diff(DELETE, "c")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Simple elimination.", diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "b")), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(EQUAL, "cd"), new Diff(DELETE, "e"), new Diff(EQUAL, "f"), new Diff(INSERT, "g")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Backpass elimination.", diffList(new Diff(DELETE, "abcdef"), new Diff(INSERT, "cdfg")), diffs); - - diffs = diffList(new Diff(INSERT, "1"), new Diff(EQUAL, "A"), new Diff(DELETE, "B"), new Diff(INSERT, "2"), new Diff(EQUAL, "_"), - new Diff(INSERT, "1"), new Diff(EQUAL, "A"), new Diff(DELETE, "B"), new Diff(INSERT, "2")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Multiple elimination.", diffList(new Diff(DELETE, "AB_AB"), new Diff(INSERT, "1A2_1A2")), diffs); - - diffs = diffList(new Diff(EQUAL, "The c"), new Diff(DELETE, "ow and the c"), new Diff(EQUAL, "at.")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Word boundaries.", - diffList(new Diff(EQUAL, "The "), new Diff(DELETE, "cow and the "), new Diff(EQUAL, "cat.")), diffs); - - diffs = diffList(new Diff(DELETE, "abcxx"), new Diff(INSERT, "xxdef")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: No overlap elimination.", diffList(new Diff(DELETE, "abcxx"), new Diff(INSERT, "xxdef")), diffs); - - diffs = diffList(new Diff(DELETE, "abcxxx"), new Diff(INSERT, "xxxdef")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Overlap elimination.", diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "xxx"), new Diff(INSERT, "def")), - diffs); - - diffs = diffList(new Diff(DELETE, "xxxabc"), new Diff(INSERT, "defxxx")); - dmp.diff_cleanupSemantic(diffs); - assertEquals("diff_cleanupSemantic: Reverse overlap elimination.", - diffList(new Diff(INSERT, "def"), new Diff(EQUAL, "xxx"), new Diff(DELETE, "abc")), diffs); - - diffs = diffList(new Diff(DELETE, "abcd1212"), new Diff(INSERT, "1212efghi"), new Diff(EQUAL, "----"), new Diff(DELETE, "A3"), - new Diff(INSERT, "3BC")); - dmp.diff_cleanupSemantic(diffs); - assertEquals( - "diff_cleanupSemantic: Two overlap eliminations.", diffList(new Diff(DELETE, "abcd"), new Diff(EQUAL, "1212"), - new Diff(INSERT, "efghi"), new Diff(EQUAL, "----"), new Diff(DELETE, "A"), new Diff(EQUAL, "3"), new Diff(INSERT, "BC")), - diffs); - } - - @Test - public void testDiffCleanupEfficiency() { - // Cleanup operationally trivial equalities. - dmp.Diff_EditCost = 4; - LinkedList diffs = diffList(); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: Null case.", diffList(), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: No elimination.", - diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")), - diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "xyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: Four-edit elimination.", diffList(new Diff(DELETE, "abxyzcd"), new Diff(INSERT, "12xyz34")), diffs); - - diffs = diffList(new Diff(INSERT, "12"), new Diff(EQUAL, "x"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: Three-edit elimination.", diffList(new Diff(DELETE, "xcd"), new Diff(INSERT, "12x34")), diffs); - - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "xy"), new Diff(INSERT, "34"), new Diff(EQUAL, "z"), - new Diff(DELETE, "cd"), new Diff(INSERT, "56")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: Backpass elimination.", diffList(new Diff(DELETE, "abxyzcd"), new Diff(INSERT, "12xy34z56")), diffs); - - dmp.Diff_EditCost = 5; - diffs = diffList(new Diff(DELETE, "ab"), new Diff(INSERT, "12"), new Diff(EQUAL, "wxyz"), new Diff(DELETE, "cd"), new Diff(INSERT, "34")); - dmp.diff_cleanupEfficiency(diffs); - assertEquals("diff_cleanupEfficiency: High cost elimination.", diffList(new Diff(DELETE, "abwxyzcd"), new Diff(INSERT, "12wxyz34")), diffs); - dmp.Diff_EditCost = 4; - } - - @Test - public void testDiffPrettyHtml() { - // Pretty print. - LinkedList diffs = diffList(new Diff(EQUAL, "a\n"), new Diff(DELETE, "b"), new Diff(INSERT, "c&d")); - assertEquals("diff_prettyHtml:", - "
<B>b</B>c&d", - dmp.diff_prettyHtml(diffs)); - } - - @Test - public void testDiffText() { - // Compute the source and destination texts. - LinkedList diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), - new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, " lazy")); - assertEquals("diff_text1:", "jumps over the lazy", dmp.diff_text1(diffs)); - assertEquals("diff_text2:", "jumped over a lazy", dmp.diff_text2(diffs)); - } - - @Test - public void testDiffDelta() { - // Convert a diff into delta string. - LinkedList diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), - new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, " lazy"), new Diff(INSERT, "old dog")); - String text1 = dmp.diff_text1(diffs); - assertEquals("diff_text1: Base text.", "jumps over the lazy", text1); - - String delta = dmp.diff_toDelta(diffs); - assertEquals("diff_toDelta:", "=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog", delta); - - // Convert delta string into a diff. - assertEquals("diff_fromDelta: Normal.", diffs, dmp.diff_fromDelta(text1, delta)); - - // Generates error (19 < 20). - try { - dmp.diff_fromDelta(text1 + "x", delta); - fail("diff_fromDelta: Too long."); - } catch (IllegalArgumentException ex) { - // Exception expected. - } - - // Generates error (19 > 18). - try { - dmp.diff_fromDelta(text1.substring(1), delta); - fail("diff_fromDelta: Too short."); - } catch (IllegalArgumentException ex) { - // Exception expected. - } - - // Generates error (%c3%xy invalid Unicode). - try { - dmp.diff_fromDelta("", "+%c3%xy"); - fail("diff_fromDelta: Invalid character."); - } catch (IllegalArgumentException ex) { - // Exception expected. - } - - // Test deltas with special characters. - diffs = diffList(new Diff(EQUAL, "\u0680 \000 \t %"), new Diff(DELETE, "\u0681 \001 \n ^"), new Diff(INSERT, "\u0682 \002 \\ |")); - text1 = dmp.diff_text1(diffs); - assertEquals("diff_text1: Unicode text.", "\u0680 \000 \t %\u0681 \001 \n ^", text1); - - delta = dmp.diff_toDelta(diffs); - assertEquals("diff_toDelta: Unicode.", "=7\t-7\t+%DA%82 %02 %5C %7C", delta); - - assertEquals("diff_fromDelta: Unicode.", diffs, dmp.diff_fromDelta(text1, delta)); - - // Verify pool of unchanged characters. - diffs = diffList(new Diff(INSERT, "A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # ")); - String text2 = dmp.diff_text2(diffs); - assertEquals("diff_text2: Unchanged characters.", "A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ", text2); - - delta = dmp.diff_toDelta(diffs); - assertEquals("diff_toDelta: Unchanged characters.", "+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ", delta); - - // Convert delta string into a diff. - assertEquals("diff_fromDelta: Unchanged characters.", diffs, dmp.diff_fromDelta("", delta)); - } - - @Test - public void testDiffXIndex() { - // Translate a location in text1 to text2. - LinkedList diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz")); - assertEquals("diff_xIndex: Translation on equality.", 5, dmp.diff_xIndex(diffs, 2)); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "1234"), new Diff(EQUAL, "xyz")); - assertEquals("diff_xIndex: Translation on deletion.", 1, dmp.diff_xIndex(diffs, 3)); - } - - @Test - public void testDiffLevenshtein() { - LinkedList diffs = diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz")); - assertEquals("diff_levenshtein: Levenshtein with trailing equality.", 4, dmp.diff_levenshtein(diffs)); - - diffs = diffList(new Diff(EQUAL, "xyz"), new Diff(DELETE, "abc"), new Diff(INSERT, "1234")); - assertEquals("diff_levenshtein: Levenshtein with leading equality.", 4, dmp.diff_levenshtein(diffs)); - - diffs = diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "xyz"), new Diff(INSERT, "1234")); - assertEquals("diff_levenshtein: Levenshtein with middle equality.", 7, dmp.diff_levenshtein(diffs)); - } - - @Test - public void testDiffBisect() { - // Normal. - String a = "cat"; - String b = "map"; - // 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. - LinkedList diffs = diffList(new Diff(DELETE, "c"), new Diff(INSERT, "m"), new Diff(EQUAL, "a"), new Diff(DELETE, "t"), - new Diff(INSERT, "p")); - assertEquals("diff_bisect: Normal.", diffs, dmp.diff_bisect(a, b, Long.MAX_VALUE)); - - // Timeout. - diffs = diffList(new Diff(DELETE, "cat"), new Diff(INSERT, "map")); - assertEquals("diff_bisect: Timeout.", diffs, dmp.diff_bisect(a, b, 0)); - } - - @Test - public void testDiffMain() { - // Perform a trivial diff. - LinkedList diffs = diffList(); - assertEquals("diff_main: Null case.", diffs, dmp.diff_main("", "", false)); - - diffs = diffList(new Diff(EQUAL, "abc")); - assertEquals("diff_main: Equality.", diffs, dmp.diff_main("abc", "abc", false)); - - diffs = diffList(new Diff(EQUAL, "ab"), new Diff(INSERT, "123"), new Diff(EQUAL, "c")); - assertEquals("diff_main: Simple insertion.", diffs, dmp.diff_main("abc", "ab123c", false)); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "123"), new Diff(EQUAL, "bc")); - assertEquals("diff_main: Simple deletion.", diffs, dmp.diff_main("a123bc", "abc", false)); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(INSERT, "123"), new Diff(EQUAL, "b"), new Diff(INSERT, "456"), new Diff(EQUAL, "c")); - assertEquals("diff_main: Two insertions.", diffs, dmp.diff_main("abc", "a123b456c", false)); - - diffs = diffList(new Diff(EQUAL, "a"), new Diff(DELETE, "123"), new Diff(EQUAL, "b"), new Diff(DELETE, "456"), new Diff(EQUAL, "c")); - assertEquals("diff_main: Two deletions.", diffs, dmp.diff_main("a123b456c", "abc", false)); - - // Perform a real diff. - // Switch off the timeout. - dmp.Diff_Timeout = 0; - diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "b")); - assertEquals("diff_main: Simple case #1.", diffs, dmp.diff_main("a", "b", false)); - - diffs = diffList(new Diff(DELETE, "Apple"), new Diff(INSERT, "Banana"), new Diff(EQUAL, "s are a"), new Diff(INSERT, "lso"), - new Diff(EQUAL, " fruit.")); - assertEquals("diff_main: Simple case #2.", diffs, dmp.diff_main("Apples are a fruit.", "Bananas are also fruit.", false)); - - diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "\u0680"), new Diff(EQUAL, "x"), new Diff(DELETE, "\t"), new Diff(INSERT, "\000")); - assertEquals("diff_main: Simple case #3.", diffs, dmp.diff_main("ax\t", "\u0680x\000", false)); - - diffs = diffList(new Diff(DELETE, "1"), new Diff(EQUAL, "a"), new Diff(DELETE, "y"), new Diff(EQUAL, "b"), new Diff(DELETE, "2"), - new Diff(INSERT, "xab")); - assertEquals("diff_main: Overlap #1.", diffs, dmp.diff_main("1ayb2", "abxab", false)); - - diffs = diffList(new Diff(INSERT, "xaxcx"), new Diff(EQUAL, "abc"), new Diff(DELETE, "y")); - assertEquals("diff_main: Overlap #2.", diffs, dmp.diff_main("abcy", "xaxcxabc", false)); - - diffs = diffList(new Diff(DELETE, "ABCD"), new Diff(EQUAL, "a"), new Diff(DELETE, "="), new Diff(INSERT, "-"), new Diff(EQUAL, "bcd"), - new Diff(DELETE, "="), new Diff(INSERT, "-"), new Diff(EQUAL, "efghijklmnopqrs"), new Diff(DELETE, "EFGHIJKLMNOefg")); - assertEquals("diff_main: Overlap #3.", diffs, dmp.diff_main("ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg", "a-bcd-efghijklmnopqrs", false)); - - diffs = diffList(new Diff(INSERT, " "), new Diff(EQUAL, "a"), new Diff(INSERT, "nd"), new Diff(EQUAL, " [[Pennsylvania]]"), - new Diff(DELETE, " and [[New")); - assertEquals("diff_main: Large equality.", diffs, dmp.diff_main("a [[Pennsylvania]] and [[New", " and [[Pennsylvania]]", false)); - - dmp.Diff_Timeout = 0.1f; // 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 x = 0; x < 10; x++) { - a = a + a; - b = b + b; - } - long startTime = System.currentTimeMillis(); - dmp.diff_main(a, b); - long endTime = System.currentTimeMillis(); - // Test that we took at least the timeout period. - assertTrue("diff_main: Timeout min.", dmp.Diff_Timeout * 1000 <= endTime - startTime); - // Test that we didn't take forever (be forgiving). - // Theoretically this test could fail very occasionally if the - // OS task swaps or locks up for a second at the wrong moment. - assertTrue("diff_main: Timeout max.", dmp.Diff_Timeout * 1000 * 2 > endTime - startTime); - dmp.Diff_Timeout = 0; - - // Test the linemode speedup. - // Must be long to pass the 100 char cutoff. - a = "1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n"; - b = "abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n"; - assertEquals("diff_main: Simple line-mode.", dmp.diff_main(a, b, true), dmp.diff_main(a, b, false)); - - a = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; - b = "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"; - assertEquals("diff_main: Single line-mode.", dmp.diff_main(a, b, true), dmp.diff_main(a, b, false)); - - a = "1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n"; - b = "abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n"; - String[] texts_linemode = diff_rebuildtexts(dmp.diff_main(a, b, true)); - String[] texts_textmode = diff_rebuildtexts(dmp.diff_main(a, b, false)); - assertArrayEquals("diff_main: Overlap line-mode.", texts_textmode, texts_linemode); - - // Test null inputs. - try { - dmp.diff_main(null, null); - fail("diff_main: Null inputs."); - } catch (IllegalArgumentException ex) { - // Error expected. - } - } - - // MATCH TEST FUNCTIONS - - @Test - public void testMatchAlphabet() { - // Initialise the bitmasks for Bitap. - Map bitmask; - bitmask = new HashMap(); - bitmask.put('a', 4); - bitmask.put('b', 2); - bitmask.put('c', 1); - assertEquals("match_alphabet: Unique.", bitmask, dmp.match_alphabet("abc")); - - bitmask = new HashMap(); - bitmask.put('a', 37); - bitmask.put('b', 18); - bitmask.put('c', 8); - assertEquals("match_alphabet: Duplicates.", bitmask, dmp.match_alphabet("abcaba")); - } - - @Test - public void testMatchBitap() { - // Bitap algorithm. - dmp.Match_Distance = 100; - dmp.Match_Threshold = 0.5f; - assertEquals("match_bitap: Exact match #1.", 5, dmp.match_bitap("abcdefghijk", "fgh", 5)); - - assertEquals("match_bitap: Exact match #2.", 5, dmp.match_bitap("abcdefghijk", "fgh", 0)); - - assertEquals("match_bitap: Fuzzy match #1.", 4, dmp.match_bitap("abcdefghijk", "efxhi", 0)); - - assertEquals("match_bitap: Fuzzy match #2.", 2, dmp.match_bitap("abcdefghijk", "cdefxyhijk", 5)); - - assertEquals("match_bitap: Fuzzy match #3.", -1, dmp.match_bitap("abcdefghijk", "bxy", 1)); - - assertEquals("match_bitap: Overflow.", 2, dmp.match_bitap("123456789xx0", "3456789x0", 2)); - - assertEquals("match_bitap: Before start match.", 0, dmp.match_bitap("abcdef", "xxabc", 4)); - - assertEquals("match_bitap: Beyond end match.", 3, dmp.match_bitap("abcdef", "defyy", 4)); - - assertEquals("match_bitap: Oversized pattern.", 0, dmp.match_bitap("abcdef", "xabcdefy", 0)); - - dmp.Match_Threshold = 0.4f; - assertEquals("match_bitap: Threshold #1.", 4, dmp.match_bitap("abcdefghijk", "efxyhi", 1)); - - dmp.Match_Threshold = 0.3f; - assertEquals("match_bitap: Threshold #2.", -1, dmp.match_bitap("abcdefghijk", "efxyhi", 1)); - - dmp.Match_Threshold = 0.0f; - assertEquals("match_bitap: Threshold #3.", 1, dmp.match_bitap("abcdefghijk", "bcdef", 1)); - - dmp.Match_Threshold = 0.5f; - assertEquals("match_bitap: Multiple select #1.", 0, dmp.match_bitap("abcdexyzabcde", "abccde", 3)); - - assertEquals("match_bitap: Multiple select #2.", 8, dmp.match_bitap("abcdexyzabcde", "abccde", 5)); - - dmp.Match_Distance = 10; // Strict location. - assertEquals("match_bitap: Distance test #1.", -1, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24)); - - assertEquals("match_bitap: Distance test #2.", 0, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdxxefg", 1)); - - dmp.Match_Distance = 1000; // Loose location. - assertEquals("match_bitap: Distance test #3.", 0, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24)); - } - - @Test - public void testMatchMain() { - // Full match. - assertEquals("match_main: Equality.", 0, dmp.match_main("abcdef", "abcdef", 1000)); - - assertEquals("match_main: Null text.", -1, dmp.match_main("", "abcdef", 1)); - - assertEquals("match_main: Null pattern.", 3, dmp.match_main("abcdef", "", 3)); - - assertEquals("match_main: Exact match.", 3, dmp.match_main("abcdef", "de", 3)); - - assertEquals("match_main: Beyond end match.", 3, dmp.match_main("abcdef", "defy", 4)); - - assertEquals("match_main: Oversized pattern.", 0, dmp.match_main("abcdef", "abcdefy", 0)); - - dmp.Match_Threshold = 0.7f; - assertEquals("match_main: Complex match.", 4, dmp.match_main("I am the very model of a modern major general.", " that berry ", 5)); - dmp.Match_Threshold = 0.5f; - - // Test null inputs. - try { - dmp.match_main(null, null, 0); - fail("match_main: Null inputs."); - } catch (IllegalArgumentException ex) { - // Error expected. - } - } - - // PATCH TEST FUNCTIONS - - @Test - public void testPatchObj() { - // Patch Object. - Patch p = new Patch(); - p.start1 = 20; - p.start2 = 21; - p.length1 = 18; - p.length2 = 17; - p.diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), new Diff(DELETE, "the"), - new Diff(INSERT, "a"), new Diff(EQUAL, "\nlaz")); - String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n"; - assertEquals("Patch: toString.", strp, p.toString()); - } - - @Test - public void testPatchFromText() { - assertTrue("patch_fromText: #0.", dmp.patch_fromText("").isEmpty()); - - String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n"; - assertEquals("patch_fromText: #1.", strp, dmp.patch_fromText(strp).get(0).toString()); - - assertEquals("patch_fromText: #2.", "@@ -1 +1 @@\n-a\n+b\n", dmp.patch_fromText("@@ -1 +1 @@\n-a\n+b\n").get(0).toString()); - - assertEquals("patch_fromText: #3.", "@@ -1,3 +0,0 @@\n-abc\n", dmp.patch_fromText("@@ -1,3 +0,0 @@\n-abc\n").get(0).toString()); - - assertEquals("patch_fromText: #4.", "@@ -0,0 +1,3 @@\n+abc\n", dmp.patch_fromText("@@ -0,0 +1,3 @@\n+abc\n").get(0).toString()); - - // Generates error. - try { - dmp.patch_fromText("Bad\nPatch\n"); - fail("patch_fromText: #5."); - } catch (IllegalArgumentException ex) { - // Exception expected. - } - } - - @Test - public void testPatchToText() { - String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n"; - List patches; - patches = dmp.patch_fromText(strp); - assertEquals("patch_toText: Single.", strp, dmp.patch_toText(patches)); - - strp = "@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n"; - patches = dmp.patch_fromText(strp); - assertEquals("patch_toText: Dual.", strp, dmp.patch_toText(patches)); - } - - @Test - public void testPatchAddContext() { - dmp.Patch_Margin = 4; - Patch p; - p = dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n").get(0); - dmp.patch_addContext(p, "The quick brown fox jumps over the lazy dog."); - assertEquals("patch_addContext: Simple case.", "@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n", p.toString()); - - p = dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n").get(0); - dmp.patch_addContext(p, "The quick brown fox jumps."); - assertEquals("patch_addContext: Not enough trailing context.", "@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n", p.toString()); - - p = dmp.patch_fromText("@@ -3 +3,2 @@\n-e\n+at\n").get(0); - dmp.patch_addContext(p, "The quick brown fox jumps."); - assertEquals("patch_addContext: Not enough leading context.", "@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n", p.toString()); - - p = dmp.patch_fromText("@@ -3 +3,2 @@\n-e\n+at\n").get(0); - dmp.patch_addContext(p, "The quick brown fox jumps. The quick brown fox crashes."); - assertEquals("patch_addContext: Ambiguity.", "@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n", p.toString()); - } - - @SuppressWarnings("deprecation") - @Test - public void testPatchMake() { - LinkedList patches; - patches = dmp.patch_make("", ""); - assertEquals("patch_make: Null case.", "", dmp.patch_toText(patches)); - - 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"; - // The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context. - patches = dmp.patch_make(text2, text1); - assertEquals("patch_make: Text2+Text1 inputs.", expectedPatch, dmp.patch_toText(patches)); - - 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); - assertEquals("patch_make: Text1+Text2 inputs.", expectedPatch, dmp.patch_toText(patches)); - - LinkedList diffs = dmp.diff_main(text1, text2, false); - patches = dmp.patch_make(diffs); - assertEquals("patch_make: Diff input.", expectedPatch, dmp.patch_toText(patches)); - - patches = dmp.patch_make(text1, diffs); - assertEquals("patch_make: Text1+Diff inputs.", expectedPatch, dmp.patch_toText(patches)); - - patches = dmp.patch_make(text1, text2, diffs); - assertEquals("patch_make: Text1+Text2+Diff inputs (deprecated).", expectedPatch, dmp.patch_toText(patches)); - - patches = dmp.patch_make("`1234567890-=[]\\;',./", "~!@#$%^&*()_+{}|:\"<>?"); - assertEquals("patch_toText: Character encoding.", - "@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n", dmp.patch_toText(patches)); - - diffs = diffList(new Diff(DELETE, "`1234567890-=[]\\;',./"), new Diff(INSERT, "~!@#$%^&*()_+{}|:\"<>?")); - assertEquals("patch_fromText: Character decoding.", diffs, - dmp.patch_fromText("@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n").get(0).diffs); - - text1 = ""; - for (int x = 0; x < 100; x++) { - text1 += "abcdef"; - } - text2 = text1 + "123"; - expectedPatch = "@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n"; - patches = dmp.patch_make(text1, text2); - assertEquals("patch_make: Long string with repeats.", expectedPatch, dmp.patch_toText(patches)); - - // Test null inputs. - try { - dmp.patch_make(null); - fail("patch_make: Null inputs."); - } catch (IllegalArgumentException ex) { - // Error expected. - } - } - - @Test - public void testPatchSplitMax() { - // Assumes that Match_MaxBits is 32. - LinkedList patches; - patches = dmp.patch_make("abcdefghijklmnopqrstuvwxyz01234567890", "XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0"); - dmp.patch_splitMax(patches); - assertEquals("patch_splitMax: #1.", - "@@ -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)); - - patches = dmp.patch_make("abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz", "abcdefuvwxyz"); - String oldToText = dmp.patch_toText(patches); - dmp.patch_splitMax(patches); - assertEquals("patch_splitMax: #2.", oldToText, dmp.patch_toText(patches)); - - patches = dmp.patch_make("1234567890123456789012345678901234567890123456789012345678901234567890", "abc"); - dmp.patch_splitMax(patches); - assertEquals("patch_splitMax: #3.", - "@@ -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)); - - 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); - assertEquals("patch_splitMax: #4.", - "@@ -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)); - } - - @Test - public void testPatchAddPadding() { - LinkedList patches; - patches = dmp.patch_make("", "test"); - assertEquals("patch_addPadding: Both edges full.", "@@ -0,0 +1,4 @@\n+test\n", dmp.patch_toText(patches)); - dmp.patch_addPadding(patches); - assertEquals("patch_addPadding: Both edges full.", "@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n", dmp.patch_toText(patches)); - - patches = dmp.patch_make("XY", "XtestY"); - assertEquals("patch_addPadding: Both edges partial.", "@@ -1,2 +1,6 @@\n X\n+test\n Y\n", dmp.patch_toText(patches)); - dmp.patch_addPadding(patches); - assertEquals("patch_addPadding: Both edges partial.", "@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n", dmp.patch_toText(patches)); - - patches = dmp.patch_make("XXXXYYYY", "XXXXtestYYYY"); - assertEquals("patch_addPadding: Both edges none.", "@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n", dmp.patch_toText(patches)); - dmp.patch_addPadding(patches); - assertEquals("patch_addPadding: Both edges none.", "@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n", dmp.patch_toText(patches)); - } - - @Test - public void testPatchApply() { - dmp.Match_Distance = 1000; - dmp.Match_Threshold = 0.5f; - dmp.Patch_DeleteThreshold = 0.5f; - LinkedList patches; - patches = dmp.patch_make("", ""); - Object[] results = dmp.patch_apply(patches, "Hello world."); - boolean[] boolArray = (boolean[]) results[1]; - String resultStr = results[0] + "\t" + boolArray.length; - assertEquals("patch_apply: Null case.", "Hello world.\t0", resultStr); - - 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 = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Exact match.", "That quick brown fox jumped over a lazy dog.\ttrue\ttrue", resultStr); - - results = dmp.patch_apply(patches, "The quick red rabbit jumps over the tired tiger."); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Partial match.", "That quick red rabbit jumped over a tired tiger.\ttrue\ttrue", resultStr); - - results = dmp.patch_apply(patches, "I am the very model of a modern major general."); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Failed match.", "I am the very model of a modern major general.\tfalse\tfalse", resultStr); - - patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); - results = dmp.patch_apply(patches, "x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Big delete, small change.", "xabcy\ttrue\ttrue", resultStr); - - patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); - results = dmp.patch_apply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Big delete, big change 1.", - "xabc12345678901234567890---------------++++++++++---------------12345678901234567890y\tfalse\ttrue", resultStr); - - dmp.Patch_DeleteThreshold = 0.6f; - patches = dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy"); - results = dmp.patch_apply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Big delete, big change 2.", "xabcy\ttrue\ttrue", resultStr); - dmp.Patch_DeleteThreshold = 0.5f; - - // Compensate for failed patch. - dmp.Match_Threshold = 0.0f; - dmp.Match_Distance = 0; - patches = dmp.patch_make("abcdefghijklmnopqrstuvwxyz--------------------1234567890", - "abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890"); - results = dmp.patch_apply(patches, "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0] + "\t" + boolArray[1]; - assertEquals("patch_apply: Compensate for failed patch.", "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890\tfalse\ttrue", - resultStr); - dmp.Match_Threshold = 0.5f; - dmp.Match_Distance = 1000; - - patches = dmp.patch_make("", "test"); - String patchStr = dmp.patch_toText(patches); - dmp.patch_apply(patches, ""); - assertEquals("patch_apply: No side effects.", patchStr, dmp.patch_toText(patches)); - - patches = dmp.patch_make("The quick brown fox jumps over the lazy dog.", "Woof"); - patchStr = dmp.patch_toText(patches); - dmp.patch_apply(patches, "The quick brown fox jumps over the lazy dog."); - assertEquals("patch_apply: No side effects with major delete.", patchStr, dmp.patch_toText(patches)); - - patches = dmp.patch_make("", "test"); - results = dmp.patch_apply(patches, ""); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0]; - assertEquals("patch_apply: Edge exact match.", "test\ttrue", resultStr); - - patches = dmp.patch_make("XY", "XtestY"); - results = dmp.patch_apply(patches, "XY"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0]; - assertEquals("patch_apply: Near edge exact match.", "XtestY\ttrue", resultStr); - - patches = dmp.patch_make("y", "y123"); - results = dmp.patch_apply(patches, "x"); - boolArray = (boolean[]) results[1]; - resultStr = results[0] + "\t" + boolArray[0]; - assertEquals("patch_apply: Edge partial match.", "x123\ttrue", resultStr); - } - - private static void assertEquals(String error_msg, Object a, Object b) { - if (!a.toString().equals(b.toString())) { - throw new Error("assertEquals fail:\n Expected: " + a + "\n Actual: " + b + "\n" + error_msg); - } - } - - private static void assertTrue(String error_msg, boolean a) { - if (!a) { - throw new Error("assertTrue fail: " + error_msg); - } - } - - private static void assertNull(String error_msg, Object n) { - if (n != null) { - throw new Error("assertNull fail: " + error_msg); - } - } - - private static void fail(String error_msg) { - throw new Error("Fail: " + error_msg); - } - - private static void assertArrayEquals(String error_msg, Object[] a, Object[] b) { - List list_a = Arrays.asList(a); - List list_b = Arrays.asList(b); - assertEquals(error_msg, list_a, list_b); - } - - private static void assertLinesToCharsResultEquals(String error_msg, LinesToCharsResult a, LinesToCharsResult b) { - assertEquals(error_msg, a.chars1, b.chars1); - assertEquals(error_msg, a.chars2, b.chars2); - assertEquals(error_msg, a.lineArray, b.lineArray); - } - - // Construct the two texts which made up the diff originally. - private static String[] diff_rebuildtexts(LinkedList diffs) { - String[] text = { "", "" }; - for (Diff myDiff : diffs) { - if (myDiff.operation != diff_match_patch.Operation.INSERT) { - text[0] += myDiff.text; - } - if (myDiff.operation != diff_match_patch.Operation.DELETE) { - text[1] += myDiff.text; - } - } - return text; - } - - // Private function for quickly building lists of diffs. - private static LinkedList diffList(Diff... diffs) { - LinkedList myDiffList = new LinkedList(); - for (Diff myDiff : diffs) { - myDiffList.add(myDiff); - } - return myDiffList; - } -} diff --git a/java/tests/name/fraser/neil/plaintext/diff_match_patch_test.java b/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java similarity index 97% rename from java/tests/name/fraser/neil/plaintext/diff_match_patch_test.java rename to java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java index a15e504d..a2f56bf9 100644 --- a/java/tests/name/fraser/neil/plaintext/diff_match_patch_test.java +++ b/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java @@ -37,9 +37,11 @@ import name.fraser.neil.plaintext.diff_match_patch.LinesToCharsResult; import name.fraser.neil.plaintext.diff_match_patch.Patch; +import org.junit.Test; + public class diff_match_patch_test { - private static diff_match_patch dmp; + private static diff_match_patch dmp = new diff_match_patch(); private static diff_match_patch.Operation DELETE = diff_match_patch.Operation.DELETE; private static diff_match_patch.Operation EQUAL = diff_match_patch.Operation.EQUAL; private static diff_match_patch.Operation INSERT = diff_match_patch.Operation.INSERT; @@ -47,8 +49,8 @@ public class diff_match_patch_test { // DIFF TEST FUNCTIONS - - public static void testDiffCommonPrefix() { + @Test + public void testDiffCommonPrefix() { // Detect any common prefix. assertEquals("diff_commonPrefix: Null case.", 0, dmp.diff_commonPrefix("abc", "xyz")); @@ -57,7 +59,8 @@ public static void testDiffCommonPrefix() { assertEquals("diff_commonPrefix: Whole case.", 4, dmp.diff_commonPrefix("1234", "1234xyz")); } - public static void testDiffCommonSuffix() { + @Test + public void testDiffCommonSuffix() { // Detect any common suffix. assertEquals("diff_commonSuffix: Null case.", 0, dmp.diff_commonSuffix("abc", "xyz")); @@ -66,7 +69,8 @@ public static void testDiffCommonSuffix() { assertEquals("diff_commonSuffix: Whole case.", 4, dmp.diff_commonSuffix("1234", "xyz1234")); } - public static void testDiffCommonOverlap() { + @Test + public void testDiffCommonOverlap() { // Detect any suffix/prefix overlap. assertEquals("diff_commonOverlap: Null case.", 0, dmp.diff_commonOverlap("", "abcd")); @@ -81,7 +85,8 @@ public static void testDiffCommonOverlap() { assertEquals("diff_commonOverlap: Unicode.", 0, dmp.diff_commonOverlap("fi", "\ufb01i")); } - public static void testDiffHalfmatch() { + @Test + public void testDiffHalfmatch() { // Detect a halfmatch. dmp.Diff_Timeout = 1; assertNull("diff_halfMatch: No match #1.", dmp.diff_halfMatch("1234567890", "abcdef")); @@ -109,7 +114,8 @@ public static void testDiffHalfmatch() { assertNull("diff_halfMatch: Optimal no halfmatch.", dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy")); } - public static void testDiffLinesToChars() { + @Test + public void testDiffLinesToChars() { // Convert lines down to characters. ArrayList tmpVector = new ArrayList(); tmpVector.add(""); @@ -148,7 +154,8 @@ public static void testDiffLinesToChars() { assertLinesToCharsResultEquals("diff_linesToChars: More than 256.", new LinesToCharsResult(chars, "", tmpVector), dmp.diff_linesToChars(lines, "")); } - public static void testDiffCharsToLines() { + @Test + public void testDiffCharsToLines() { // First check that Diff equality works. assertTrue("diff_charsToLines: Equality #1.", new Diff(EQUAL, "a").equals(new Diff(EQUAL, "a"))); @@ -194,7 +201,8 @@ public static void testDiffCharsToLines() { assertEquals("diff_charsToLines: More than 65536.", chars, diffs.getFirst().text); } - public static void testDiffCleanupMerge() { + @Test + public void testDiffCleanupMerge() { // Cleanup a messy diff. LinkedList diffs = diffList(); dmp.diff_cleanupMerge(diffs); @@ -245,7 +253,8 @@ public static void testDiffCleanupMerge() { assertEquals("diff_cleanupMerge: Slide edit right recursive.", diffList(new Diff(EQUAL, "xca"), new Diff(DELETE, "cba")), diffs); } - public static void testDiffCleanupSemanticLossless() { + @Test + public void testDiffCleanupSemanticLossless() { // Slide diffs to match logical boundaries. LinkedList diffs = diffList(); dmp.diff_cleanupSemanticLossless(diffs); @@ -280,7 +289,8 @@ public static void testDiffCleanupSemanticLossless() { assertEquals("diff_cleanupSemanticLossless: Sentence boundaries.", diffList(new Diff(EQUAL, "The xxx."), new Diff(INSERT, " The zzz."), new Diff(EQUAL, " The yyy.")), diffs); } - public static void testDiffCleanupSemantic() { + @Test + public void testDiffCleanupSemantic() { // Cleanup semantically trivial equalities. LinkedList diffs = diffList(); dmp.diff_cleanupSemantic(diffs); @@ -327,7 +337,8 @@ public static void testDiffCleanupSemantic() { assertEquals("diff_cleanupSemantic: Two overlap eliminations.", diffList(new Diff(DELETE, "abcd"), new Diff(EQUAL, "1212"), new Diff(INSERT, "efghi"), new Diff(EQUAL, "----"), new Diff(DELETE, "A"), new Diff(EQUAL, "3"), new Diff(INSERT, "BC")), diffs); } - public static void testDiffCleanupEfficiency() { + @Test + public void testDiffCleanupEfficiency() { // Cleanup operationally trivial equalities. dmp.Diff_EditCost = 4; LinkedList diffs = diffList(); @@ -357,20 +368,23 @@ public static void testDiffCleanupEfficiency() { dmp.Diff_EditCost = 4; } - public static void testDiffPrettyHtml() { + @Test + public void testDiffPrettyHtml() { // Pretty print. LinkedList diffs = diffList(new Diff(EQUAL, "a\n"), new Diff(DELETE, "b"), new Diff(INSERT, "c&d")); assertEquals("diff_prettyHtml:", "
<B>b</B>c&d", dmp.diff_prettyHtml(diffs)); } - public static void testDiffText() { + @Test + public void testDiffText() { // Compute the source and destination texts. LinkedList diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, " lazy")); assertEquals("diff_text1:", "jumps over the lazy", dmp.diff_text1(diffs)); assertEquals("diff_text2:", "jumped over a lazy", dmp.diff_text2(diffs)); } - public static void testDiffDelta() { + @Test + public void testDiffDelta() { // Convert a diff into delta string. LinkedList diffs = diffList(new Diff(EQUAL, "jump"), new Diff(DELETE, "s"), new Diff(INSERT, "ed"), new Diff(EQUAL, " over "), new Diff(DELETE, "the"), new Diff(INSERT, "a"), new Diff(EQUAL, " lazy"), new Diff(INSERT, "old dog")); String text1 = dmp.diff_text1(diffs); @@ -428,7 +442,8 @@ public static void testDiffDelta() { assertEquals("diff_fromDelta: Unchanged characters.", diffs, dmp.diff_fromDelta("", delta)); } - public static void testDiffXIndex() { + @Test + public void testDiffXIndex() { // Translate a location in text1 to text2. LinkedList diffs = diffList(new Diff(DELETE, "a"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz")); assertEquals("diff_xIndex: Translation on equality.", 5, dmp.diff_xIndex(diffs, 2)); @@ -437,7 +452,8 @@ public static void testDiffXIndex() { assertEquals("diff_xIndex: Translation on deletion.", 1, dmp.diff_xIndex(diffs, 3)); } - public static void testDiffLevenshtein() { + @Test + public void testDiffLevenshtein() { LinkedList diffs = diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz")); assertEquals("diff_levenshtein: Levenshtein with trailing equality.", 4, dmp.diff_levenshtein(diffs)); @@ -448,7 +464,8 @@ public static void testDiffLevenshtein() { assertEquals("diff_levenshtein: Levenshtein with middle equality.", 7, dmp.diff_levenshtein(diffs)); } - public static void testDiffBisect() { + @Test + public void testDiffBisect() { // Normal. String a = "cat"; String b = "map"; @@ -463,7 +480,8 @@ public static void testDiffBisect() { assertEquals("diff_bisect: Timeout.", diffs, dmp.diff_bisect(a, b, 0)); } - public static void testDiffMain() { + @Test + public void testDiffMain() { // Perform a trivial diff. LinkedList diffs = diffList(); assertEquals("diff_main: Null case.", diffs, dmp.diff_main("", "", false)); @@ -555,7 +573,8 @@ public static void testDiffMain() { // MATCH TEST FUNCTIONS - public static void testMatchAlphabet() { + @Test + public void testMatchAlphabet() { // Initialise the bitmasks for Bitap. Map bitmask; bitmask = new HashMap(); @@ -567,7 +586,8 @@ public static void testMatchAlphabet() { assertEquals("match_alphabet: Duplicates.", bitmask, dmp.match_alphabet("abcaba")); } - public static void testMatchBitap() { + @Test + public void testMatchBitap() { // Bitap algorithm. dmp.Match_Distance = 100; dmp.Match_Threshold = 0.5f; @@ -612,7 +632,8 @@ public static void testMatchBitap() { assertEquals("match_bitap: Distance test #3.", 0, dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24)); } - public static void testMatchMain() { + @Test + public void testMatchMain() { // Full match. assertEquals("match_main: Equality.", 0, dmp.match_main("abcdef", "abcdef", 1000)); @@ -643,7 +664,8 @@ public static void testMatchMain() { // PATCH TEST FUNCTIONS - public static void testPatchObj() { + @Test + public void testPatchObj() { // Patch Object. Patch p = new Patch(); p.start1 = 20; @@ -655,7 +677,8 @@ public static void testPatchObj() { assertEquals("Patch: toString.", strp, p.toString()); } - public static void testPatchFromText() { + @Test + public void testPatchFromText() { assertTrue("patch_fromText: #0.", dmp.patch_fromText("").isEmpty()); String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n"; @@ -676,7 +699,8 @@ public static void testPatchFromText() { } } - public static void testPatchToText() { + @Test + public void testPatchToText() { String strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n"; List patches; patches = dmp.patch_fromText(strp); @@ -687,7 +711,8 @@ public static void testPatchToText() { assertEquals("patch_toText: Dual.", strp, dmp.patch_toText(patches)); } - public static void testPatchAddContext() { + @Test + public void testPatchAddContext() { dmp.Patch_Margin = 4; Patch p; p = dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n").get(0); @@ -707,8 +732,9 @@ public static void testPatchAddContext() { assertEquals("patch_addContext: Ambiguity.", "@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n", p.toString()); } + @Test @SuppressWarnings("deprecation") - public static void testPatchMake() { + public void testPatchMake() { LinkedList patches; patches = dmp.patch_make("", ""); assertEquals("patch_make: Null case.", "", dmp.patch_toText(patches)); @@ -758,7 +784,8 @@ public static void testPatchMake() { } } - public static void testPatchSplitMax() { + @Test + public void testPatchSplitMax() { // Assumes that Match_MaxBits is 32. LinkedList patches; patches = dmp.patch_make("abcdefghijklmnopqrstuvwxyz01234567890", "XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0"); @@ -779,7 +806,8 @@ public static void testPatchSplitMax() { assertEquals("patch_splitMax: #4.", "@@ -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)); } - public static void testPatchAddPadding() { + @Test + public void testPatchAddPadding() { LinkedList patches; patches = dmp.patch_make("", "test"); assertEquals("patch_addPadding: Both edges full.", "@@ -0,0 +1,4 @@\n+test\n", dmp.patch_toText(patches)); @@ -797,7 +825,8 @@ public static void testPatchAddPadding() { assertEquals("patch_addPadding: Both edges none.", "@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n", dmp.patch_toText(patches)); } - public static void testPatchApply() { + @Test + public void testPatchApply() { dmp.Match_Distance = 1000; dmp.Match_Threshold = 0.5f; dmp.Patch_DeleteThreshold = 0.5f; @@ -979,4 +1008,4 @@ public static void main(String args[]) { System.out.println("All tests passed."); } -} +} \ No newline at end of file From c3a3c4ed2ffc83b7607d18f7bec18cc5dacd2de1 Mon Sep 17 00:00:00 2001 From: Santhosh Kumar Date: Wed, 23 May 2018 09:17:32 -0700 Subject: [PATCH 10/10] Remove the main method from test class --- .../neil/plaintext/diff_match_patch_test.java | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java b/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java index a2f56bf9..d189c6ee 100644 --- a/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java +++ b/java/src/test/java/name/fraser/neil/plaintext/diff_match_patch_test.java @@ -971,41 +971,4 @@ private static LinkedList diffList(Diff... diffs) { } return myDiffList; } - - public static void main(String args[]) { - dmp = new diff_match_patch(); - - testDiffCommonPrefix(); - testDiffCommonSuffix(); - testDiffCommonOverlap(); - testDiffHalfmatch(); - testDiffLinesToChars(); - testDiffCharsToLines(); - testDiffCleanupMerge(); - testDiffCleanupSemanticLossless(); - testDiffCleanupSemantic(); - testDiffCleanupEfficiency(); - testDiffPrettyHtml(); - testDiffText(); - testDiffDelta(); - testDiffXIndex(); - testDiffLevenshtein(); - testDiffBisect(); - testDiffMain(); - - testMatchAlphabet(); - testMatchBitap(); - testMatchMain(); - - testPatchObj(); - testPatchFromText(); - testPatchToText(); - testPatchAddContext(); - testPatchMake(); - testPatchSplitMax(); - testPatchAddPadding(); - testPatchApply(); - - System.out.println("All tests passed."); - } } \ No newline at end of file