mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
Fizzy apply (#125)
* add applyFuzzyTo and restoreFuzzy * implement applyFuzzyTo and restoreFuzzy for EqualDelta * add verifyChunk with fuzzy and delta * implement fuzzy apply and add tests * fix style * extract method * fix: assign lastPatchDelta and lastPatchEnd * fix use explict import * document EqualDelta#applyFuzzyToAt * set access modifiers * change test method name * document empty method * apply from first * add more tests * add more documentation about fuzz parameter * fix documentation about fizzy patch Co-authored-by: cowwoc <cowwoc2020@gmail.com> Co-authored-by: cowwoc <cowwoc2020@gmail.com>
This commit is contained in:
@@ -70,6 +70,19 @@ public abstract class AbstractDelta<T> implements Serializable {
|
||||
|
||||
protected abstract void restore(List<T> target);
|
||||
|
||||
/**
|
||||
* Apply patch fuzzy.
|
||||
*
|
||||
* @param target the list this patch will be applied to
|
||||
* @param fuzz the number of elements to ignore before/after the patched elements
|
||||
* @param position the position this patch will be applied to. ignores {@code source.getPosition()}
|
||||
* @see <a href="https://www.gnu.org/software/diffutils/manual/html_node/Inexact.html">Description of Fuzzy Patch</a> for more information.
|
||||
*/
|
||||
@SuppressWarnings("RedundantThrows")
|
||||
protected void applyFuzzyToAt(List<T> target, int fuzz, int position) throws PatchFailedException {
|
||||
throw new UnsupportedOperationException(this.getClass().getSimpleName() + " does not supports applying patch fuzzy");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new delta of the actual instance with customized chunk data.
|
||||
*/
|
||||
|
||||
@@ -66,6 +66,19 @@ public final class ChangeDelta<T> extends AbstractDelta<T> {
|
||||
}
|
||||
}
|
||||
|
||||
protected void applyFuzzyToAt(List<T> target, int fuzz, int position) throws PatchFailedException {
|
||||
int size = getSource().size();
|
||||
for (int i = fuzz; i < size - fuzz; i++) {
|
||||
target.remove(position + fuzz);
|
||||
}
|
||||
|
||||
int i = fuzz;
|
||||
for (T line : getTarget().getLines().subList(fuzz, getTarget().size() - fuzz)) {
|
||||
target.add(position + i, line);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[ChangeDelta, position: " + getSource().getPosition() + ", lines: "
|
||||
|
||||
@@ -95,10 +95,28 @@ public final class Chunk<T> implements Serializable {
|
||||
* @throws com.github.difflib.patch.PatchFailedException
|
||||
*/
|
||||
public VerifyChunk verifyChunk(List<T> target) throws PatchFailedException {
|
||||
if (position > target.size() || last() > target.size()) {
|
||||
return verifyChunk(target, 0, getPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that this chunk's saved text matches the corresponding text in
|
||||
* the given sequence.
|
||||
*
|
||||
* @param target the sequence to verify against.
|
||||
* @param fuzz the count of ignored prefix/suffix
|
||||
* @param position the position of target
|
||||
* @throws com.github.difflib.patch.PatchFailedException
|
||||
*/
|
||||
public VerifyChunk verifyChunk(List<T> target, int fuzz, int position) throws PatchFailedException {
|
||||
//noinspection UnnecessaryLocalVariable
|
||||
int startIndex = fuzz;
|
||||
int lastIndex = size() - fuzz;
|
||||
int last = position + size() - 1;
|
||||
|
||||
if (position + fuzz > target.size() || last - fuzz > target.size()) {
|
||||
return VerifyChunk.POSITION_OUT_OF_TARGET;
|
||||
}
|
||||
for (int i = 0; i < size(); i++) {
|
||||
for (int i = startIndex; i < lastIndex; i++) {
|
||||
if (!target.get(position + i).equals(lines.get(i))) {
|
||||
return VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,14 @@ public class EqualDelta<T> extends AbstractDelta<T> {
|
||||
protected void restore(List<T> target) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void applyFuzzyToAt(List<T> target, int fuzz, int delta) {
|
||||
// equals so no operations
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[EqualDelta, position: " + getSource().getPosition() + ", lines: "
|
||||
|
||||
@@ -66,6 +66,117 @@ public final class Patch<T> implements Serializable {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class PatchApplyingContext<T> {
|
||||
public final List<T> result;
|
||||
public final int maxFuzz;
|
||||
|
||||
// the position last patch applied to.
|
||||
public int lastPatchEnd = -1;
|
||||
|
||||
///// passing values from find to apply
|
||||
public int currentFuzz = 0;
|
||||
|
||||
public int defaultPosition;
|
||||
public boolean beforeOutRange = false;
|
||||
public boolean afterOutRange = false;
|
||||
|
||||
private PatchApplyingContext(List<T> result, int maxFuzz) {
|
||||
this.result = result;
|
||||
this.maxFuzz = maxFuzz;
|
||||
}
|
||||
}
|
||||
|
||||
public List<T> applyFuzzy(List<T> target, int maxFuzz) throws PatchFailedException {
|
||||
PatchApplyingContext<T> ctx = new PatchApplyingContext<>(new ArrayList<>(target), maxFuzz);
|
||||
|
||||
// the difference between patch's position and actually applied position
|
||||
int lastPatchDelta = 0;
|
||||
|
||||
for (AbstractDelta<T> delta : getDeltas()) {
|
||||
ctx.defaultPosition = delta.getSource().getPosition() + lastPatchDelta;
|
||||
int patchPosition = findPositionFuzzy(ctx, delta);
|
||||
if (0 <= patchPosition) {
|
||||
delta.applyFuzzyToAt(ctx.result, ctx.currentFuzz, patchPosition);
|
||||
lastPatchDelta = patchPosition - delta.getSource().getPosition();
|
||||
ctx.lastPatchEnd = delta.getSource().last() + lastPatchDelta;
|
||||
} else {
|
||||
conflictOutput.processConflict(VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET, delta, ctx.result);
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.result;
|
||||
}
|
||||
|
||||
// negative for not found
|
||||
private int findPositionFuzzy(PatchApplyingContext<T> ctx, AbstractDelta<T> delta) throws PatchFailedException {
|
||||
for (int fuzz = 0; fuzz <= ctx.maxFuzz; fuzz++) {
|
||||
ctx.currentFuzz = fuzz;
|
||||
int foundPosition = findPositionWithFuzz(ctx, delta, fuzz);
|
||||
if (foundPosition >= 0) {
|
||||
return foundPosition;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// negative for not found
|
||||
private int findPositionWithFuzz(PatchApplyingContext<T> ctx, AbstractDelta<T> delta, int fuzz) throws PatchFailedException {
|
||||
if (delta.getSource().verifyChunk(ctx.result, fuzz, ctx.defaultPosition) == VerifyChunk.OK) {
|
||||
return ctx.defaultPosition;
|
||||
}
|
||||
|
||||
ctx.beforeOutRange = false;
|
||||
ctx.afterOutRange = false;
|
||||
|
||||
// moreDelta >= 0: just for overflow guard, not a normal condition
|
||||
//noinspection OverflowingLoopIndex
|
||||
for (int moreDelta = 0; moreDelta >= 0; moreDelta++) {
|
||||
int pos = findPositionWithFuzzAndMoreDelta(ctx, delta, fuzz, moreDelta);
|
||||
if (pos >= 0) {
|
||||
return pos;
|
||||
}
|
||||
if (ctx.beforeOutRange && ctx.afterOutRange) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// negative for not found
|
||||
private int findPositionWithFuzzAndMoreDelta(PatchApplyingContext<T> ctx, AbstractDelta<T> delta, int fuzz, int moreDelta) throws PatchFailedException {
|
||||
// range check: can't apply before end of last patch
|
||||
if (!ctx.beforeOutRange) {
|
||||
int beginAt = ctx.defaultPosition - moreDelta + fuzz;
|
||||
// We can't apply patch before end of last patch.
|
||||
if (beginAt <= ctx.lastPatchEnd) {
|
||||
ctx.beforeOutRange = true;
|
||||
}
|
||||
}
|
||||
// range check: can't apply after end of result
|
||||
if (!ctx.afterOutRange) {
|
||||
int beginAt = ctx.defaultPosition + moreDelta + delta.getSource().size() - fuzz;
|
||||
// We can't apply patch before end of last patch.
|
||||
if (ctx.result.size() < beginAt) {
|
||||
ctx.afterOutRange = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx.beforeOutRange) {
|
||||
VerifyChunk before = delta.getSource().verifyChunk(ctx.result, fuzz, ctx.defaultPosition - moreDelta);
|
||||
if (before == VerifyChunk.OK) {
|
||||
return ctx.defaultPosition - moreDelta;
|
||||
}
|
||||
}
|
||||
if (!ctx.afterOutRange) {
|
||||
VerifyChunk after = delta.getSource().verifyChunk(ctx.result, fuzz, ctx.defaultPosition + moreDelta);
|
||||
if (after == VerifyChunk.OK) {
|
||||
return ctx.defaultPosition + moreDelta;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Patch behaviour to throw an exception for pathching conflicts.
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.github.difflib.algorithm.myers;
|
||||
|
||||
import com.github.difflib.patch.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -9,8 +10,13 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -57,6 +63,104 @@ public class WithMeyersDiffWithLinearSpacePatchTest {
|
||||
}
|
||||
}
|
||||
|
||||
// region testPatch_fuzzyApply utils
|
||||
|
||||
private List<String> intRange(int count) {
|
||||
return IntStream.range(0, count)
|
||||
.mapToObj(Integer::toString)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private final List<String> join(List<String>... lists) {
|
||||
return Arrays.stream(lists).flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static class FuzzyApplyTestPair {
|
||||
public final List<String> from;
|
||||
public final List<String> to;
|
||||
public final int requiredFuzz;
|
||||
|
||||
private FuzzyApplyTestPair(List<String> from, List<String> to, int requiredFuzz) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.requiredFuzz = requiredFuzz;
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
@Test
|
||||
public void fuzzyApply() throws PatchFailedException {
|
||||
Patch<String> patch = new Patch<>();
|
||||
List<String> deltaFrom = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee", "fff");
|
||||
List<String> deltaTo = Arrays.asList("aaa", "bbb", "cxc", "dxd", "eee", "fff");
|
||||
patch.addDelta(new ChangeDelta<>(
|
||||
new Chunk<>(6, deltaFrom),
|
||||
new Chunk<>(6, deltaTo)));
|
||||
|
||||
//noinspection unchecked
|
||||
List<String>[] moves = new List[] {
|
||||
intRange(6), // no patch move
|
||||
intRange(3), // forward patch move
|
||||
intRange(9), // backward patch move
|
||||
intRange(0), // apply to the first
|
||||
};
|
||||
|
||||
for (FuzzyApplyTestPair pair : FUZZY_APPLY_TEST_PAIRS) {
|
||||
for (List<String> move : moves) {
|
||||
List<String> from = join(move, pair.from);
|
||||
List<String> to = join(move, pair.to);
|
||||
|
||||
for (int i = 0; i < pair.requiredFuzz; i++) {
|
||||
int maxFuzz = i;
|
||||
assertThrows(PatchFailedException.class, () ->
|
||||
patch.applyFuzzy(from, maxFuzz),
|
||||
() -> "fail for " + from + " -> " + to + " for fuzz " + maxFuzz + " required " + pair.requiredFuzz);
|
||||
}
|
||||
for (int i = pair.requiredFuzz; i < 4; i++) {
|
||||
int maxFuzz = i;
|
||||
assertEquals(to, patch.applyFuzzy(from, maxFuzz),
|
||||
() -> "with " + maxFuzz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fuzzyApplyTwoSideBySidePatches() throws PatchFailedException {
|
||||
Patch<String> patch = new Patch<>();
|
||||
List<String> deltaFrom = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee", "fff");
|
||||
List<String> deltaTo = Arrays.asList("aaa", "bbb", "cxc", "dxd", "eee", "fff");
|
||||
patch.addDelta(new ChangeDelta<>(
|
||||
new Chunk<>(0, deltaFrom),
|
||||
new Chunk<>(0, deltaTo)));
|
||||
patch.addDelta(new ChangeDelta<>(
|
||||
new Chunk<>(6, deltaFrom),
|
||||
new Chunk<>(6, deltaTo)));
|
||||
|
||||
|
||||
assertEquals(join(deltaTo, deltaTo), patch.applyFuzzy(join(deltaFrom, deltaFrom), 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fuzzyApplyToNearest() throws PatchFailedException {
|
||||
Patch<String> patch = new Patch<>();
|
||||
List<String> deltaFrom = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee", "fff");
|
||||
List<String> deltaTo = Arrays.asList("aaa", "bbb", "cxc", "dxd", "eee", "fff");
|
||||
patch.addDelta(new ChangeDelta<>(
|
||||
new Chunk<>(0, deltaFrom),
|
||||
new Chunk<>(0, deltaTo)));
|
||||
patch.addDelta(new ChangeDelta<>(
|
||||
new Chunk<>(10, deltaFrom),
|
||||
new Chunk<>(10, deltaTo)));
|
||||
|
||||
assertEquals(join(deltaTo, deltaFrom, deltaTo),
|
||||
patch.applyFuzzy(join(deltaFrom, deltaFrom, deltaFrom), 0));
|
||||
assertEquals(join(intRange(1), deltaTo, deltaFrom, deltaTo),
|
||||
patch.applyFuzzy(join(intRange(1), deltaFrom, deltaFrom, deltaFrom), 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch_Serializable() throws IOException, ClassNotFoundException {
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
@@ -101,4 +205,190 @@ public class WithMeyersDiffWithLinearSpacePatchTest {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
static class FuzzyApplyTestDataGenerator {
|
||||
private static String createList(List<String> values) {
|
||||
return values.stream()
|
||||
.map(x -> '"' + x + '"')
|
||||
.collect(Collectors.joining(", ", "Arrays.asList(", ")"));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String[] deltaFrom = new String[] { "aaa", "bbb", "ccc", "ddd", "eee", "fff" };
|
||||
String[] deltaTo = new String[] { "aaa", "bbb", "cxc", "dxd", "eee", "fff" };
|
||||
|
||||
List<FuzzyApplyTestPair> pairs = new ArrayList<>();
|
||||
|
||||
// create test data.
|
||||
// Brute-force search
|
||||
String[] changedValue = new String[]{"axa", "bxb", "czc", "dzd", "exe", "fxf"};
|
||||
for (int i = 0; i < 1 << 6; i++) {
|
||||
if ((i & 0b001100) != 0 && (i & 0b001100) != 0b001100) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] from = deltaFrom.clone();
|
||||
String[] to = deltaTo.clone();
|
||||
for (int j = 0; j < 6; j++) {
|
||||
if ((i & (1 << j)) != 0) {
|
||||
from[j] = changedValue[j];
|
||||
to[j] = changedValue[j];
|
||||
}
|
||||
}
|
||||
|
||||
int requiredFuzz;
|
||||
if ((i & 0b001100) != 0) {
|
||||
requiredFuzz = 3;
|
||||
} else if ((i & 0b010010) != 0) {
|
||||
requiredFuzz = 2;
|
||||
} else if ((i & 0b100001) != 0) {
|
||||
requiredFuzz = 1;
|
||||
} else {
|
||||
requiredFuzz = 0;
|
||||
}
|
||||
|
||||
pairs.add(new FuzzyApplyTestPair(Arrays.asList(from), Arrays.asList(to), requiredFuzz));
|
||||
}
|
||||
pairs.sort(Comparator.comparingInt(a -> a.requiredFuzz));
|
||||
System.out.println("FuzzyApplyTestPair[] pairs = new FuzzyApplyTestPair[] {");
|
||||
for (FuzzyApplyTestPair pair : pairs) {
|
||||
System.out.println(" new FuzzyApplyTestPair(");
|
||||
System.out.println(" " + createList(pair.from) + ",");
|
||||
System.out.println(" " + createList(pair.to) + ",");
|
||||
System.out.println(" " + pair.requiredFuzz + "),");
|
||||
}
|
||||
System.out.println("};");
|
||||
}
|
||||
}
|
||||
|
||||
private static final FuzzyApplyTestPair[] FUZZY_APPLY_TEST_PAIRS = new FuzzyApplyTestPair[] {
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee", "fff"),
|
||||
Arrays.asList("aaa", "bbb", "cxc", "dxd", "eee", "fff"),
|
||||
0),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bbb", "ccc", "ddd", "eee", "fff"),
|
||||
Arrays.asList("axa", "bbb", "cxc", "dxd", "eee", "fff"),
|
||||
1),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee", "fxf"),
|
||||
Arrays.asList("aaa", "bbb", "cxc", "dxd", "eee", "fxf"),
|
||||
1),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bbb", "ccc", "ddd", "eee", "fxf"),
|
||||
Arrays.asList("axa", "bbb", "cxc", "dxd", "eee", "fxf"),
|
||||
1),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bxb", "ccc", "ddd", "eee", "fff"),
|
||||
Arrays.asList("aaa", "bxb", "cxc", "dxd", "eee", "fff"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bxb", "ccc", "ddd", "eee", "fff"),
|
||||
Arrays.asList("axa", "bxb", "cxc", "dxd", "eee", "fff"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bbb", "ccc", "ddd", "exe", "fff"),
|
||||
Arrays.asList("aaa", "bbb", "cxc", "dxd", "exe", "fff"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bbb", "ccc", "ddd", "exe", "fff"),
|
||||
Arrays.asList("axa", "bbb", "cxc", "dxd", "exe", "fff"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bxb", "ccc", "ddd", "exe", "fff"),
|
||||
Arrays.asList("aaa", "bxb", "cxc", "dxd", "exe", "fff"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bxb", "ccc", "ddd", "exe", "fff"),
|
||||
Arrays.asList("axa", "bxb", "cxc", "dxd", "exe", "fff"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bxb", "ccc", "ddd", "eee", "fxf"),
|
||||
Arrays.asList("aaa", "bxb", "cxc", "dxd", "eee", "fxf"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bxb", "ccc", "ddd", "eee", "fxf"),
|
||||
Arrays.asList("axa", "bxb", "cxc", "dxd", "eee", "fxf"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bbb", "ccc", "ddd", "exe", "fxf"),
|
||||
Arrays.asList("aaa", "bbb", "cxc", "dxd", "exe", "fxf"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bbb", "ccc", "ddd", "exe", "fxf"),
|
||||
Arrays.asList("axa", "bbb", "cxc", "dxd", "exe", "fxf"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bxb", "ccc", "ddd", "exe", "fxf"),
|
||||
Arrays.asList("aaa", "bxb", "cxc", "dxd", "exe", "fxf"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bxb", "ccc", "ddd", "exe", "fxf"),
|
||||
Arrays.asList("axa", "bxb", "cxc", "dxd", "exe", "fxf"),
|
||||
2),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bbb", "czc", "dzd", "eee", "fff"),
|
||||
Arrays.asList("aaa", "bbb", "czc", "dzd", "eee", "fff"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bbb", "czc", "dzd", "eee", "fff"),
|
||||
Arrays.asList("axa", "bbb", "czc", "dzd", "eee", "fff"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bxb", "czc", "dzd", "eee", "fff"),
|
||||
Arrays.asList("aaa", "bxb", "czc", "dzd", "eee", "fff"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bxb", "czc", "dzd", "eee", "fff"),
|
||||
Arrays.asList("axa", "bxb", "czc", "dzd", "eee", "fff"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bbb", "czc", "dzd", "exe", "fff"),
|
||||
Arrays.asList("aaa", "bbb", "czc", "dzd", "exe", "fff"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bbb", "czc", "dzd", "exe", "fff"),
|
||||
Arrays.asList("axa", "bbb", "czc", "dzd", "exe", "fff"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bxb", "czc", "dzd", "exe", "fff"),
|
||||
Arrays.asList("aaa", "bxb", "czc", "dzd", "exe", "fff"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bxb", "czc", "dzd", "exe", "fff"),
|
||||
Arrays.asList("axa", "bxb", "czc", "dzd", "exe", "fff"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bbb", "czc", "dzd", "eee", "fxf"),
|
||||
Arrays.asList("aaa", "bbb", "czc", "dzd", "eee", "fxf"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bbb", "czc", "dzd", "eee", "fxf"),
|
||||
Arrays.asList("axa", "bbb", "czc", "dzd", "eee", "fxf"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bxb", "czc", "dzd", "eee", "fxf"),
|
||||
Arrays.asList("aaa", "bxb", "czc", "dzd", "eee", "fxf"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bxb", "czc", "dzd", "eee", "fxf"),
|
||||
Arrays.asList("axa", "bxb", "czc", "dzd", "eee", "fxf"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bbb", "czc", "dzd", "exe", "fxf"),
|
||||
Arrays.asList("aaa", "bbb", "czc", "dzd", "exe", "fxf"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bbb", "czc", "dzd", "exe", "fxf"),
|
||||
Arrays.asList("axa", "bbb", "czc", "dzd", "exe", "fxf"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("aaa", "bxb", "czc", "dzd", "exe", "fxf"),
|
||||
Arrays.asList("aaa", "bxb", "czc", "dzd", "exe", "fxf"),
|
||||
3),
|
||||
new FuzzyApplyTestPair(
|
||||
Arrays.asList("axa", "bxb", "czc", "dzd", "exe", "fxf"),
|
||||
Arrays.asList("axa", "bxb", "czc", "dzd", "exe", "fxf"),
|
||||
3),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.github.difflib.patch;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class ChunkTest {
|
||||
@Test
|
||||
void verifyChunk() throws PatchFailedException {
|
||||
Chunk<Character> chunk = new Chunk<>(7, toCharList("test"));
|
||||
|
||||
// normal check
|
||||
assertEquals(VerifyChunk.OK,
|
||||
chunk.verifyChunk(toCharList("prefix test suffix")));
|
||||
assertEquals(VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET,
|
||||
chunk.verifyChunk(toCharList("prefix es suffix"), 0, 7));
|
||||
|
||||
// position
|
||||
assertEquals(VerifyChunk.OK,
|
||||
chunk.verifyChunk(toCharList("short test suffix"), 0, 6));
|
||||
assertEquals(VerifyChunk.OK,
|
||||
chunk.verifyChunk(toCharList("loonger test suffix"), 0, 8));
|
||||
assertEquals(VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET,
|
||||
chunk.verifyChunk(toCharList("prefix test suffix"), 0, 6));
|
||||
assertEquals(VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET,
|
||||
chunk.verifyChunk(toCharList("prefix test suffix"), 0, 8));
|
||||
|
||||
// fuzz
|
||||
assertEquals(VerifyChunk.OK,
|
||||
chunk.verifyChunk(toCharList("prefix test suffix"), 1, 7));
|
||||
assertEquals(VerifyChunk.OK,
|
||||
chunk.verifyChunk(toCharList("prefix es suffix"), 1, 7));
|
||||
assertEquals(VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET,
|
||||
chunk.verifyChunk(toCharList("prefix suffix"), 1, 7));
|
||||
}
|
||||
|
||||
private List<Character> toCharList(String str) {
|
||||
return str.chars().mapToObj(x -> (char) x).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user