mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
feat(diffrow): add processEqualities hook and ensure equalities are processed for unchanged lines (Fixes #219) (#224)
- Introduces a new protected method `processEqualities(String)` in DiffRowGenerator - Builder exposes `.processEqualities(Function<String,String>)` - Equal (unchanged) lines now invoke processEqualities() - Inline diffs remain unchanged (as expected in Option 3) - Added new test suite DiffRowGeneratorEqualitiesTest - Updated documentation and Javadoc for new extension point - Fixes #219 (HTML escaping issue when inline diff by word) Co-authored-by: Tushar Soni <tushar.soni@siemens.com>
This commit is contained in:
@@ -189,6 +189,8 @@ public final class DiffRowGenerator {
|
||||
private final Function<String, String> lineNormalizer;
|
||||
private final Function<String, String> processDiffs;
|
||||
private final Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> inlineDeltaMerger;
|
||||
// processor for equal (unchanged) lines
|
||||
private final Function<String, String> equalityProcessor;
|
||||
|
||||
private final boolean showInlineDiffs;
|
||||
private final boolean replaceOriginalLinefeedInChangesWithSpaces;
|
||||
@@ -214,6 +216,7 @@ public final class DiffRowGenerator {
|
||||
lineNormalizer = builder.lineNormalizer;
|
||||
processDiffs = builder.processDiffs;
|
||||
inlineDeltaMerger = builder.inlineDeltaMerger;
|
||||
equalityProcessor = builder.equalityProcessor;
|
||||
|
||||
replaceOriginalLinefeedInChangesWithSpaces = builder.replaceOriginalLinefeedInChangesWithSpaces;
|
||||
|
||||
@@ -262,7 +265,8 @@ public final class DiffRowGenerator {
|
||||
|
||||
// Copy the final matching chunk if any.
|
||||
for (String line : original.subList(endPos, original.size())) {
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||
String processed = processEqualities(line);
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, processed, processed));
|
||||
}
|
||||
return diffRows;
|
||||
}
|
||||
@@ -276,7 +280,8 @@ public final class DiffRowGenerator {
|
||||
Chunk<String> rev = delta.getTarget();
|
||||
|
||||
for (String line : original.subList(endPos, orig.getPosition())) {
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||
String processed = processEqualities(line);
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, processed, processed));
|
||||
}
|
||||
|
||||
switch (delta.getType()) {
|
||||
@@ -496,6 +501,19 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for processing equal (unchanged) text segments.
|
||||
* Delegates to the builder-configured equalityProcessor if present.
|
||||
*
|
||||
* @author tusharsoni52
|
||||
* @param text
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
protected String processEqualities(final String text) {
|
||||
return equalityProcessor != null ? equalityProcessor.apply(text) : text;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class used for building the DiffRowGenerator.
|
||||
*
|
||||
@@ -521,6 +539,8 @@ public final class DiffRowGenerator {
|
||||
private boolean replaceOriginalLinefeedInChangesWithSpaces = false;
|
||||
private Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> inlineDeltaMerger =
|
||||
DEFAULT_INLINE_DELTA_MERGER;
|
||||
// Processor for equalities
|
||||
private Function<String, String> equalityProcessor = null;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
@@ -613,6 +633,20 @@ public final class DiffRowGenerator {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processor for equal (unchanged) text parts.
|
||||
* Allows applying the same escaping/transformation as for diffs.
|
||||
*
|
||||
* @author tusharsoni52
|
||||
* @param equalityProcessor
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public Builder processEqualities(Function<String, String> equalityProcessor) {
|
||||
this.equalityProcessor = equalityProcessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the column width of generated lines of original and revised
|
||||
* texts.
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.github.difflib.text;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class DiffRowGeneratorEqualitiesTest {
|
||||
|
||||
@Test
|
||||
public void testDefaultEqualityProcessingLeavesTextUnchanged() {
|
||||
DiffRowGenerator generator =
|
||||
DiffRowGenerator.create().showInlineDiffs(false).build();
|
||||
|
||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("hello world"), Arrays.asList("hello world"));
|
||||
|
||||
assertEquals(1, rows.size());
|
||||
assertEquals("hello world", rows.get(0).getOldLine());
|
||||
assertEquals("hello world", rows.get(0).getNewLine());
|
||||
assertEquals(DiffRow.Tag.EQUAL, rows.get(0).getTag());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomEqualityProcessingIsApplied() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(false)
|
||||
.processEqualities(text -> "[" + text + "]")
|
||||
.build();
|
||||
|
||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("A", "B"), Arrays.asList("A", "B"));
|
||||
|
||||
assertEquals(2, rows.size());
|
||||
assertEquals("[A]", rows.get(0).getOldLine());
|
||||
assertEquals("[B]", rows.get(1).getOldLine());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that processEqualities can be used to HTML-escape unchanged
|
||||
* lines while still working together with the default HTML-oriented
|
||||
* lineNormalizer.
|
||||
*/
|
||||
@Test
|
||||
public void testHtmlEscapingEqualitiesWorksWithDefaultNormalizer() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.inlineDiffByWord(true)
|
||||
.processEqualities(s -> s.replace("<", "<").replace(">", ">"))
|
||||
.build();
|
||||
|
||||
// both lines are equal -> Tag.EQUAL, processEqualities is invoked
|
||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("hello <world>"), Arrays.asList("hello <world>"));
|
||||
|
||||
DiffRow row = rows.get(0);
|
||||
|
||||
assertTrue(row.getOldLine().contains("<world>"));
|
||||
assertTrue(row.getNewLine().contains("<world>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures equalities are processed while inline diff markup is still
|
||||
* present somewhere in the line.
|
||||
*/
|
||||
@Test
|
||||
public void testEqualitiesProcessedButInlineDiffStillPresent() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.inlineDiffByWord(true)
|
||||
.processEqualities(s -> "(" + s + ")")
|
||||
.build();
|
||||
|
||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("hello world"), Arrays.asList("hello there"));
|
||||
|
||||
DiffRow row = rows.get(0);
|
||||
|
||||
System.out.println("OLD = " + row.getOldLine());
|
||||
System.out.println("NEW = " + row.getNewLine());
|
||||
|
||||
// Row must be CHANGE
|
||||
assertEquals(DiffRow.Tag.CHANGE, row.getTag());
|
||||
|
||||
// Inline diff markup must appear
|
||||
assertTrue(
|
||||
row.getOldLine().contains("span") || row.getNewLine().contains("span"),
|
||||
"Expected inline <span> diff markup in old or new line");
|
||||
|
||||
// Equalities inside CHANGE row must NOT be wrapped by processEqualities
|
||||
// Option 3 does NOT modify inline equalities
|
||||
assertTrue(row.getOldLine().startsWith("hello "), "Equal (unchanged) inline segment should remain unchanged");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user