文本差异比较工具完善
This commit is contained in:
@@ -0,0 +1,956 @@
|
|||||||
|
/*
|
||||||
|
* Test harness for diff_match_patch.java
|
||||||
|
*
|
||||||
|
* Copyright 2006 Google Inc.
|
||||||
|
* http://code.google.com/p/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 com.jeesite.common.text;
|
||||||
|
|
||||||
|
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 com.jeesite.common.io.FileUtils;
|
||||||
|
import com.jeesite.common.text.DiffMatchPatch.Diff;
|
||||||
|
import com.jeesite.common.text.DiffMatchPatch.LinesToCharsResult;
|
||||||
|
import com.jeesite.common.text.DiffMatchPatch.Patch;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public class DiffMatchPatchTest {
|
||||||
|
|
||||||
|
private DiffMatchPatch dmp;
|
||||||
|
private DiffMatchPatch.Operation DELETE = DiffMatchPatch.Operation.DELETE;
|
||||||
|
private DiffMatchPatch.Operation EQUAL = DiffMatchPatch.Operation.EQUAL;
|
||||||
|
private DiffMatchPatch.Operation INSERT = DiffMatchPatch.Operation.INSERT;
|
||||||
|
|
||||||
|
public DiffMatchPatchTest() {
|
||||||
|
// Create an instance of the diff_match_patch object.
|
||||||
|
dmp = new DiffMatchPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DIFF TEST FUNCTIONS
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDiffLinesToChars() {
|
||||||
|
// Convert lines down to characters.
|
||||||
|
ArrayList<String> tmpVector = new ArrayList<String>();
|
||||||
|
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(n, tmpVector.size());
|
||||||
|
String lines = lineList.toString();
|
||||||
|
String chars = charList.toString();
|
||||||
|
assertEquals(n, chars.length());
|
||||||
|
tmpVector.add(0, "");
|
||||||
|
assertLinesToCharsResultEquals("diff_linesToChars: More than 256.", new LinesToCharsResult(chars, "", tmpVector), dmp.diff_linesToChars(lines, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Diff> diffs = diffList(new Diff(EQUAL, "\u0001\u0002\u0001"), new Diff(INSERT, "\u0002\u0001\u0002"));
|
||||||
|
ArrayList<String> tmpVector = new ArrayList<String>();
|
||||||
|
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(n, tmpVector.size());
|
||||||
|
String lines = lineList.toString();
|
||||||
|
String chars = charList.toString();
|
||||||
|
assertEquals(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 void testDiffCleanupMerge() {
|
||||||
|
// Cleanup a messy diff.
|
||||||
|
LinkedList<Diff> 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 void testDiffCleanupSemanticLossless() {
|
||||||
|
// Slide diffs to match logical boundaries.
|
||||||
|
LinkedList<Diff> 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 void testDiffCleanupSemantic() {
|
||||||
|
// Cleanup semantically trivial equalities.
|
||||||
|
LinkedList<Diff> 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 void testDiffCleanupEfficiency() {
|
||||||
|
// Cleanup operationally trivial equalities.
|
||||||
|
dmp.Diff_EditCost = 4;
|
||||||
|
LinkedList<Diff> diffs = diffList();
|
||||||
|
dmp.diff_cleanupEfficiency(diffs);
|
||||||
|
assertEquals("diff_cleanupEfficiency: Null case.", diffList(), diffs);
|
||||||
|
System.out.println(dmp.diff_prettyHtml(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);
|
||||||
|
System.out.println(dmp.diff_prettyHtml(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);
|
||||||
|
System.out.println(dmp.diff_prettyHtml(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);
|
||||||
|
System.out.println(dmp.diff_prettyHtml(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);
|
||||||
|
System.out.println(dmp.diff_prettyHtml(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 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 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 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);
|
||||||
|
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 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));
|
||||||
|
|
||||||
|
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 void testDiffLevenshtein() {
|
||||||
|
LinkedList<Diff> diffs = diffList(new Diff(DELETE, "abc"), new Diff(INSERT, "1234"), new Diff(EQUAL, "xyz"));
|
||||||
|
assertEquals("Levenshtein with trailing equality.", 4, dmp.diff_levenshtein(diffs));
|
||||||
|
|
||||||
|
diffs = diffList(new Diff(EQUAL, "xyz"), new Diff(DELETE, "abc"), new Diff(INSERT, "1234"));
|
||||||
|
assertEquals("Levenshtein with leading equality.", 4, dmp.diff_levenshtein(diffs));
|
||||||
|
|
||||||
|
diffs = diffList(new Diff(DELETE, "abc"), new Diff(EQUAL, "xyz"), new Diff(INSERT, "1234"));
|
||||||
|
assertEquals("Levenshtein with middle equality.", 7, dmp.diff_levenshtein(diffs));
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Diff> 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 void testDiffMain() {
|
||||||
|
// Perform a trivial diff.
|
||||||
|
LinkedList<Diff> 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 void testMatchAlphabet() {
|
||||||
|
// Initialise the bitmasks for Bitap.
|
||||||
|
Map<Character, Integer> bitmask;
|
||||||
|
bitmask = new HashMap<Character, Integer>();
|
||||||
|
bitmask.put('a', 4); bitmask.put('b', 2); bitmask.put('c', 1);
|
||||||
|
assertEquals("match_alphabet: Unique.", bitmask, dmp.match_alphabet("abc"));
|
||||||
|
|
||||||
|
bitmask = new HashMap<Character, Integer>();
|
||||||
|
bitmask.put('a', 37); bitmask.put('b', 18); bitmask.put('c', 8);
|
||||||
|
assertEquals("match_alphabet: Duplicates.", bitmask, dmp.match_alphabet("abcaba"));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPatchMake() {
|
||||||
|
LinkedList<Patch> 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<Diff> 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("`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 void testPatchSplitMax() {
|
||||||
|
// Assumes that Match_MaxBits is 32.
|
||||||
|
LinkedList<Patch> 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 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));
|
||||||
|
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 void testPatchApply() {
|
||||||
|
dmp.Match_Distance = 1000;
|
||||||
|
dmp.Match_Threshold = 0.5f;
|
||||||
|
dmp.Patch_DeleteThreshold = 0.5f;
|
||||||
|
LinkedList<Patch> 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 void assertArrayEquals(String error_msg, Object[] a, Object[] b) {
|
||||||
|
List<Object> list_a = Arrays.asList(a);
|
||||||
|
List<Object> list_b = Arrays.asList(b);
|
||||||
|
assertEquals(error_msg, list_a, list_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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<Diff> diffs) {
|
||||||
|
String[] text = {"", ""};
|
||||||
|
for (Diff myDiff : diffs) {
|
||||||
|
if (myDiff.operation != DiffMatchPatch.Operation.INSERT) {
|
||||||
|
text[0] += myDiff.text;
|
||||||
|
}
|
||||||
|
if (myDiff.operation != DiffMatchPatch.Operation.DELETE) {
|
||||||
|
text[1] += myDiff.text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private function for quickly building lists of diffs.
|
||||||
|
private static LinkedList<Diff> diffList(Diff... diffs) {
|
||||||
|
LinkedList<Diff> myDiffList = new LinkedList<Diff>();
|
||||||
|
for (Diff myDiff : diffs) {
|
||||||
|
myDiffList.add(myDiff);
|
||||||
|
}
|
||||||
|
return myDiffList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertNull(String message, Object object) {
|
||||||
|
Assert.assertNull(message, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertEquals(String message, Object expected, Object actual) {
|
||||||
|
Assert.assertEquals(message, expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertEquals(String message, String expected, String actual) {
|
||||||
|
Assert.assertEquals(message, expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertTrue(String message, boolean condition) {
|
||||||
|
Assert.assertTrue(message, condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertEquals(Object expected, Object actual) {
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fail(String message) {
|
||||||
|
Assert.fail(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
// DiffMatchPatchTest d = new DiffMatchPatchTest();
|
||||||
|
// d.testDiffCleanupEfficiency();
|
||||||
|
// d.testDiffPrettyHtml();
|
||||||
|
|
||||||
|
String text1 = "花<b>一样</b>的你,花一样的我,花一样的年华,花一样的世界,花一样的未来。";
|
||||||
|
String text2 = "花<b>一</b>样的你,花一样的年华,花一样的我,花一样的未来,花一样的世界。";
|
||||||
|
|
||||||
|
DiffMatchPatch dmp = new DiffMatchPatch();
|
||||||
|
|
||||||
|
LinkedList<Diff> diffs = dmp.diff_main(text1, text2);
|
||||||
|
String result = dmp.diff_prettyHtml(diffs);
|
||||||
|
|
||||||
|
FileUtils.writeToFile("x:\\test.html", result, false);
|
||||||
|
System.out.println(result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Diff Speed Test
|
|
||||||
*
|
|
||||||
* Compile from google3/third_party/diff_match_patch/java with:
|
|
||||||
* javac name/fraser/neil/plaintext/Speedtest.java name/fraser/neil/plaintext/diff_match_patch.java
|
|
||||||
* Execute with:
|
|
||||||
* java name/fraser/neil/plaintext/Speedtest
|
|
||||||
*
|
|
||||||
* @author fraser@google.com (Neil Fraser)
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.jeesite.test.diff;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class Speedtest {
|
|
||||||
|
|
||||||
public static void main(String args[]) {
|
|
||||||
String text1 = readFile("name/fraser/neil/plaintext/Speedtest1.txt");
|
|
||||||
String text2 = readFile("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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
This is a '''list of newspapers published by [[Journal Register Company]]'''.
|
|
||||||
|
|
||||||
The company owns daily and weekly newspapers, other print media properties and newspaper-affiliated local Websites in the [[U.S.]] states of [[Connecticut]], [[Michigan]], [[New York]], [[Ohio]] and [[Pennsylvania]], organized in six geographic "clusters":<ref>[http://www.journalregister.com/newspapers.html Journal Register Company: Our Newspapers], accessed February 10, 2008.</ref>
|
|
||||||
|
|
||||||
== Capital-Saratoga ==
|
|
||||||
Three dailies, associated weeklies and [[pennysaver]]s in greater [[Albany, New York]]; also [http://www.capitalcentral.com capitalcentral.com] and [http://www.jobsinnewyork.com JobsInNewYork.com].
|
|
||||||
|
|
||||||
* ''The Oneida Daily Dispatch'' {{WS|oneidadispatch.com}} of [[Oneida, New York]]
|
|
||||||
* ''[[The Record (Troy)|The Record]]'' {{WS|troyrecord.com}} of [[Troy, New York]]
|
|
||||||
* ''[[The Saratogian]]'' {{WS|saratogian.com}} of [[Saratoga Springs, New York]]
|
|
||||||
* Weeklies:
|
|
||||||
** ''Community News'' {{WS|cnweekly.com}} weekly of [[Clifton Park, New York]]
|
|
||||||
** ''Rome Observer'' of [[Rome, New York]]
|
|
||||||
** ''Life & Times of Utica'' of [[Utica, New York]]
|
|
||||||
|
|
||||||
== Connecticut ==
|
|
||||||
Five dailies, associated weeklies and [[pennysaver]]s in the state of [[Connecticut]]; also [http://www.ctcentral.com CTcentral.com], [http://www.ctcarsandtrucks.com CTCarsAndTrucks.com] and [http://www.jobsinct.com JobsInCT.com].
|
|
||||||
|
|
||||||
* ''The Middletown Press'' {{WS|middletownpress.com}} of [[Middletown, Connecticut|Middletown]]
|
|
||||||
* ''[[New Haven Register]]'' {{WS|newhavenregister.com}} of [[New Haven, Connecticut|New Haven]]
|
|
||||||
* ''The Register Citizen'' {{WS|registercitizen.com}} of [[Torrington, Connecticut|Torrington]]
|
|
||||||
|
|
||||||
* [[New Haven Register#Competitors|Elm City Newspapers]] {{WS|ctcentral.com}}
|
|
||||||
** ''The Advertiser'' of [[East Haven, Connecticut|East Haven]]
|
|
||||||
** ''Hamden Chronicle'' of [[Hamden, Connecticut|Hamden]]
|
|
||||||
** ''Milford Weekly'' of [[Milford, Connecticut|Milford]]
|
|
||||||
** ''The Orange Bulletin'' of [[Orange, Connecticut|Orange]]
|
|
||||||
** ''The Post'' of [[North Haven, Connecticut|North Haven]]
|
|
||||||
** ''Shelton Weekly'' of [[Shelton, Connecticut|Shelton]]
|
|
||||||
** ''The Stratford Bard'' of [[Stratford, Connecticut|Stratford]]
|
|
||||||
** ''Wallingford Voice'' of [[Wallingford, Connecticut|Wallingford]]
|
|
||||||
** ''West Haven News'' of [[West Haven, Connecticut|West Haven]]
|
|
||||||
* Housatonic Publications
|
|
||||||
** ''The New Milford Times'' {{WS|newmilfordtimes.com}} of [[New Milford, Connecticut|New Milford]]
|
|
||||||
** ''The Brookfield Journal'' of [[Brookfield, Connecticut|Brookfield]]
|
|
||||||
** ''The Kent Good Times Dispatch'' of [[Kent, Connecticut|Kent]]
|
|
||||||
** ''The Bethel Beacon'' of [[Bethel, Connecticut|Bethel]]
|
|
||||||
** ''The Litchfield Enquirer'' of [[Litchfield, Connecticut|Litchfield]]
|
|
||||||
** ''Litchfield County Times'' of [[Litchfield, Connecticut|Litchfield]]
|
|
||||||
* Imprint Newspapers {{WS|imprintnewspapers.com}}
|
|
||||||
** ''West Hartford News'' of [[West Hartford, Connecticut|West Hartford]]
|
|
||||||
** ''Windsor Journal'' of [[Windsor, Connecticut|Windsor]]
|
|
||||||
** ''Windsor Locks Journal'' of [[Windsor Locks, Connecticut|Windsor Locks]]
|
|
||||||
** ''Avon Post'' of [[Avon, Connecticut|Avon]]
|
|
||||||
** ''Farmington Post'' of [[Farmington, Connecticut|Farmington]]
|
|
||||||
** ''Simsbury Post'' of [[Simsbury, Connecticut|Simsbury]]
|
|
||||||
** ''Tri-Town Post'' of [[Burlington, Connecticut|Burlington]], [[Canton, Connecticut|Canton]] and [[Harwinton, Connecticut|Harwinton]]
|
|
||||||
* Minuteman Publications
|
|
||||||
** ''[[Fairfield Minuteman]]'' of [[Fairfield, Connecticut|Fairfield]]
|
|
||||||
** ''The Westport Minuteman'' {{WS|westportminuteman.com}} of [[Westport, Connecticut|Westport]]
|
|
||||||
* Shoreline Newspapers weeklies:
|
|
||||||
** ''Branford Review'' of [[Branford, Connecticut|Branford]]
|
|
||||||
** ''Clinton Recorder'' of [[Clinton, Connecticut|Clinton]]
|
|
||||||
** ''The Dolphin'' of [[Naval Submarine Base New London]] in [[New London, Connecticut|New London]]
|
|
||||||
** ''Main Street News'' {{WS|ctmainstreetnews.com}} of [[Essex, Connecticut|Essex]]
|
|
||||||
** ''Pictorial Gazette'' of [[Old Saybrook, Connecticut|Old Saybrook]]
|
|
||||||
** ''Regional Express'' of [[Colchester, Connecticut|Colchester]]
|
|
||||||
** ''Regional Standard'' of [[Colchester, Connecticut|Colchester]]
|
|
||||||
** ''Shoreline Times'' {{WS|shorelinetimes.com}} of [[Guilford, Connecticut|Guilford]]
|
|
||||||
** ''Shore View East'' of [[Madison, Connecticut|Madison]]
|
|
||||||
** ''Shore View West'' of [[Guilford, Connecticut|Guilford]]
|
|
||||||
* Other weeklies:
|
|
||||||
** ''Registro'' {{WS|registroct.com}} of [[New Haven, Connecticut|New Haven]]
|
|
||||||
** ''Thomaston Express'' {{WS|thomastownexpress.com}} of [[Thomaston, Connecticut|Thomaston]]
|
|
||||||
** ''Foothills Traders'' {{WS|foothillstrader.com}} of Torrington, Bristol, Canton
|
|
||||||
|
|
||||||
== Michigan ==
|
|
||||||
Four dailies, associated weeklies and [[pennysaver]]s in the state of [[Michigan]]; also [http://www.micentralhomes.com MIcentralhomes.com] and [http://www.micentralautos.com MIcentralautos.com]
|
|
||||||
* ''[[Oakland Press]]'' {{WS|theoaklandpress.com}} of [[Oakland, Michigan|Oakland]]
|
|
||||||
* ''Daily Tribune'' {{WS|dailytribune.com}} of [[Royal Oak, Michigan|Royal Oak]]
|
|
||||||
* ''Macomb Daily'' {{WS|macombdaily.com}} of [[Mt. Clemens, Michigan|Mt. Clemens]]
|
|
||||||
* ''[[Morning Sun]]'' {{WS|themorningsun.com}} of [[Mount Pleasant, Michigan|Mount Pleasant]]
|
|
||||||
* Heritage Newspapers {{WS|heritage.com}}
|
|
||||||
** ''Belleville View''
|
|
||||||
** ''Ile Camera''
|
|
||||||
** ''Monroe Guardian''
|
|
||||||
** ''Ypsilanti Courier''
|
|
||||||
** ''News-Herald''
|
|
||||||
** ''Press & Guide''
|
|
||||||
** ''Chelsea Standard & Dexter Leader''
|
|
||||||
** ''Manchester Enterprise''
|
|
||||||
** ''Milan News-Leader''
|
|
||||||
** ''Saline Reporter''
|
|
||||||
* Independent Newspapers {{WS|sourcenewspapers.com}}
|
|
||||||
** ''Advisor''
|
|
||||||
** ''Source''
|
|
||||||
* Morning Star {{WS|morningstarpublishing.com}}
|
|
||||||
** ''Alma Reminder''
|
|
||||||
** ''Alpena Star''
|
|
||||||
** ''Antrim County News''
|
|
||||||
** ''Carson City Reminder''
|
|
||||||
** ''The Leader & Kalkaskian''
|
|
||||||
** ''Ogemaw/Oscoda County Star''
|
|
||||||
** ''Petoskey/Charlevoix Star''
|
|
||||||
** ''Presque Isle Star''
|
|
||||||
** ''Preview Community Weekly''
|
|
||||||
** ''Roscommon County Star''
|
|
||||||
** ''St. Johns Reminder''
|
|
||||||
** ''Straits Area Star''
|
|
||||||
** ''The (Edmore) Advertiser''
|
|
||||||
* Voice Newspapers {{WS|voicenews.com}}
|
|
||||||
** ''Armada Times''
|
|
||||||
** ''Bay Voice''
|
|
||||||
** ''Blue Water Voice''
|
|
||||||
** ''Downriver Voice''
|
|
||||||
** ''Macomb Township Voice''
|
|
||||||
** ''North Macomb Voice''
|
|
||||||
** ''Weekend Voice''
|
|
||||||
** ''Suburban Lifestyles'' {{WS|suburbanlifestyles.com}}
|
|
||||||
|
|
||||||
== Mid-Hudson ==
|
|
||||||
One daily, associated magazines in the [[Hudson River Valley]] of [[New York]]; also [http://www.midhudsoncentral.com MidHudsonCentral.com] and [http://www.jobsinnewyork.com JobsInNewYork.com].
|
|
||||||
|
|
||||||
* ''[[Daily Freeman]]'' {{WS|dailyfreeman.com}} of [[Kingston, New York]]
|
|
||||||
|
|
||||||
== Ohio ==
|
|
||||||
Two dailies, associated magazines and three shared Websites, all in the state of [[Ohio]]: [http://www.allaroundcleveland.com AllAroundCleveland.com], [http://www.allaroundclevelandcars.com AllAroundClevelandCars.com] and [http://www.allaroundclevelandjobs.com AllAroundClevelandJobs.com].
|
|
||||||
|
|
||||||
* ''[[The News-Herald (Ohio)|The News-Herald]]'' {{WS|news-herald.com}} of [[Willoughby, Ohio|Willoughby]]
|
|
||||||
* ''[[The Morning Journal]]'' {{WS|morningjournal.com}} of [[Lorain, Ohio|Lorain]]
|
|
||||||
|
|
||||||
== Philadelphia area ==
|
|
||||||
Seven dailies and associated weeklies and magazines in [[Pennsylvania]] and [[New Jersey]], and associated Websites: [http://www.allaroundphilly.com AllAroundPhilly.com], [http://www.jobsinnj.com JobsInNJ.com], [http://www.jobsinpa.com JobsInPA.com], and [http://www.phillycarsearch.com PhillyCarSearch.com].
|
|
||||||
|
|
||||||
* ''The Daily Local'' {{WS|dailylocal.com}} of [[West Chester, Pennsylvania|West Chester]]
|
|
||||||
* ''[[Delaware County Daily and Sunday Times]] {{WS|delcotimes.com}} of Primos
|
|
||||||
* ''[[The Mercury (Pennsylvania)|The Mercury]]'' {{WS|pottstownmercury.com}} of [[Pottstown, Pennsylvania|Pottstown]]
|
|
||||||
* ''The Phoenix'' {{WS|phoenixvillenews.com}} of [[Phoenixville, Pennsylvania|Phoenixville]]
|
|
||||||
* ''[[The Reporter (Lansdale)|The Reporter]]'' {{WS|thereporteronline.com}} of [[Lansdale, Pennsylvania|Lansdale]]
|
|
||||||
* ''The Times Herald'' {{WS|timesherald.com}} of [[Norristown, Pennsylvania|Norristown]]
|
|
||||||
* ''[[The Trentonian]]'' {{WS|trentonian.com}} of [[Trenton, New Jersey]]
|
|
||||||
|
|
||||||
* Weeklies
|
|
||||||
** ''El Latino Expreso'' of [[Trenton, New Jersey]]
|
|
||||||
** ''La Voz'' of [[Norristown, Pennsylvania]]
|
|
||||||
** ''The Village News'' of [[Downingtown, Pennsylvania]]
|
|
||||||
** ''The Times Record'' of [[Kennett Square, Pennsylvania]]
|
|
||||||
** ''The Tri-County Record'' {{WS|tricountyrecord.com}} of [[Morgantown, Pennsylvania]]
|
|
||||||
** ''News of Delaware County'' {{WS|newsofdelawarecounty.com}}of [[Havertown, Pennsylvania]]
|
|
||||||
** ''Main Line Times'' {{WS|mainlinetimes.com}}of [[Ardmore, Pennsylvania]]
|
|
||||||
** ''Penny Pincher'' of [[Pottstown, Pennsylvania]]
|
|
||||||
** ''Town Talk'' {{WS|towntalknews.com}} of [[Ridley, Pennsylvania]]
|
|
||||||
* Chesapeake Publishing {{WS|pa8newsgroup.com}}
|
|
||||||
** ''Solanco Sun Ledger'' of [[Quarryville, Pennsylvania]]
|
|
||||||
** ''Columbia Ledger'' of [[Columbia, Pennsylvania]]
|
|
||||||
** ''Coatesville Ledger'' of [[Downingtown, Pennsylvania]]
|
|
||||||
** ''Parkesburg Post Ledger'' of [[Quarryville, Pennsylvania]]
|
|
||||||
** ''Downingtown Ledger'' of [[Downingtown, Pennsylvania]]
|
|
||||||
** ''The Kennett Paper'' of [[Kennett Square, Pennsylvania]]
|
|
||||||
** ''Avon Grove Sun'' of [[West Grove, Pennsylvania]]
|
|
||||||
** ''Oxford Tribune'' of [[Oxford, Pennsylvania]]
|
|
||||||
** ''Elizabethtown Chronicle'' of [[Elizabethtown, Pennsylvania]]
|
|
||||||
** ''Donegal Ledger'' of [[Donegal, Pennsylvania]]
|
|
||||||
** ''Chadds Ford Post'' of [[Chadds Ford, Pennsylvania]]
|
|
||||||
** ''The Central Record'' of [[Medford, New Jersey]]
|
|
||||||
** ''Maple Shade Progress'' of [[Maple Shade, New Jersey]]
|
|
||||||
* Intercounty Newspapers {{WS|buckslocalnews.com}}
|
|
||||||
** ''The Review'' of Roxborough, Pennsylvania
|
|
||||||
** ''The Recorder'' of [[Conshohocken, Pennsylvania]]
|
|
||||||
** ''The Leader'' of [[Mount Airy, Pennsylvania|Mount Airy]] and West Oak Lake, Pennsylvania
|
|
||||||
** ''The Pennington Post'' of [[Pennington, New Jersey]]
|
|
||||||
** ''The Bristol Pilot'' of [[Bristol, Pennsylvania]]
|
|
||||||
** ''Yardley News'' of [[Yardley, Pennsylvania]]
|
|
||||||
** ''New Hope Gazette'' of [[New Hope, Pennsylvania]]
|
|
||||||
** ''Doylestown Patriot'' of [[Doylestown, Pennsylvania]]
|
|
||||||
** ''Newtown Advance'' of [[Newtown, Pennsylvania]]
|
|
||||||
** ''The Plain Dealer'' of [[Williamstown, New Jersey]]
|
|
||||||
** ''News Report'' of [[Sewell, New Jersey]]
|
|
||||||
** ''Record Breeze'' of [[Berlin, New Jersey]]
|
|
||||||
** ''Newsweekly'' of [[Moorestown, New Jersey]]
|
|
||||||
** ''Haddon Herald'' of [[Haddonfield, New Jersey]]
|
|
||||||
** ''New Egypt Press'' of [[New Egypt, New Jersey]]
|
|
||||||
** ''Community News'' of [[Pemberton, New Jersey]]
|
|
||||||
** ''Plymouth Meeting Journal'' of [[Plymouth Meeting, Pennsylvania]]
|
|
||||||
** ''Lafayette Hill Journal'' of [[Lafayette Hill, Pennsylvania]]
|
|
||||||
* Montgomery Newspapers {{WS|montgomerynews.com}}
|
|
||||||
** ''Ambler Gazette'' of [[Ambler, Pennsylvania]]
|
|
||||||
** ''Central Bucks Life'' of [[Bucks County, Pennsylvania]]
|
|
||||||
** ''The Colonial'' of [[Plymouth Meeting, Pennsylvania]]
|
|
||||||
** ''Glenside News'' of [[Glenside, Pennsylvania]]
|
|
||||||
** ''The Globe'' of [[Lower Moreland Township, Pennsylvania]]
|
|
||||||
** ''Main Line Life'' of [[Ardmore, Pennsylvania]]
|
|
||||||
** ''Montgomery Life'' of [[Fort Washington, Pennsylvania]]
|
|
||||||
** ''North Penn Life'' of [[Lansdale, Pennsylvania]]
|
|
||||||
** ''Perkasie News Herald'' of [[Perkasie, Pennsylvania]]
|
|
||||||
** ''Public Spirit'' of [[Hatboro, Pennsylvania]]
|
|
||||||
** ''Souderton Independent'' of [[Souderton, Pennsylvania]]
|
|
||||||
** ''Springfield Sun'' of [[Springfield, Pennsylvania]]
|
|
||||||
** ''Spring-Ford Reporter'' of [[Royersford, Pennsylvania]]
|
|
||||||
** ''Times Chronicle'' of [[Jenkintown, Pennsylvania]]
|
|
||||||
** ''Valley Item'' of [[Perkiomenville, Pennsylvania]]
|
|
||||||
** ''Willow Grove Guide'' of [[Willow Grove, Pennsylvania]]
|
|
||||||
* News Gleaner Publications (closed December 2008) {{WS|newsgleaner.com}}
|
|
||||||
** ''Life Newspapers'' of [[Philadelphia, Pennsylvania]]
|
|
||||||
* Suburban Publications
|
|
||||||
** ''The Suburban & Wayne Times'' {{WS|waynesuburban.com}} of [[Wayne, Pennsylvania]]
|
|
||||||
** ''The Suburban Advertiser'' of [[Exton, Pennsylvania]]
|
|
||||||
** ''The King of Prussia Courier'' of [[King of Prussia, Pennsylvania]]
|
|
||||||
* Press Newspapers {{WS|countypressonline.com}}
|
|
||||||
** ''County Press'' of [[Newtown Square, Pennsylvania]]
|
|
||||||
** ''Garnet Valley Press'' of [[Glen Mills, Pennsylvania]]
|
|
||||||
** ''Haverford Press'' of [[Newtown Square, Pennsylvania]] (closed January 2009)
|
|
||||||
** ''Hometown Press'' of [[Glen Mills, Pennsylvania]] (closed January 2009)
|
|
||||||
** ''Media Press'' of [[Newtown Square, Pennsylvania]] (closed January 2009)
|
|
||||||
** ''Springfield Press'' of [[Springfield, Pennsylvania]]
|
|
||||||
* Berks-Mont Newspapers {{WS|berksmontnews.com}}
|
|
||||||
** ''The Boyertown Area Times'' of [[Boyertown, Pennsylvania]]
|
|
||||||
** ''The Kutztown Area Patriot'' of [[Kutztown, Pennsylvania]]
|
|
||||||
** ''The Hamburg Area Item'' of [[Hamburg, Pennsylvania]]
|
|
||||||
** ''The Southern Berks News'' of [[Exeter Township, Berks County, Pennsylvania]]
|
|
||||||
** ''The Free Press'' of [[Quakertown, Pennsylvania]]
|
|
||||||
** ''The Saucon News'' of [[Quakertown, Pennsylvania]]
|
|
||||||
** ''Westside Weekly'' of [[Reading, Pennsylvania]]
|
|
||||||
|
|
||||||
* Magazines
|
|
||||||
** ''Bucks Co. Town & Country Living''
|
|
||||||
** ''Chester Co. Town & Country Living''
|
|
||||||
** ''Montomgery Co. Town & Country Living''
|
|
||||||
** ''Garden State Town & Country Living''
|
|
||||||
** ''Montgomery Homes''
|
|
||||||
** ''Philadelphia Golfer''
|
|
||||||
** ''Parents Express''
|
|
||||||
** ''Art Matters''
|
|
||||||
|
|
||||||
{{JRC}}
|
|
||||||
|
|
||||||
==References==
|
|
||||||
<references />
|
|
||||||
|
|
||||||
[[Category:Journal Register publications|*]]
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
This is a '''list of newspapers published by [[Journal Register Company]]'''.
|
|
||||||
|
|
||||||
The company owns daily and weekly newspapers, other print media properties and newspaper-affiliated local Websites in the [[U.S.]] states of [[Connecticut]], [[Michigan]], [[New York]], [[Ohio]], [[Pennsylvania]] and [[New Jersey]], organized in six geographic "clusters":<ref>[http://www.journalregister.com/publications.html Journal Register Company: Our Publications], accessed April 21, 2010.</ref>
|
|
||||||
|
|
||||||
== Capital-Saratoga ==
|
|
||||||
Three dailies, associated weeklies and [[pennysaver]]s in greater [[Albany, New York]]; also [http://www.capitalcentral.com capitalcentral.com] and [http://www.jobsinnewyork.com JobsInNewYork.com].
|
|
||||||
|
|
||||||
* ''The Oneida Daily Dispatch'' {{WS|oneidadispatch.com}} of [[Oneida, New York]]
|
|
||||||
* ''[[The Record (Troy)|The Record]]'' {{WS|troyrecord.com}} of [[Troy, New York]]
|
|
||||||
* ''[[The Saratogian]]'' {{WS|saratogian.com}} of [[Saratoga Springs, New York]]
|
|
||||||
* Weeklies:
|
|
||||||
** ''Community News'' {{WS|cnweekly.com}} weekly of [[Clifton Park, New York]]
|
|
||||||
** ''Rome Observer'' {{WS|romeobserver.com}} of [[Rome, New York]]
|
|
||||||
** ''WG Life '' {{WS|saratogian.com/wglife/}} of [[Wilton, New York]]
|
|
||||||
** ''Ballston Spa Life '' {{WS|saratogian.com/bspalife}} of [[Ballston Spa, New York]]
|
|
||||||
** ''Greenbush Life'' {{WS|troyrecord.com/greenbush}} of [[Troy, New York]]
|
|
||||||
** ''Latham Life'' {{WS|troyrecord.com/latham}} of [[Latham, New York]]
|
|
||||||
** ''River Life'' {{WS|troyrecord.com/river}} of [[Troy, New York]]
|
|
||||||
|
|
||||||
== Connecticut ==
|
|
||||||
Three dailies, associated weeklies and [[pennysaver]]s in the state of [[Connecticut]]; also [http://www.ctcentral.com CTcentral.com], [http://www.ctcarsandtrucks.com CTCarsAndTrucks.com] and [http://www.jobsinct.com JobsInCT.com].
|
|
||||||
|
|
||||||
* ''The Middletown Press'' {{WS|middletownpress.com}} of [[Middletown, Connecticut|Middletown]]
|
|
||||||
* ''[[New Haven Register]]'' {{WS|newhavenregister.com}} of [[New Haven, Connecticut|New Haven]]
|
|
||||||
* ''The Register Citizen'' {{WS|registercitizen.com}} of [[Torrington, Connecticut|Torrington]]
|
|
||||||
|
|
||||||
* Housatonic Publications
|
|
||||||
** ''The Housatonic Times'' {{WS|housatonictimes.com}} of [[New Milford, Connecticut|New Milford]]
|
|
||||||
** ''Litchfield County Times'' {{WS|countytimes.com}} of [[Litchfield, Connecticut|Litchfield]]
|
|
||||||
|
|
||||||
* Minuteman Publications
|
|
||||||
** ''[[Fairfield Minuteman]]'' {{WS|fairfieldminuteman.com}}of [[Fairfield, Connecticut|Fairfield]]
|
|
||||||
** ''The Westport Minuteman'' {{WS|westportminuteman.com}} of [[Westport, Connecticut|Westport]]
|
|
||||||
|
|
||||||
* Shoreline Newspapers
|
|
||||||
** ''The Dolphin'' {{WS|dolphin-news.com}} of [[Naval Submarine Base New London]] in [[New London, Connecticut|New London]]
|
|
||||||
** ''Shoreline Times'' {{WS|shorelinetimes.com}} of [[Guilford, Connecticut|Guilford]]
|
|
||||||
|
|
||||||
* Foothills Media Group {{WS|foothillsmediagroup.com}}
|
|
||||||
** ''Thomaston Express'' {{WS|thomastonexpress.com}} of [[Thomaston, Connecticut|Thomaston]]
|
|
||||||
** ''Good News About Torrington'' {{WS|goodnewsabouttorrington.com}} of [[Torrington, Connecticut|Torrington]]
|
|
||||||
** ''Granby News'' {{WS|foothillsmediagroup.com/granby}} of [[Granby, Connecticut|Granby]]
|
|
||||||
** ''Canton News'' {{WS|foothillsmediagroup.com/canton}} of [[Canton, Connecticut|Canton]]
|
|
||||||
** ''Avon News'' {{WS|foothillsmediagroup.com/avon}} of [[Avon, Connecticut|Avon]]
|
|
||||||
** ''Simsbury News'' {{WS|foothillsmediagroup.com/simsbury}} of [[Simsbury, Connecticut|Simsbury]]
|
|
||||||
** ''Litchfield News'' {{WS|foothillsmediagroup.com/litchfield}} of [[Litchfield, Connecticut|Litchfield]]
|
|
||||||
** ''Foothills Trader'' {{WS|foothillstrader.com}} of Torrington, Bristol, Canton
|
|
||||||
|
|
||||||
* Other weeklies
|
|
||||||
** ''The Milford-Orange Bulletin'' {{WS|ctbulletin.com}} of [[Orange, Connecticut|Orange]]
|
|
||||||
** ''The Post-Chronicle'' {{WS|ctpostchronicle.com}} of [[North Haven, Connecticut|North Haven]]
|
|
||||||
** ''West Hartford News'' {{WS|westhartfordnews.com}} of [[West Hartford, Connecticut|West Hartford]]
|
|
||||||
|
|
||||||
* Magazines
|
|
||||||
** ''The Connecticut Bride'' {{WS|connecticutmag.com}}
|
|
||||||
** ''Connecticut Magazine'' {{WS|theconnecticutbride.com}}
|
|
||||||
** ''Passport Magazine'' {{WS|passport-mag.com}}
|
|
||||||
|
|
||||||
== Michigan ==
|
|
||||||
Four dailies, associated weeklies and [[pennysaver]]s in the state of [[Michigan]]; also [http://www.micentralhomes.com MIcentralhomes.com] and [http://www.micentralautos.com MIcentralautos.com]
|
|
||||||
* ''[[Oakland Press]]'' {{WS|theoaklandpress.com}} of [[Oakland, Michigan|Oakland]]
|
|
||||||
* ''Daily Tribune'' {{WS|dailytribune.com}} of [[Royal Oak, Michigan|Royal Oak]]
|
|
||||||
* ''Macomb Daily'' {{WS|macombdaily.com}} of [[Mt. Clemens, Michigan|Mt. Clemens]]
|
|
||||||
* ''[[Morning Sun]]'' {{WS|themorningsun.com}} of [[Mount Pleasant, Michigan|Mount Pleasant]]
|
|
||||||
|
|
||||||
* Heritage Newspapers {{WS|heritage.com}}
|
|
||||||
** ''Belleville View'' {{WS|bellevilleview.com}}
|
|
||||||
** ''Ile Camera'' {{WS|thenewsherald.com/ile_camera}}
|
|
||||||
** ''Monroe Guardian'' {{WS|monreguardian.com}}
|
|
||||||
** ''Ypsilanti Courier'' {{WS|ypsilanticourier.com}}
|
|
||||||
** ''News-Herald'' {{WS|thenewsherald.com}}
|
|
||||||
** ''Press & Guide'' {{WS|pressandguide.com}}
|
|
||||||
** ''Chelsea Standard & Dexter Leader'' {{WS|chelseastandard.com}}
|
|
||||||
** ''Manchester Enterprise'' {{WS|manchesterguardian.com}}
|
|
||||||
** ''Milan News-Leader'' {{WS|milannews.com}}
|
|
||||||
** ''Saline Reporter'' {{WS|salinereporter.com}}
|
|
||||||
* Independent Newspapers
|
|
||||||
** ''Advisor'' {{WS|sourcenewspapers.com}}
|
|
||||||
** ''Source'' {{WS|sourcenewspapers.com}}
|
|
||||||
* Morning Star {{WS|morningstarpublishing.com}}
|
|
||||||
** ''The Leader & Kalkaskian'' {{WS|leaderandkalkaskian.com}}
|
|
||||||
** ''Grand Traverse Insider'' {{WS|grandtraverseinsider.com}}
|
|
||||||
** ''Alma Reminder''
|
|
||||||
** ''Alpena Star''
|
|
||||||
** ''Ogemaw/Oscoda County Star''
|
|
||||||
** ''Presque Isle Star''
|
|
||||||
** ''St. Johns Reminder''
|
|
||||||
|
|
||||||
* Voice Newspapers {{WS|voicenews.com}}
|
|
||||||
** ''Armada Times''
|
|
||||||
** ''Bay Voice''
|
|
||||||
** ''Blue Water Voice''
|
|
||||||
** ''Downriver Voice''
|
|
||||||
** ''Macomb Township Voice''
|
|
||||||
** ''North Macomb Voice''
|
|
||||||
** ''Weekend Voice''
|
|
||||||
|
|
||||||
== Mid-Hudson ==
|
|
||||||
One daily, associated magazines in the [[Hudson River Valley]] of [[New York]]; also [http://www.midhudsoncentral.com MidHudsonCentral.com] and [http://www.jobsinnewyork.com JobsInNewYork.com].
|
|
||||||
|
|
||||||
* ''[[Daily Freeman]]'' {{WS|dailyfreeman.com}} of [[Kingston, New York]]
|
|
||||||
* ''Las Noticias'' {{WS|lasnoticiasny.com}} of [[Kingston, New York]]
|
|
||||||
|
|
||||||
== Ohio ==
|
|
||||||
Two dailies, associated magazines and three shared Websites, all in the state of [[Ohio]]: [http://www.allaroundcleveland.com AllAroundCleveland.com], [http://www.allaroundclevelandcars.com AllAroundClevelandCars.com] and [http://www.allaroundclevelandjobs.com AllAroundClevelandJobs.com].
|
|
||||||
|
|
||||||
* ''[[The News-Herald (Ohio)|The News-Herald]]'' {{WS|news-herald.com}} of [[Willoughby, Ohio|Willoughby]]
|
|
||||||
* ''[[The Morning Journal]]'' {{WS|morningjournal.com}} of [[Lorain, Ohio|Lorain]]
|
|
||||||
* ''El Latino Expreso'' {{WS|lorainlatino.com}} of [[Lorain, Ohio|Lorain]]
|
|
||||||
|
|
||||||
== Philadelphia area ==
|
|
||||||
Seven dailies and associated weeklies and magazines in [[Pennsylvania]] and [[New Jersey]], and associated Websites: [http://www.allaroundphilly.com AllAroundPhilly.com], [http://www.jobsinnj.com JobsInNJ.com], [http://www.jobsinpa.com JobsInPA.com], and [http://www.phillycarsearch.com PhillyCarSearch.com].
|
|
||||||
|
|
||||||
* ''[[The Daily Local News]]'' {{WS|dailylocal.com}} of [[West Chester, Pennsylvania|West Chester]]
|
|
||||||
* ''[[Delaware County Daily and Sunday Times]] {{WS|delcotimes.com}} of Primos [[Upper Darby Township, Pennsylvania]]
|
|
||||||
* ''[[The Mercury (Pennsylvania)|The Mercury]]'' {{WS|pottstownmercury.com}} of [[Pottstown, Pennsylvania|Pottstown]]
|
|
||||||
* ''[[The Reporter (Lansdale)|The Reporter]]'' {{WS|thereporteronline.com}} of [[Lansdale, Pennsylvania|Lansdale]]
|
|
||||||
* ''The Times Herald'' {{WS|timesherald.com}} of [[Norristown, Pennsylvania|Norristown]]
|
|
||||||
* ''[[The Trentonian]]'' {{WS|trentonian.com}} of [[Trenton, New Jersey]]
|
|
||||||
|
|
||||||
* Weeklies
|
|
||||||
* ''The Phoenix'' {{WS|phoenixvillenews.com}} of [[Phoenixville, Pennsylvania]]
|
|
||||||
** ''El Latino Expreso'' {{WS|njexpreso.com}} of [[Trenton, New Jersey]]
|
|
||||||
** ''La Voz'' {{WS|lavozpa.com}} of [[Norristown, Pennsylvania]]
|
|
||||||
** ''The Tri County Record'' {{WS|tricountyrecord.com}} of [[Morgantown, Pennsylvania]]
|
|
||||||
** ''Penny Pincher'' {{WS|pennypincherpa.com}}of [[Pottstown, Pennsylvania]]
|
|
||||||
|
|
||||||
* Chesapeake Publishing {{WS|southernchestercountyweeklies.com}}
|
|
||||||
** ''The Kennett Paper'' {{WS|kennettpaper.com}} of [[Kennett Square, Pennsylvania]]
|
|
||||||
** ''Avon Grove Sun'' {{WS|avongrovesun.com}} of [[West Grove, Pennsylvania]]
|
|
||||||
** ''The Central Record'' {{WS|medfordcentralrecord.com}} of [[Medford, New Jersey]]
|
|
||||||
** ''Maple Shade Progress'' {{WS|mapleshadeprogress.com}} of [[Maple Shade, New Jersey]]
|
|
||||||
|
|
||||||
* Intercounty Newspapers {{WS|buckslocalnews.com}} {{WS|southjerseylocalnews.com}}
|
|
||||||
** ''The Pennington Post'' {{WS|penningtonpost.com}} of [[Pennington, New Jersey]]
|
|
||||||
** ''The Bristol Pilot'' {{WS|bristolpilot.com}} of [[Bristol, Pennsylvania]]
|
|
||||||
** ''Yardley News'' {{WS|yardleynews.com}} of [[Yardley, Pennsylvania]]
|
|
||||||
** ''Advance of Bucks County'' {{WS|advanceofbucks.com}} of [[Newtown, Pennsylvania]]
|
|
||||||
** ''Record Breeze'' {{WS|recordbreeze.com}} of [[Berlin, New Jersey]]
|
|
||||||
** ''Community News'' {{WS|sjcommunitynews.com}} of [[Pemberton, New Jersey]]
|
|
||||||
|
|
||||||
* Montgomery Newspapers {{WS|montgomerynews.com}}
|
|
||||||
** ''Ambler Gazette'' {{WS|amblergazette.com}} of [[Ambler, Pennsylvania]]
|
|
||||||
** ''The Colonial'' {{WS|colonialnews.com}} of [[Plymouth Meeting, Pennsylvania]]
|
|
||||||
** ''Glenside News'' {{WS|glensidenews.com}} of [[Glenside, Pennsylvania]]
|
|
||||||
** ''The Globe'' {{WS|globenewspaper.com}} of [[Lower Moreland Township, Pennsylvania]]
|
|
||||||
** ''Montgomery Life'' {{WS|montgomerylife.com}} of [[Fort Washington, Pennsylvania]]
|
|
||||||
** ''North Penn Life'' {{WS|northpennlife.com}} of [[Lansdale, Pennsylvania]]
|
|
||||||
** ''Perkasie News Herald'' {{WS|perkasienewsherald.com}} of [[Perkasie, Pennsylvania]]
|
|
||||||
** ''Public Spirit'' {{WS|thepublicspirit.com}} of [[Hatboro, Pennsylvania]]
|
|
||||||
** ''Souderton Independent'' {{WS|soudertonindependent.com}} of [[Souderton, Pennsylvania]]
|
|
||||||
** ''Springfield Sun'' {{WS|springfieldsun.com}} of [[Springfield, Pennsylvania]]
|
|
||||||
** ''Spring-Ford Reporter'' {{WS|springfordreporter.com}} of [[Royersford, Pennsylvania]]
|
|
||||||
** ''Times Chronicle'' {{WS|thetimeschronicle.com}} of [[Jenkintown, Pennsylvania]]
|
|
||||||
** ''Valley Item'' {{WS|valleyitem.com}} of [[Perkiomenville, Pennsylvania]]
|
|
||||||
** ''Willow Grove Guide'' {{WS|willowgroveguide.com}} of [[Willow Grove, Pennsylvania]]
|
|
||||||
** ''The Review'' {{WS|roxreview.com}} of [[Roxborough, Philadelphia, Pennsylvania]]
|
|
||||||
|
|
||||||
* Main Line Media News {{WS|mainlinemedianews.com}}
|
|
||||||
** ''Main Line Times'' {{WS|mainlinetimes.com}} of [[Ardmore, Pennsylvania]]
|
|
||||||
** ''Main Line Life'' {{WS|mainlinelife.com}} of [[Ardmore, Pennsylvania]]
|
|
||||||
** ''The King of Prussia Courier'' {{WS|kingofprussiacourier.com}} of [[King of Prussia, Pennsylvania]]
|
|
||||||
|
|
||||||
* Delaware County News Network {{WS|delconewsnetwork.com}}
|
|
||||||
** ''News of Delaware County'' {{WS|newsofdelawarecounty.com}} of [[Havertown, Pennsylvania]]
|
|
||||||
** ''County Press'' {{WS|countypressonline.com}} of [[Newtown Square, Pennsylvania]]
|
|
||||||
** ''Garnet Valley Press'' {{WS|countypressonline.com}} of [[Glen Mills, Pennsylvania]]
|
|
||||||
** ''Springfield Press'' {{WS|countypressonline.com}} of [[Springfield, Pennsylvania]]
|
|
||||||
** ''Town Talk'' {{WS|towntalknews.com}} of [[Ridley, Pennsylvania]]
|
|
||||||
|
|
||||||
* Berks-Mont Newspapers {{WS|berksmontnews.com}}
|
|
||||||
** ''The Boyertown Area Times'' {{WS|berksmontnews.com/boyertown_area_times}} of [[Boyertown, Pennsylvania]]
|
|
||||||
** ''The Kutztown Area Patriot'' {{WS|berksmontnews.com/kutztown_area_patriot}} of [[Kutztown, Pennsylvania]]
|
|
||||||
** ''The Hamburg Area Item'' {{WS|berksmontnews.com/hamburg_area_item}} of [[Hamburg, Pennsylvania]]
|
|
||||||
** ''The Southern Berks News'' {{WS|berksmontnews.com/southern_berks_news}} of [[Exeter Township, Berks County, Pennsylvania]]
|
|
||||||
** ''Community Connection'' {{WS|berksmontnews.com/community_connection}} of [[Boyertown, Pennsylvania]]
|
|
||||||
|
|
||||||
* Magazines
|
|
||||||
** ''Bucks Co. Town & Country Living'' {{WS|buckscountymagazine.com}}
|
|
||||||
** ''Parents Express'' {{WS|parents-express.com}}
|
|
||||||
** ''Real Men, Rednecks'' {{WS|realmenredneck.com}}
|
|
||||||
|
|
||||||
{{JRC}}
|
|
||||||
|
|
||||||
==References==
|
|
||||||
<references />
|
|
||||||
|
|
||||||
[[Category:Journal Register publications|*]]
|
|
||||||
Reference in New Issue
Block a user