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/ diff --git a/java/pom.xml b/java/pom.xml new file mode 100644 index 00000000..ee282238 --- /dev/null +++ b/java/pom.xml @@ -0,0 +1,132 @@ +<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>com.google</groupId> + <artifactId>diff-match-patch</artifactId> + <version>1.0.0</version> + <packaging>jar</packaging> + + <properties> + <java-version>1.6</java-version> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <junit.version>4.11</junit.version> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.6.2</version> + <configuration> + <source>${java-version}</source> + <target>${java-version}</target> + <showDeprecation>true</showDeprecation> + <showWarnings>true</showWarnings> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-source-plugin</artifactId> + <version>3.0.1</version> + <executions> + <execution> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.10.4</version> + <configuration> + <excludePackageNames>*.internal.*</excludePackageNames> + <failOnError>false</failOnError> + <additionalparam>-Xdoclint:none</additionalparam> + </configuration> + <executions> + <execution> + <goals> + <goal>jar</goal> + </goals> + <inherited>true</inherited> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>2.6</version> + <configuration> + <useDefaultManifestFile>true</useDefaultManifestFile> + <archive> + <index>true</index> + <manifest> + <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + </archive> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.21.0</version> + <configuration> + <surefire.useFile>false</surefire.useFile> + <includes> + <include>**/diff_match_patch_test.java</include> + <include>**/*Test</include> + </includes> + </configuration> + </plugin> + </plugins> + </build> + + <name>Google Diff Match and Patch</name> + <url>https://github.com/google/diff-match-patch</url> + <description>Diff Match Patch is a high-performance library in multiple languages that manipulates plain text.</description> + <inceptionYear>2006</inceptionYear> + <organization> + <url>https://www.google.com</url> + <name>Google Inc</name> + </organization> + <scm> + <url>https://github.com/google/diff-match-patch</url> + <connection>scm:git:git@github.com:google/diff-match-patch</connection> + <developerConnection>scm:git:git@github.com:google/diff-match-patch</developerConnection> + </scm> + <issueManagement> + <system>github.com</system> + <url>https://github.com/google/diff-match-patch/issues</url> + </issueManagement> + <developers> + <developer> + <name>Neil Fraser</name> + <organizationUrl>https://www.google.com</organizationUrl> + <url>https://www.google.com</url> + <roles> + <role>Initiator</role> + <role>Commiter</role> + </roles> + <email>fraser at google.com</email> + </developer> + </developers> + <licenses> + <license> + <name>The Apache Software License, Version 2.0</name> + <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url> + <distribution>repo</distribution> + </license> + </licenses> +</project> 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/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/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 95% 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..d189c6ee 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<String> tmpVector = new ArrayList<String>(); 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<Diff> 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<Diff> 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<Diff> 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<Diff> 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<Diff> diffs = diffList(new Diff(EQUAL, "a\n"), new Diff(DELETE, "<B>b</B>"), new Diff(INSERT, "c&d")); assertEquals("diff_prettyHtml:", "<span>a¶<br></span><del style=\"background:#ffe6e6;\"><B>b</B></del><ins style=\"background:#e6ffe6;\">c&d</ins>", dmp.diff_prettyHtml(diffs)); } - public static void testDiffText() { + @Test + public void testDiffText() { // Compute the source and destination texts. LinkedList<Diff> 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<Diff> 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<Diff> 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<Diff> 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<Diff> 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<Character, Integer> bitmask; bitmask = new HashMap<Character, Integer>(); @@ -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<Patch> 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<Patch> 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<Patch> 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<Patch> 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; @@ -942,41 +971,4 @@ private static LinkedList<Diff> 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 diff --git a/java/tests/name/fraser/neil/plaintext/Speedtest.java b/java/tests/name/fraser/neil/plaintext/Speedtest.java deleted file mode 100644 index 5c0ef034..00000000 --- a/java/tests/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(); - } -}