Skip to content
Snippets Groups Projects
Commit 5c2d98b1 authored by Emmanuel Bourg's avatar Emmanuel Bourg
Browse files

New upstream version 4.8

parent 671e9a74
No related branches found
No related tags found
No related merge requests found
Showing
with 468 additions and 59 deletions
......@@ -2,3 +2,5 @@
build/
nbproject/
target/
*.iml
......@@ -5,7 +5,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
This project uses a custom versioning scheme (and not [Semantic Versioning](https://semver.org/spec/v2.0.0.html)).
## [Unreleased]
## [unreleased]
### Changed
## [4.8]
### Changed
* some bugfixes regarding unified diff writer
* UnifiedDiffReader improved for **deleted file mode** and better timestamp recognition
* UnifiedDiffReader improved for **new file mode** and better timestamp recognition
## [4.7]
### Changed
* minor bug fixes
* optional include equal parts of original and revised data
......
......@@ -14,6 +14,10 @@ Main reason to build this library was the lack of easy-to-use libraries with all
**This is originally a fork of java-diff-utils from Google Code Archive.**
## API
Javadocs of the actual release version: [JavaDocs java-diff-utils](https://java-diff-utils.github.io/java-diff-utils/4.7/docs/api/)
## Examples
Look [here](https://github.com/wumpz/java-diff-utils/wiki) to find more helpful informations and examples.
......
theme: jekyll-theme-minimal
\ No newline at end of file
......@@ -4,7 +4,7 @@
<parent>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils-parent</artifactId>
<version>4.7</version>
<version>4.8</version>
</parent>
<artifactId>java-diff-utils-jgit</artifactId>
<name>java-diff-utils-jgit</name>
......@@ -20,7 +20,7 @@
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.4.1.201607150455-r</version>
<version>5.8.1.202007141445-r</version>
<exclusions>
<exclusion>
<groupId>com.googlecode.javaewah</groupId>
......
......@@ -82,6 +82,6 @@ public class HistogramDiffTest {
assertEquals(revList, patched);
System.out.println(logdata);
assertEquals(17, logdata.size());
assertEquals(19, logdata.size());
}
}
......@@ -7,7 +7,7 @@
<parent>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils-parent</artifactId>
<version>4.7</version>
<version>4.8</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......@@ -51,6 +51,16 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<trimStackTrace>false</trimStackTrace>
<systemPropertyVariables>
<java.util.logging.config.file>target/test-classes/logging.properties</java.util.logging.config.file>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
......
......@@ -33,6 +33,7 @@ public final class UnifiedDiffUtils {
private static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern
.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@$");
private static final String NULL_FILE_INDICATOR = "/dev/null";
/**
* Parse the given text in unified format and creates the list of deltas for it.
......@@ -97,19 +98,31 @@ public final class UnifiedDiffUtils {
List<String> oldChunkLines = new ArrayList<>();
List<String> newChunkLines = new ArrayList<>();
List<Integer> removePosition = new ArrayList<>();
List<Integer> addPosition = new ArrayList<>();
int removeNum = 0;
int addNum = 0;
for (String[] raw_line : rawChunk) {
tag = raw_line[0];
rest = raw_line[1];
if (" ".equals(tag) || "-".equals(tag)) {
removeNum++;
oldChunkLines.add(rest);
if ("-".equals(tag)) {
removePosition.add(old_ln - 1 + removeNum);
}
}
if (" ".equals(tag) || "+".equals(tag)) {
addNum++;
newChunkLines.add(rest);
if ("+".equals(tag)) {
addPosition.add(new_ln - 1 + addNum);
}
}
}
patch.addDelta(new ChangeDelta<>(new Chunk<>(
old_ln - 1, oldChunkLines), new Chunk<>(
new_ln - 1, newChunkLines)));
old_ln - 1, oldChunkLines, removePosition), new Chunk<>(
new_ln - 1, newChunkLines, addPosition)));
rawChunk.clear();
}
}
......@@ -131,8 +144,8 @@ public final class UnifiedDiffUtils {
int contextSize) {
if (!patch.getDeltas().isEmpty()) {
List<String> ret = new ArrayList<>();
ret.add("--- " + Optional.ofNullable(originalFileName).orElse(""));
ret.add("+++ " + Optional.ofNullable(revisedFileName).orElse(""));
ret.add("--- " + Optional.ofNullable(originalFileName).orElse(NULL_FILE_INDICATOR));
ret.add("+++ " + Optional.ofNullable(revisedFileName).orElse(NULL_FILE_INDICATOR));
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
patch.getDeltas());
......
......@@ -37,16 +37,19 @@ public final class Chunk<T> {
private final int position;
private List<T> lines;
private final List<Integer> changePosition;
/**
* Creates a chunk and saves a copy of affected lines
*
* @param position the start position
* @param lines the affected lines
* @param changePosition the positions of changed lines
*/
public Chunk(int position, List<T> lines) {
public Chunk(int position, List<T> lines, List<Integer> changePosition) {
this.position = position;
this.lines = new ArrayList<>(lines);
this.changePosition = changePosition;
}
/**
......@@ -55,9 +58,31 @@ public final class Chunk<T> {
* @param position the start position
* @param lines the affected lines
*/
public Chunk(int position, T[] lines) {
public Chunk(int position, List<T> lines) {
this(position, lines, null);
}
/**
* Creates a chunk and saves a copy of affected lines
*
* @param position the start position
* @param lines the affected lines
* @param changePosition the positions of changed lines
*/
public Chunk(int position, T[] lines, List<Integer> changePosition) {
this.position = position;
this.lines = Arrays.asList(lines);
this.changePosition = changePosition;
}
/**
* Creates a chunk and saves a copy of affected lines
*
* @param position the start position
* @param lines the affected lines
*/
public Chunk(int position, T[] lines) {
this(position, lines, null);
}
/**
......@@ -96,6 +121,13 @@ public final class Chunk<T> {
return lines;
}
/**
* @return the positions of changed lines of chunk in the text
*/
public List<Integer> getChangePosition() {
return changePosition;
}
public int size() {
return lines.size();
}
......
......@@ -16,7 +16,18 @@
package com.github.difflib.patch;
/**
* Specifies the type of the delta.
* Specifies the type of the delta. There are three types of modifications from
* the original to get the revised text.
*
* CHANGE: a block of data of the original is replaced by another block of data.
* DELETE: a block of data of the original is removed
* INSERT: at a position of the original a block of data is inserted
*
* to be complete there is also
*
* EQUAL: a block of data of original and the revised text is equal
*
* which is no change at all.
*
*/
public enum DeltaType {
......
......@@ -61,6 +61,7 @@ public final class DiffRowGenerator {
}
return list;
};
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
/**
......@@ -106,7 +107,7 @@ public final class DiffRowGenerator {
*/
static void wrapInTag(List<String> sequence, int startPosition,
int endPosition, Tag tag, BiFunction<Tag, Boolean, String> tagGenerator,
Function<String, String> processDiffs) {
Function<String, String> processDiffs, boolean replaceLinefeedWithSpace) {
int endPos = endPosition;
while (endPos >= startPosition) {
......@@ -115,6 +116,9 @@ public final class DiffRowGenerator {
while (endPos > startPosition) {
if (!"\n".equals(sequence.get(endPos - 1))) {
break;
} else if (replaceLinefeedWithSpace) {
sequence.set(endPos - 1, " ");
break;
}
endPos--;
}
......@@ -133,7 +137,11 @@ public final class DiffRowGenerator {
//search position for end tag
while (endPos > startPosition) {
if ("\n".equals(sequence.get(endPos - 1))) {
break;
if (replaceLinefeedWithSpace) {
sequence.set(endPos - 1, " ");
} else {
break;
}
}
if (processDiffs != null) {
sequence.set(endPos - 1,
......@@ -159,6 +167,7 @@ public final class DiffRowGenerator {
private final Function<String, String> processDiffs;
private final boolean showInlineDiffs;
private final boolean replaceOriginalLinefeedInChangesWithSpaces;
private DiffRowGenerator(Builder builder) {
showInlineDiffs = builder.showInlineDiffs;
......@@ -178,6 +187,8 @@ public final class DiffRowGenerator {
reportLinesUnchanged = builder.reportLinesUnchanged;
lineNormalizer = builder.lineNormalizer;
processDiffs = builder.processDiffs;
replaceOriginalLinefeedInChangesWithSpaces = builder.replaceOriginalLinefeedInChangesWithSpaces;
Objects.requireNonNull(inlineDiffSplitter);
Objects.requireNonNull(lineNormalizer);
......@@ -313,7 +324,7 @@ public final class DiffRowGenerator {
if (inlineDelta.getType() == DeltaType.DELETE) {
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
.getPosition()
+ inlineOrig.size(), Tag.DELETE, oldTag, processDiffs);
+ inlineOrig.size(), Tag.DELETE, oldTag, processDiffs, replaceOriginalLinefeedInChangesWithSpaces && mergeOriginalRevised);
} else if (inlineDelta.getType() == DeltaType.INSERT) {
if (mergeOriginalRevised) {
origList.addAll(inlineOrig.getPosition(),
......@@ -321,11 +332,11 @@ public final class DiffRowGenerator {
inlineRev.getPosition() + inlineRev.size()));
wrapInTag(origList, inlineOrig.getPosition(),
inlineOrig.getPosition() + inlineRev.size(),
Tag.INSERT, newTag, processDiffs);
Tag.INSERT, newTag, processDiffs, false);
} else {
wrapInTag(revList, inlineRev.getPosition(),
inlineRev.getPosition() + inlineRev.size(),
Tag.INSERT, newTag, processDiffs);
Tag.INSERT, newTag, processDiffs, false);
}
} else if (inlineDelta.getType() == DeltaType.CHANGE) {
if (mergeOriginalRevised) {
......@@ -334,15 +345,15 @@ public final class DiffRowGenerator {
inlineRev.getPosition() + inlineRev.size()));
wrapInTag(origList, inlineOrig.getPosition() + inlineOrig.size(),
inlineOrig.getPosition() + inlineOrig.size() + inlineRev.size(),
Tag.CHANGE, newTag, processDiffs);
Tag.CHANGE, newTag, processDiffs, false);
} else {
wrapInTag(revList, inlineRev.getPosition(),
inlineRev.getPosition() + inlineRev.size(),
Tag.CHANGE, newTag, processDiffs);
Tag.CHANGE, newTag, processDiffs, false);
}
wrapInTag(origList, inlineOrig.getPosition(),
inlineOrig.getPosition() + inlineOrig.size(),
Tag.CHANGE, oldTag, processDiffs);
Tag.CHANGE, oldTag, processDiffs, replaceOriginalLinefeedInChangesWithSpaces && mergeOriginalRevised);
}
}
StringBuilder origResult = new StringBuilder();
......@@ -385,10 +396,10 @@ public final class DiffRowGenerator {
private boolean showInlineDiffs = false;
private boolean ignoreWhiteSpaces = false;
private BiFunction<Tag, Boolean, String> oldTag =
(tag, f) -> f ? "<span class=\"editOldInline\">" : "</span>";
private BiFunction<Tag, Boolean, String> newTag =
(tag, f) -> f ? "<span class=\"editNewInline\">" : "</span>";
private BiFunction<Tag, Boolean, String> oldTag
= (tag, f) -> f ? "<span class=\"editOldInline\">" : "</span>";
private BiFunction<Tag, Boolean, String> newTag
= (tag, f) -> f ? "<span class=\"editNewInline\">" : "</span>";
private int columnWidth = 0;
private boolean mergeOriginalRevised = false;
......@@ -397,6 +408,7 @@ public final class DiffRowGenerator {
private Function<String, String> lineNormalizer = LINE_NORMALIZER_FOR_HTML;
private Function<String, String> processDiffs = null;
private BiPredicate<String, String> equalizer = null;
private boolean replaceOriginalLinefeedInChangesWithSpaces = false;
private Builder() {
}
......@@ -445,7 +457,7 @@ public final class DiffRowGenerator {
this.oldTag = generator;
return this;
}
/**
* Generator for Old-Text-Tags.
*
......@@ -467,7 +479,7 @@ public final class DiffRowGenerator {
this.newTag = generator;
return this;
}
/**
* Generator for New-Text-Tags.
*
......@@ -494,8 +506,8 @@ public final class DiffRowGenerator {
/**
* Set the column width of generated lines of original and revised texts.
*
* @param width the width to set. Making it < 0 doesn't have any sense. Default 80. @return
* builder with config ured ignoreBlankLines parameter
* @param width the width to set. Making it < 0 doesn't make any sense. Default 80.
* @return builder with config of column width
*/
public Builder columnWidth(int width) {
if (width >= 0) {
......@@ -575,5 +587,17 @@ public final class DiffRowGenerator {
this.equalizer = equalizer;
return this;
}
/**
* Sometimes it happens that a change contains multiple lines. If there is no correspondence
* in old and new. To keep the merged line more readable the linefeeds could be replaced
* by spaces.
* @param replace
* @return
*/
public Builder replaceOriginalLinefeedInChangesWithSpaces(boolean replace) {
this.replaceOriginalLinefeedInChangesWithSpaces = replace;
return this;
}
}
}
......@@ -29,6 +29,8 @@ public final class UnifiedDiffFile {
private String toFile;
private String toTimestamp;
private String index;
private String newFileMode;
private String deletedFileMode;
private Patch<String> patch = new Patch<>();
public String getDiffCommand() {
......@@ -92,4 +94,20 @@ public final class UnifiedDiffFile {
file.patch = patch;
return file;
}
public void setNewFileMode(String newFileMode) {
this.newFileMode = newFileMode;
}
public String getNewFileMode() {
return newFileMode;
}
public String getDeletedFileMode() {
return deletedFileMode;
}
public void setDeletedFileMode(String deletedFileMode) {
this.deletedFileMode = deletedFileMode;
}
}
......@@ -39,7 +39,7 @@ import java.util.regex.Pattern;
public final class UnifiedDiffReader {
static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
static final Pattern TIMESTAMP_REGEXP = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3,})");
static final Pattern TIMESTAMP_REGEXP = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3,})(?: [+-]\\d+)?");
private final InternalUnifiedDiffReader READER;
private final UnifiedDiff data = new UnifiedDiff();
......@@ -49,6 +49,10 @@ public final class UnifiedDiffReader {
private final UnifiedDiffLine FROM_FILE = new UnifiedDiffLine(true, "^---\\s", this::processFromFile);
private final UnifiedDiffLine TO_FILE = new UnifiedDiffLine(true, "^\\+\\+\\+\\s", this::processToFile);
private final UnifiedDiffLine NEW_FILE_MODE = new UnifiedDiffLine(true, "^new\\sfile\\smode\\s(\\d+)", this::processNewFileMode);
private final UnifiedDiffLine DELETED_FILE_MODE = new UnifiedDiffLine(true, "^deleted\\sfile\\smode\\s(\\d+)", this::processDeletedFileMode);
private final UnifiedDiffLine CHUNK = new UnifiedDiffLine(false, UNIFIED_DIFF_CHUNK_REGEXP, this::processChunk);
private final UnifiedDiffLine LINE_NORMAL = new UnifiedDiffLine("^\\s", this::processNormalLine);
private final UnifiedDiffLine LINE_DEL = new UnifiedDiffLine("^-", this::processDelLine);
......@@ -66,13 +70,14 @@ public final class UnifiedDiffReader {
// [/^-/, del], [/^\+/, add], [/^\\ No newline at end of file$/, eof]];
private UnifiedDiff parse() throws IOException, UnifiedDiffParserException {
String headerTxt = "";
LOG.log(Level.INFO, "header parsing");
LOG.log(Level.FINE, "header parsing");
String line = null;
while (READER.ready()) {
line = READER.readLine();
LOG.log(Level.INFO, "parsing line {0}", line);
LOG.log(Level.FINE, "parsing line {0}", line);
if (DIFF_COMMAND.validLine(line) || INDEX.validLine(line)
|| FROM_FILE.validLine(line) || TO_FILE.validLine(line)) {
|| FROM_FILE.validLine(line) || TO_FILE.validLine(line)
|| NEW_FILE_MODE.validLine(line)) {
break;
} else {
headerTxt += line + "\n";
......@@ -85,26 +90,28 @@ public final class UnifiedDiffReader {
while (line != null) {
if (!CHUNK.validLine(line)) {
initFileIfNecessary();
while (!CHUNK.validLine(line)) {
if (processLine(line, DIFF_COMMAND, INDEX, FROM_FILE, TO_FILE) == false) {
while (line != null && !CHUNK.validLine(line)) {
if (processLine(line, DIFF_COMMAND, INDEX, FROM_FILE, TO_FILE, NEW_FILE_MODE, DELETED_FILE_MODE) == false) {
throw new UnifiedDiffParserException("expected file start line not found");
}
line = READER.readLine();
}
}
processLine(line, CHUNK);
while ((line = READER.readLine()) != null) {
if (processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL) == false) {
throw new UnifiedDiffParserException("expected data line not found");
}
if ((originalTxt.size() == old_size && revisedTxt.size() == new_size)
|| (old_size==0 && new_size==0 && originalTxt.size() == this.old_ln
if (line != null) {
processLine(line, CHUNK);
while ((line = READER.readLine()) != null) {
if (processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL) == false) {
throw new UnifiedDiffParserException("expected data line not found");
}
if ((originalTxt.size() == old_size && revisedTxt.size() == new_size)
|| (old_size == 0 && new_size == 0 && originalTxt.size() == this.old_ln
&& revisedTxt.size() == this.new_ln)) {
finalizeChunk();
break;
finalizeChunk();
break;
}
}
line = READER.readLine();
}
line = READER.readLine();
if (line == null || line.startsWith("--")) {
break;
}
......@@ -113,7 +120,10 @@ public final class UnifiedDiffReader {
if (READER.ready()) {
String tailTxt = "";
while (READER.ready()) {
tailTxt += READER.readLine() + "\n";
if (tailTxt.length() > 0) {
tailTxt += "\n";
}
tailTxt += READER.readLine();
}
data.setTailTxt(tailTxt);
}
......@@ -137,13 +147,16 @@ public final class UnifiedDiffReader {
}
private boolean processLine(String line, UnifiedDiffLine... rules) throws UnifiedDiffParserException {
if (line == null) {
return false;
}
for (UnifiedDiffLine rule : rules) {
if (rule.processLine(line)) {
LOG.info(" >>> processed rule " + rule.toString());
LOG.fine(" >>> processed rule " + rule.toString());
return true;
}
}
LOG.info(" >>> no rule matched " + line);
LOG.warning(" >>> no rule matched " + line);
return false;
//throw new UnifiedDiffParserException("parsing error at line " + line);
}
......@@ -161,7 +174,7 @@ public final class UnifiedDiffReader {
private void processDiff(MatchResult match, String line) {
//initFileIfNecessary();
LOG.log(Level.INFO, "start {0}", line);
LOG.log(Level.FINE, "start {0}", line);
String[] fromTo = parseFileNames(READER.lastLine());
actualFile.setFromFile(fromTo[0]);
actualFile.setToFile(fromTo[1]);
......@@ -223,7 +236,7 @@ public final class UnifiedDiffReader {
private void processIndex(MatchResult match, String line) {
//initFileIfNecessary();
LOG.log(Level.INFO, "index {0}", line);
LOG.log(Level.FINE, "index {0}", line);
actualFile.setIndex(line.substring(6));
}
......@@ -239,14 +252,25 @@ public final class UnifiedDiffReader {
actualFile.setToTimestamp(extractTimestamp(line));
}
private void processNewFileMode(MatchResult match, String line) {
//initFileIfNecessary();
actualFile.setNewFileMode(match.group(1));
}
private void processDeletedFileMode(MatchResult match, String line) {
//initFileIfNecessary();
actualFile.setDeletedFileMode(match.group(1));
}
private String extractFileName(String _line) {
Matcher matcher = TIMESTAMP_REGEXP.matcher(_line);
String line = _line;
if (matcher.find()) {
line = line.substring(0, matcher.start());
}
line = line.split("\t")[0];
return line.substring(4).replaceFirst("^(a|b|old|new)(\\/)?", "")
.replace(TIMESTAMP_REGEXP.toString(), "").trim();
.trim();
}
private String extractTimestamp(String line) {
......
......@@ -59,7 +59,7 @@ public class UnifiedDiffWriter {
writer.accept("index " + file.getIndex());
}
writer.accept("--- " + file.getFromFile());
writer.accept("--- " + (file.getFromFile() == null ? "/dev/null" : file.getFromFile()));
if (file.getToFile() != null) {
writer.accept("+++ " + file.getToFile());
......@@ -96,7 +96,7 @@ public class UnifiedDiffWriter {
}
// don't forget to process the last set of Deltas
processDeltas(writer, originalLines, deltas, contextSize,
processDeltas(writer, originalLines, deltas, contextSize,
patchDeltas.size() == 1 && file.getFromFile() == null);
}
......@@ -156,7 +156,7 @@ public class UnifiedDiffWriter {
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
int intermediateStart = curDelta.getSource().getPosition()
+ curDelta.getSource().getLines().size();
for (line = intermediateStart; line < nextDelta.getSource().getPosition()
for (line = intermediateStart; line < nextDelta.getSource().getPosition()
&& line < origLines.size(); line++) {
// output the code between the last Delta and this one
buffer.add(" " + origLines.get(line));
......
package com.github.difflib;
import com.github.difflib.patch.Chunk;
import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException;
import java.io.BufferedReader;
......@@ -8,9 +9,11 @@ import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static java.util.stream.Collectors.joining;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.Test;
......@@ -119,13 +122,51 @@ public class GenerateUnifiedDiffTest {
List<String> udiff = UnifiedDiffUtils.generateUnifiedDiff(null, "revised",
original, patch, 10);
assertEquals("--- ", udiff.get(0));
assertEquals("--- /dev/null", udiff.get(0));
assertEquals("+++ revised", udiff.get(1));
assertEquals("@@ -0,0 +1,2 @@", udiff.get(2));
UnifiedDiffUtils.parseUnifiedDiff(udiff);
}
/**
* Issue 89
*/
@Test
public void testChagngePosition() throws IOException {
final List<String> patchLines = fileToLines(TestConstants.MOCK_FOLDER + "issue89_patch.txt");
final Patch<String> patch = UnifiedDiffUtils.parseUnifiedDiff(patchLines);
List<Integer> realRemoveListOne = Collections.singletonList(3);
List<Integer> realAddListOne = Arrays.asList(3, 7, 8, 9, 10, 11, 12, 13, 14);
validateChangePosition(patch, 0, realRemoveListOne, realAddListOne);
List<Integer> realRemoveListTwo = new ArrayList<>();
List<Integer> realAddListTwo = Arrays.asList(27, 28);
validateChangePosition(patch, 1, realRemoveListTwo, realAddListTwo);
}
private void validateChangePosition(Patch<String> patch, int index, List<Integer> realRemoveList,
List<Integer> realAddList ) {
final Chunk originChunk = patch.getDeltas().get(index).getSource();
List<Integer> removeList = originChunk.getChangePosition();
assertEquals(realRemoveList.size(), removeList.size());
for (Integer ele: realRemoveList) {
assertTrue(realRemoveList.contains(ele));
}
for (Integer ele: removeList) {
assertTrue(realAddList.contains(ele));
}
final Chunk targetChunk = patch.getDeltas().get(index).getTarget();
List<Integer> addList = targetChunk.getChangePosition();
assertEquals(realAddList.size(), addList.size());
for (Integer ele: realAddList) {
assertTrue(addList.contains(ele));
}
for (Integer ele: addList) {
assertTrue(realAddList.contains(ele));
}
}
private void verify(List<String> origLines, List<String> revLines,
String originalFile, String revisedFile) {
Patch<String> patch = DiffUtils.diff(origLines, revLines);
......
......@@ -3,10 +3,12 @@ package com.github.difflib.text;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
......@@ -498,4 +500,125 @@ public class DiffRowGeneratorTest {
assertEquals("This~//~**/**is~//~**/**a~//~**/**test~.~", rows.get(0).getOldLine());
}
@Test
public void testProblemTooManyDiffRowsIssue65() {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.reportLinesUnchanged(true)
.oldTag(f -> "~")
.newTag(f -> "**")
.mergeOriginalRevised(true)
.inlineDiffByWord(false)
.replaceOriginalLinefeedInChangesWithSpaces(true)
.build();
List<DiffRow> diffRows = generator.generateDiffRows(
Arrays.asList("Ich möchte nicht mit einem Bot sprechen.", "Ich soll das schon wieder wiederholen?"),
Arrays.asList("Ich möchte nicht mehr mit dir sprechen. Leite mich weiter.", "Kannst du mich zum Kundendienst weiterleiten?"));
print(diffRows);
assertThat(diffRows).hasSize(2);
}
@Test
public void testProblemTooManyDiffRowsIssue65_NoMerge() {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.reportLinesUnchanged(true)
.oldTag(f -> "~")
.newTag(f -> "**")
.mergeOriginalRevised(false)
.inlineDiffByWord(false)
.build();
List<DiffRow> diffRows = generator.generateDiffRows(
Arrays.asList("Ich möchte nicht mit einem Bot sprechen.", "Ich soll das schon wieder wiederholen?"),
Arrays.asList("Ich möchte nicht mehr mit dir sprechen. Leite mich weiter.", "Kannst du mich zum Kundendienst weiterleiten?"));
System.out.println(diffRows);
assertThat(diffRows).hasSize(2);
}
@Test
public void testProblemTooManyDiffRowsIssue65_DiffByWord() {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.reportLinesUnchanged(true)
.oldTag(f -> "~")
.newTag(f -> "**")
.mergeOriginalRevised(true)
.inlineDiffByWord(true)
.build();
List<DiffRow> diffRows = generator.generateDiffRows(
Arrays.asList("Ich möchte nicht mit einem Bot sprechen.", "Ich soll das schon wieder wiederholen?"),
Arrays.asList("Ich möchte nicht mehr mit dir sprechen. Leite mich weiter.", "Kannst du mich zum Kundendienst weiterleiten?"));
System.out.println(diffRows);
assertThat(diffRows).hasSize(2);
}
@Test
public void testProblemTooManyDiffRowsIssue65_NoInlineDiff() {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(false)
.reportLinesUnchanged(true)
.oldTag(f -> "~")
.newTag(f -> "**")
.mergeOriginalRevised(true)
.inlineDiffByWord(false)
.build();
List<DiffRow> diffRows = generator.generateDiffRows(
Arrays.asList("Ich möchte nicht mit einem Bot sprechen.", "Ich soll das schon wieder wiederholen?"),
Arrays.asList("Ich möchte nicht mehr mit dir sprechen. Leite mich weiter.", "Kannst du mich zum Kundendienst weiterleiten?"));
System.out.println(diffRows);
assertThat(diffRows).hasSize(2);
}
@Test
public void testLinefeedInStandardTagsWithLineWidthIssue81() {
List<String> original = Arrays.asList(("American bobtail jaguar. American bobtail bombay but turkish angora and tomcat.\n"
+ "Russian blue leopard. Lion. Tabby scottish fold for russian blue, so savannah yet lynx. Tomcat singapura, cheetah.\n"
+ "Bengal tiger panther but singapura but bombay munchkin for cougar.").split("\n"));
List<String> revised = Arrays.asList(("bobtail jaguar. American bobtail turkish angora and tomcat.\n"
+ "Russian blue leopard. Lion. Tabby scottish folded for russian blue, so savannah yettie? lynx. Tomcat singapura, cheetah.\n"
+ "Bengal tiger panther but singapura but bombay munchkin for cougar. And more.").split("\n"));
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.ignoreWhiteSpaces(true)
.columnWidth(100)
.build();
List<DiffRow> deltas = generator.generateDiffRows(original, revised);
System.out.println(deltas);
}
@Test
public void testIssue86WrongInlineDiff() throws IOException {
String original = Files.lines(Paths.get("target/test-classes/com/github/difflib/text/issue_86_original.txt")).collect(joining("\n"));
String revised = Files.lines(Paths.get("target/test-classes/com/github/difflib/text/issue_86_revised.txt")).collect(joining("\n"));
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.mergeOriginalRevised(false)
.inlineDiffByWord(true)
.oldTag( f -> "~" )
.newTag( f -> "**" )
.build();
List<DiffRow> rows = generator.generateDiffRows(
Arrays.asList(original.split("\n")),
Arrays.asList(revised.split("\n")));
for (DiffRow diff : rows) {
System.out.println(diff);
}
}
}
......@@ -21,6 +21,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
......@@ -42,7 +43,7 @@ public class UnifiedDiffReaderTest {
assertThat(file1.getFromFile()).isEqualTo("src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt");
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(3);
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n\n");
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n");
}
@Test
......@@ -100,7 +101,7 @@ public class UnifiedDiffReaderTest {
assertThat(first.getSource().size()).isGreaterThan(0);
assertThat(first.getTarget().size()).isGreaterThan(0);
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n\n");
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n");
}
@Test
......@@ -141,7 +142,7 @@ public class UnifiedDiffReaderTest {
assertThat(diff.getTail()).isNull();
assertThat(diff.getHeader()).isNull();
}
@Test
public void testParseIssue51() throws IOException {
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
......@@ -154,7 +155,85 @@ public class UnifiedDiffReaderTest {
UnifiedDiffFile file1 = diff.getFiles().get(0);
assertThat(file1.getFromFile()).isEqualTo("f1");
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(1);
UnifiedDiffFile file2 = diff.getFiles().get(1);
assertThat(file2.getFromFile()).isEqualTo("f2");
assertThat(file2.getPatch().getDeltas().size()).isEqualTo(1);
assertThat(diff.getTail()).isNull();
}
@Test
public void testParseIssue79() throws IOException {
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue79.diff"));
assertThat(diff.getFiles().size()).isEqualTo(1);
UnifiedDiffFile file1 = diff.getFiles().get(0);
assertThat(file1.getFromFile()).isEqualTo("test/Issue.java");
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(0);
assertThat(diff.getTail()).isNull();
assertThat(diff.getHeader()).isNull();
}
@Test
public void testParseIssue84() throws IOException {
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue84.diff"));
assertThat(diff.getFiles().size()).isEqualTo(2);
UnifiedDiffFile file1 = diff.getFiles().get(0);
assertThat(file1.getFromFile()).isEqualTo("config/ant-phase-verify.xml");
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(1);
UnifiedDiffFile file2 = diff.getFiles().get(1);
assertThat(file2.getFromFile()).isEqualTo("/dev/null");
assertThat(file2.getPatch().getDeltas().size()).isEqualTo(1);
assertThat(diff.getTail()).isEqualTo("2.7.4");
assertThat(diff.getHeader()).startsWith("From b53e612a2ab5ff15d14860e252f84c0f343fe93a Mon Sep 17 00:00:00 2001");
}
@Test
public void testParseIssue85() throws IOException {
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue85.diff"));
assertThat(diff.getFiles().size()).isEqualTo(1);
assertEquals(1, diff.getFiles().size());
final UnifiedDiffFile file1 = diff.getFiles().get(0);
assertEquals("diff -r 83e41b73d115 -r a4438263b228 tests/test-check-pyflakes.t",
file1.getDiffCommand());
assertEquals("tests/test-check-pyflakes.t", file1.getFromFile());
assertEquals("tests/test-check-pyflakes.t", file1.getToFile());
assertEquals(1, file1.getPatch().getDeltas().size());
assertNull(diff.getTail());
}
@Test
public void testTimeStampRegexp() {
assertThat("2019-04-18 13:49:39.516149751 +0200").matches(UnifiedDiffReader.TIMESTAMP_REGEXP);
}
@Test
public void testParseIssue98() throws IOException {
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue98.diff"));
assertThat(diff.getFiles().size()).isEqualTo(1);
assertEquals(1, diff.getFiles().size());
final UnifiedDiffFile file1 = diff.getFiles().get(0);
assertEquals("100644",
file1.getDeletedFileMode());
assertEquals("src/test/java/se/bjurr/violations/lib/model/ViolationTest.java", file1.getFromFile());
assertThat(diff.getTail()).isEqualTo("2.25.1");
}
}
......@@ -72,7 +72,7 @@ public class UnifiedDiffWriterTest {
String[] lines = writer.toString().split("\\n");
assertEquals("--- null", lines[0]);
assertEquals("--- /dev/null", lines[0]);
assertEquals("+++ revised", lines[1]);
assertEquals("@@ -0,0 +1,2 @@", lines[2]);
}
......
MessageTime,MessageType,Instrument,InstrumentState,TradePrice,TradeVolume,TradeCond,TradeId,AskPrice1,AskVol1,BidPrice1,BidVol1,AskPrice2,AskVol2,BidPrice2,BidVol2,AskPrice3,AskVol3,BidPrice3,BidVol3,AskPrice4,AskVol4,BidPrice4,BidVol4,AskPrice5,AskVol5,BidPrice5,BidVol5
2020-04-04T08:00:00.000Z,S,HHD_MAY20,Open,,,,,,,,,,,,,,,,,,,,,,,,
2020-04-04T08:00:00.000Z,S,FHK_C23.5_MAY20,Open,,,,,,,,,,,,,,,,,,,,,,,,
2020-04-04T13:49:11.522Z,Q,HHD_MAY20,,,,,,2.6,10,2.6,10,,,,,,,,,,,,,,,,
2020-04-04T13:49:18.210Z,T,HHD_MAY20,,2.6,1,Screen,0,,,,,,,,,,,,,,,,,,,,
2020-04-04T17:00:00.000Z,S,HHD_MAY20,Close,,,,,,,,,,,,,,,,,,,,,,,,
2020-04-04T17:00:00.000Z,S,FHK_C23.5_MAY20,Close,,,,,,,,,,,,,,,,,,,,,,,,
MessageTime,MessageType,Instrument,InstrumentState,TradePrice,TradeVolume,TradeCond,TradeId,AskPrice1,AskVol1,BidPrice1,BidVol1,AskPrice2,AskVol2,BidPrice2,BidVol2,AskPrice3,AskVol3,BidPrice3,BidVol3,AskPrice4,AskVol4,BidPrice4,BidVol4,AskPrice5,AskVol5,BidPrice5,BidVol5
2020-04-02T08:00:00.000Z,S,HHD_MAY20,Open,,,,,,,,,,,,,,,,,,,,,,,,
2020-04-02T08:00:00.000Z,S,FHK_C23.5_MAY20,Open,,,,,,,,,,,,,,,,,,,,,,,,
2020-04-04T13:49:11.522Z,Q,HHD_MAY20,,,,,,2.6,10,2.6,10,,,,,,,,,,,,,,,,
2020-04xs-04T17dw:00:00.000Z,Sdwdw,HHD_MAY20dwdw,Closdwde,,,,,,,,,,,,,,,,,,,,,,,,
2020-04-04T13:49:18.210Z,T,HHD_MAY20,,2.6,2,Screen,0,,,,,,,,,,,,,,,,,,,,
2020-04-04T17:00:00.000Z,S,HHD_MAY20,Close,,,,,,,,,,,,,,,,,,,,,,,,
2020-04-04T17:00:00.000Z,S,FHK_C23.5_MAY20,Close,,,,,,,,,,,,,,,,,,,,,,,,
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment