diff --git a/src/main/java/difflib/DiffUtils.java b/src/main/java/difflib/DiffUtils.java index eb8121f..ad87324 100644 --- a/src/main/java/difflib/DiffUtils.java +++ b/src/main/java/difflib/DiffUtils.java @@ -26,6 +26,7 @@ import difflib.patch.Delta; import difflib.patch.Equalizer; import difflib.patch.Patch; import difflib.patch.PatchFailedException; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -52,6 +53,13 @@ public final class DiffUtils { public static Patch diff(List original, List revised) throws DiffException { return DiffUtils.diff(original, revised, new MyersDiff<>()); } + + /** + * Computes the difference between the original and revised text. + */ + public static Patch diff(String originalText, String revisedText) throws DiffException { + return DiffUtils.diff(Arrays.asList(originalText.split("\n")), Arrays.asList(revisedText.split("\n"))); + } /** * Computes the difference between the original and revised list of elements with default diff diff --git a/src/main/java/difflib/patch/Patch.java b/src/main/java/difflib/patch/Patch.java index 30b4fc4..d75bb00 100644 --- a/src/main/java/difflib/patch/Patch.java +++ b/src/main/java/difflib/patch/Patch.java @@ -85,4 +85,9 @@ public final class Patch { Collections.sort(deltas, comparing(d -> d.getOriginal().getPosition())); return deltas; } + + @Override + public String toString() { + return "Patch{" + "deltas=" + deltas + '}'; + } } diff --git a/src/test/java/difflib/DiffUtilsTest.java b/src/test/java/difflib/DiffUtilsTest.java index 55a721d..680f56b 100644 --- a/src/test/java/difflib/DiffUtilsTest.java +++ b/src/test/java/difflib/DiffUtilsTest.java @@ -7,13 +7,22 @@ import difflib.patch.DeleteDelta; import difflib.patch.Delta; import difflib.patch.InsertDelta; import difflib.patch.Patch; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import static java.util.stream.Collectors.toList; +import java.util.zip.ZipFile; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import org.junit.Ignore; import org.junit.Test; public class DiffUtilsTest { @@ -101,13 +110,46 @@ public class DiffUtilsTest { List revised = Arrays.asList(2, 3, 4, 6); final Patch patch = DiffUtils.diff(original, revised); - + for (Delta delta : patch.getDeltas()) { System.out.println(delta); } - + assertEquals(2, patch.getDeltas().size()); assertEquals("[DeleteDelta, position: 0, lines: [1]]", patch.getDeltas().get(0).toString()); assertEquals("[ChangeDelta, position: 4, lines: [5] to [6]]", patch.getDeltas().get(1).toString()); } + + @Test + public void testDiffMissesChangeForkDnaumenkoIssue31() throws DiffException { + List original = Arrays.asList("line1", "line2", "line3"); + List revised = Arrays.asList("line1", "line2-2", "line4"); + + Patch patch = DiffUtils.diff(original, revised); + assertEquals(1, patch.getDeltas().size()); + assertEquals("[ChangeDelta, position: 1, lines: [line2, line3] to [line2-2, line4]]", patch.getDeltas().get(0).toString()); + } + + /** + * To test this, the greedy meyer algorithm is not suitable. + */ + @Test + @Ignore + public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException { + ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip"); + + Patch patch = DiffUtils.diff( + readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta"))), + readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")))); + + assertEquals(1, patch.getDeltas().size()); + } + + private static List readStringListFromInputStream(InputStream is) throws IOException { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(is, Charset.forName(StandardCharsets.UTF_8.name())))) { + + return reader.lines().collect(toList()); + } + } } diff --git a/src/test/resources/mocks/large_dataset1.zip b/src/test/resources/mocks/large_dataset1.zip new file mode 100644 index 0000000..4f1a8fa Binary files /dev/null and b/src/test/resources/mocks/large_dataset1.zip differ