13 Commits

Author SHA1 Message Date
wumpz
0a2053f71a [maven-release-plugin] prepare release diffutils-2.1 2017-11-09 22:38:40 +01:00
wumpz
4f6b1839f8 2017-11-09 22:24:46 +01:00
wumpz
5764356be2 2017-11-09 22:12:57 +01:00
wumpz
4f6f8dbcf2 fixes #14 2017-11-09 14:34:50 +01:00
wumpz
573460df9c preparing maven central release 2017-11-09 12:33:27 +01:00
wumpz
d2a432059d preparing maven central release 2017-11-09 12:30:47 +01:00
wumpz
90eaf2e134 starting corrections for maven central release 2017-11-08 08:29:59 +01:00
wumpz
e6fa5938a9 included checkstyle source code conventions 2017-10-25 08:49:20 +02:00
wumpz
88146c6afb make columnwith 0, meaning no text wrap, the standard 2017-09-28 13:25:54 +02:00
wumpz
aed1d31c2b 2017-08-30 13:46:55 +02:00
wumpz
5d5218ba30 fixes #11 2017-08-18 14:50:32 +02:00
wumpz
1107f43f36 fixes #11 2017-08-18 14:48:35 +02:00
wumpz
6c91ef68df [maven-release-plugin] prepare for next development iteration 2017-08-14 09:21:33 +02:00
31 changed files with 650 additions and 460 deletions

View File

@@ -50,6 +50,10 @@ This is a test ~senctence~**for diffutils**.
But it can easily replaced by any other which is better for handing your texts. I have plan to add implementation of some in future. But it can easily replaced by any other which is better for handing your texts. I have plan to add implementation of some in future.
### Changelog ### ### Changelog ###
* Version 2.1-SNAPSHOT
* included checkstyle source code conventions
* groupid changed to **com.github.wumpz**, due to maven central releasing
* allow configurable splitting of lines to define the blocks to compare (words, characters, phrases).
* Version 2.0 * Version 2.0
* switch to maven and removed other artifacts * switch to maven and removed other artifacts
* changed groupid to **com.github.java-diff-utils** due to different forks at github * changed groupid to **com.github.java-diff-utils** due to different forks at github
@@ -66,6 +70,26 @@ But it can easily replaced by any other which is better for handing your texts.
* Ant build script * Ant build script
* Generate output in unified diff format (thanks for Bill James) * Generate output in unified diff format (thanks for Bill James)
## Source Code conventions
Recently a checkstyle process was integrated into the build process. JSqlParser follows the sun java format convention. There are no TABs allowed. Use spaces.
```java
public static <T> Patch<T> diff(List<T> original, List<T> revised,
BiPredicate<T, T> equalizer) throws DiffException {
if (equalizer != null) {
return DiffUtils.diff(original, revised,
new MyersDiff<>(equalizer));
}
return DiffUtils.diff(original, revised, new MyersDiff<>());
}
```
This is a valid piece of source code:
* blocks without braces are not allowed
* after control statements (if, while, for) a whitespace is expected
* the opening brace should be in the same line as the control statement
### To Install ### ### To Install ###
**This jar is not yet to get at maven central.** **This jar is not yet to get at maven central.**
@@ -73,7 +97,7 @@ But it can easily replaced by any other which is better for handing your texts.
Just add the code below to your maven dependencies: Just add the code below to your maven dependencies:
``` ```
<dependency> <dependency>
<groupId>com.github.java-diff-utils</groupId> <groupId>com.github.wumpz</groupId>
<artifactId>diffutils</artifactId> <artifactId>diffutils</artifactId>
   <version>2.0-SNAPSHOT</version>    <version>2.0-SNAPSHOT</version>
</dependency> </dependency>

View File

@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false"> <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" /> <output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" /> <output-test url="file://$MODULE_DIR$/target/test-classes" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/dist" /> <excludeFolder url="file://$MODULE_DIR$/dist" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library"> <orderEntry type="module-library">
<library> <library>
<CLASSES> <CLASSES>
<root url="jar://$MODULE_DIR$/lib/junit.jar!/" /> <root url="jar://$MODULE_DIR$/lib/junit.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />
</library> </library>
</orderEntry> </orderEntry>
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.8.1" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.8.1" level="project" />
</component> </component>
</module> </module>

View File

@@ -1,22 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project-shared-configuration> <project-shared-configuration>
<!-- <!--
This file contains additional configuration written by modules in the NetBeans IDE. This file contains additional configuration written by modules in the NetBeans IDE.
The configuration is intended to be shared among all the users of project and The configuration is intended to be shared among all the users of project and
therefore it is assumed to be part of version control checkout. therefore it is assumed to be part of version control checkout.
Without this configuration present, some functionality in the IDE may be limited or fail altogether. Without this configuration present, some functionality in the IDE may be limited or fail altogether.
--> -->
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1"> <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
<!-- <!--
Properties that influence various parts of the IDE, especially code formatting and the like. Properties that influence various parts of the IDE, especially code formatting and the like.
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up. You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
That way multiple projects can share the same settings (useful for formatting rules for example). That way multiple projects can share the same settings (useful for formatting rules for example).
Any value defined here will override the pom.xml file value but is only applicable to the current project. Any value defined here will override the pom.xml file value but is only applicable to the current project.
--> -->
<netbeans.compile.on.save>none</netbeans.compile.on.save> <netbeans.compile.on.save>none</netbeans.compile.on.save>
<com-junichi11-netbeans-changelf.enable>false</com-junichi11-netbeans-changelf.enable> <com-junichi11-netbeans-changelf.enable>false</com-junichi11-netbeans-changelf.enable>
<com-junichi11-netbeans-changelf.use-project>true</com-junichi11-netbeans-changelf.use-project> <com-junichi11-netbeans-changelf.use-project>true</com-junichi11-netbeans-changelf.use-project>
<com-junichi11-netbeans-changelf.lf-kind>LF</com-junichi11-netbeans-changelf.lf-kind> <com-junichi11-netbeans-changelf.lf-kind>LF</com-junichi11-netbeans-changelf.lf-kind>
<com-junichi11-netbeans-changelf.use-global>false</com-junichi11-netbeans-changelf.use-global> <com-junichi11-netbeans-changelf.use-global>false</com-junichi11-netbeans-changelf.use-global>
</properties> </properties>
</project-shared-configuration> </project-shared-configuration>

11
nbactions.xml Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action>
<actionName>CUSTOM-clean deploy</actionName>
<displayName>clean deploy</displayName>
<goals>
<goal>clean</goal>
<goal>deploy</goal>
</goals>
</action>
</actions>

470
pom.xml
View File

@@ -1,213 +1,305 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.github.java-diff-utils</groupId> <groupId>com.github.wumpz</groupId>
<artifactId>diffutils</artifactId> <artifactId>diffutils</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>2.0</version> <version>2.1</version>
<name>java-diff-utils</name>
<name>java-diff-utils</name> <description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description>
<description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description> <url>https://github.com/wumpz/java-diff-utils</url>
<url>https://github.com/wumpz/java-diff-utils</url> <inceptionYear>2009</inceptionYear>
<inceptionYear>2009</inceptionYear>
<!--
to make a local release
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>9</version>
</parent>
-->
<scm>
<connection>scm:git:https://github.com/wumpz/java-diff-utils.git</connection>
<developerConnection>scm:git:ssh://git@github.com:wumpz/java-diff-utils.git</developerConnection>
<url>https://github.com/wumpz/java-diff-utils.git</url>
<tag>diffutils-2.0</tag>
</scm>
<issueManagement> <distributionManagement>
<system>GitHub Issues</system> <repository>
<url>https://github.com/wumpz/java-diff-utils/issues</url> <id>sonatype-nexus-staging</id>
</issueManagement> <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
<snapshotRepository>
<id>sonatype-nexus-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<organization> <scm>
<name>java-diff-utils</name> <connection>scm:git:https://github.com/wumpz/java-diff-utils.git</connection>
</organization> <developerConnection>scm:git:ssh://git@github.com:wumpz/java-diff-utils.git</developerConnection>
<url>https://github.com/wumpz/java-diff-utils.git</url>
<tag>diffutils-2.1</tag>
</scm>
<developers> <issueManagement>
<developer> <system>GitHub Issues</system>
<name>Tobias Warneke</name> <url>https://github.com/wumpz/java-diff-utils/issues</url>
<email>t.warneke@gmx.net</email> </issueManagement>
</developer>
<developer>
<name>Dmitry Naumenko</name>
<email>dm.naumenko@gmail.com</email>
</developer>
<developer>
<name>Juanco Anez</name>
<email>juanco@suigeneris.org</email>
</developer>
</developers>
<licenses> <organization>
<license> <name>java-diff-utils</name>
<name>The Apache Software License, Version 2.0</name> </organization>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution> <developers>
<comments>A business-friendly OSS license</comments> <developer>
</license> <name>Tobias Warneke</name>
</licenses> <email>t.warneke@gmx.net</email>
</developer>
<developer>
<name>Dmitry Naumenko</name>
<email>dm.naumenko@gmail.com</email>
</developer>
<developer>
<name>Juanco Anez</name>
<email>juanco@suigeneris.org</email>
</developer>
</developers>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.12</version> <version>4.12</version>
<type>jar</type> <type>jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jgit</groupId> <groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId> <artifactId>org.eclipse.jgit</artifactId>
<version>4.4.1.201607150455-r</version> <version>4.4.1.201607150455-r</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>com.googlecode.javaewah</groupId> <groupId>com.googlecode.javaewah</groupId>
<artifactId>JavaEWAH</artifactId> <artifactId>JavaEWAH</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>commons-codec</groupId> <groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId> <artifactId>commons-codec</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>com.jcraft</groupId> <groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId> <artifactId>jsch</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version> <version>3.6.1</version>
<configuration> <configuration>
<source>1.8</source> <source>1.8</source>
<target>1.8</target> <target>1.8</target>
<encoding>UTF-8</encoding> <encoding>UTF-8</encoding>
</configuration> </configuration>
</plugin> </plugin>
<!-- Make this JAR OSGi ready --> <!-- Make this JAR OSGi ready -->
<!-- We want to keep packaging type as jar. Therefore we need to customize the MANIFEST.MF. <!-- We want to keep packaging type as jar. Therefore we need to customize the MANIFEST.MF.
See http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html See http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
--> -->
<plugin> <plugin>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version> <version>3.0.2</version>
<configuration> <configuration>
<archive> <archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive> </archive>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.felix</groupId> <groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId> <artifactId>maven-bundle-plugin</artifactId>
<version>3.3.0</version> <version>3.3.0</version>
<executions> <executions>
<execution> <execution>
<id>bundle-manifest</id> <id>bundle-manifest</id>
<phase>process-classes</phase> <phase>process-classes</phase>
<goals> <goals>
<goal>manifest</goal> <goal>manifest</goal>
</goals> </goals>
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version> <version>2.10.4</version>
<configuration> <configuration>
<additionalparam>${javadoc.opts}</additionalparam> <additionalparam>${javadoc.opts}</additionalparam>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>
<id>attach-javadocs</id> <id>attach-javadocs</id>
<goals> <goals>
<goal>jar</goal> <goal>jar</goal>
</goals> </goals>
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version> <version>2.19.1</version>
<configuration> <configuration>
<excludes> <excludes>
<exclude>**/LR*.java</exclude> <exclude>**/LR*.java</exclude>
</excludes> </excludes>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId> <artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version> <version>2.5.3</version>
<configuration> <configuration>
<localCheckout>true</localCheckout> <localCheckout>true</localCheckout>
<pushChanges>false</pushChanges> <pushChanges>false</pushChanges>
<mavenExecutorId>forked-path</mavenExecutorId> <mavenExecutorId>forked-path</mavenExecutorId>
<goals>install</goals> <goals>install</goals>
</configuration> </configuration>
</plugin> </plugin>
</plugins> <plugin>
</build> <groupId>org.apache.maven.plugins</groupId>
<profiles> <artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>verify-style</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<logViolationsToConsole>true</logViolationsToConsole>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
<checkstyleRules>
<module name="Checker">
<module name="SuppressWarningsFilter" />
<module name="FileTabCharacter" />
<!-- git checkout may change linefeeds on the fly
<module name="RegexpMultiline">
<property name="format" value="(?s:(\r\n|\r).*)" />
<property name="message" value="CRLF and CR line endings are prohibited, but this file uses them." />
</module>
-->
<module name="TreeWalker">
<module name="AvoidNestedBlocks" />
<module name="ConstantName" />
<module name="EmptyCatchBlock" />
<module name="EmptyStatement" />
<module name="MissingOverride" />
<module name="MultipleVariableDeclarations" />
<module name="ParameterAssignment" />
<module name="StringLiteralEquality" />
<module name="RedundantImport" />
<module name="UnusedImports" />
<module name="WhitespaceAfter" />
<module name="NeedBraces" />
<module name="UnnecessaryParentheses" />
<module name="LeftCurly" />
<module name="RightCurly" />
<module name="SuppressWarningsHolder" />
</module>
</module>
</checkstyleRules>
</configuration>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>6.19</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<profiles>
<profile> <profile>
<id>doclint-java8-disable</id> <id>sign-release-artifacts</id>
<activation> <activation>
<jdk>[1.8,)</jdk> <property>
<name>performRelease</name>
<value>true</value>
</property>
</activation> </activation>
<properties>
<javadoc.opts>-Xdoclint:none</javadoc.opts>
</properties>
</profile>
<profile>
<id>long-running-tests</id>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-gpg-plugin</artifactId>
<configuration> <version>1.4</version>
<excludes> <executions>
<exclude>xxx</exclude> <execution>
</excludes> <id>sign-artifacts</id>
</configuration> <phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<keyname>f22e0543</keyname>
</configuration>
</execution>
</executions>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
</profile> </profile>
</profiles> <profile>
<id>doclint-java8-disable</id>
<activation>
<jdk>[1.8,)</jdk>
</activation>
<properties>
<javadoc.opts>-Xdoclint:none</javadoc.opts>
</properties>
</profile>
<profile>
<id>long-running-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>xxx</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project> </project>

View File

@@ -25,9 +25,9 @@ import com.github.difflib.algorithm.myers.MyersDiff;
import com.github.difflib.patch.Delta; import com.github.difflib.patch.Delta;
import com.github.difflib.patch.Patch; import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException; import com.github.difflib.patch.PatchFailedException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
@@ -42,18 +42,16 @@ import static java.util.stream.Collectors.joining;
public final class DiffUtils { public final class DiffUtils {
/** /**
* Computes the difference between the original and revised list of elements with default diff * Computes the difference between the original and revised list of elements with default diff algorithm
* algorithm
* *
* @param original The original text. Must not be {@code null}. * @param original The original text. Must not be {@code null}.
* @param revised The revised text. Must not be {@code null}. * @param revised The revised text. Must not be {@code null}.
* @return The patch describing the difference between the original and revised sequences. Never * @return The patch describing the difference between the original and revised sequences. Never {@code null}.
* {@code null}.
*/ */
public static <T> Patch<T> diff(List<T> original, List<T> revised) throws DiffException { public static <T> Patch<T> diff(List<T> original, List<T> revised) throws DiffException {
return DiffUtils.diff(original, revised, new MyersDiff<>()); return DiffUtils.diff(original, revised, new MyersDiff<>());
} }
/** /**
* Computes the difference between the original and revised text. * Computes the difference between the original and revised text.
*/ */
@@ -62,19 +60,17 @@ public final class DiffUtils {
} }
/** /**
* Computes the difference between the original and revised list of elements with default diff * Computes the difference between the original and revised list of elements with default diff algorithm
* algorithm
* *
* @param original The original text. Must not be {@code null}. * @param original The original text. Must not be {@code null}.
* @param revised The revised text. Must not be {@code null}. * @param revised The revised text. Must not be {@code null}.
* *
* @param equalizer the equalizer object to replace the default compare algorithm * @param equalizer the equalizer object to replace the default compare algorithm (Object.equals). If {@code null}
* (Object.equals). If {@code null} the default equalizer of the default algorithm is used.. * the default equalizer of the default algorithm is used..
* @return The patch describing the difference between the original and revised sequences. Never * @return The patch describing the difference between the original and revised sequences. Never {@code null}.
* {@code null}.
*/ */
public static <T> Patch<T> diff(List<T> original, List<T> revised, public static <T> Patch<T> diff(List<T> original, List<T> revised,
BiPredicate<T,T> equalizer) throws DiffException { BiPredicate<T, T> equalizer) throws DiffException {
if (equalizer != null) { if (equalizer != null) {
return DiffUtils.diff(original, revised, return DiffUtils.diff(original, revised,
new MyersDiff<>(equalizer)); new MyersDiff<>(equalizer));
@@ -83,36 +79,33 @@ public final class DiffUtils {
} }
/** /**
* Computes the difference between the original and revised list of elements with default diff * Computes the difference between the original and revised list of elements with default diff algorithm
* algorithm
* *
* @param original The original text. Must not be {@code null}. * @param original The original text. Must not be {@code null}.
* @param revised The revised text. Must not be {@code null}. * @param revised The revised text. Must not be {@code null}.
* @param algorithm The diff algorithm. Must not be {@code null}. * @param algorithm The diff algorithm. Must not be {@code null}.
* @return The patch describing the difference between the original and revised sequences. Never * @return The patch describing the difference between the original and revised sequences. Never {@code null}.
* {@code null}.
*/ */
public static <T> Patch<T> diff(List<T> original, List<T> revised, public static <T> Patch<T> diff(List<T> original, List<T> revised,
DiffAlgorithm<T> algorithm) throws DiffException { DiffAlgorithm<T> algorithm) throws DiffException {
Objects.requireNonNull(original,"original must not be null"); Objects.requireNonNull(original, "original must not be null");
Objects.requireNonNull(revised,"revised must not be null"); Objects.requireNonNull(revised, "revised must not be null");
Objects.requireNonNull(algorithm,"algorithm must not be null"); Objects.requireNonNull(algorithm, "algorithm must not be null");
return Patch.generate(original, revised, algorithm.diff(original, revised)); return Patch.generate(original, revised, algorithm.diff(original, revised));
} }
/** /**
* Computes the difference between the given texts inline. This one uses the "trick" to make out * Computes the difference between the given texts inline. This one uses the "trick" to make out of texts lists of
* of texts lists of characters, like DiffRowGenerator does and merges those changes at the end * characters, like DiffRowGenerator does and merges those changes at the end together again.
* together again.
* *
* @param original * @param original
* @param revised * @param revised
* @return * @return
*/ */
public static Patch<String> diffInline(String original, String revised) throws DiffException { public static Patch<String> diffInline(String original, String revised) throws DiffException {
LinkedList<String> origList = new LinkedList<>(); List<String> origList = new ArrayList<>();
LinkedList<String> revList = new LinkedList<>(); List<String> revList = new ArrayList<>();
for (Character character : original.toCharArray()) { for (Character character : original.toCharArray()) {
origList.add(character.toString()); origList.add(character.toString());
} }

View File

@@ -29,6 +29,7 @@ import java.util.regex.Pattern;
* @author toben * @author toben
*/ */
public final class UnifiedDiffUtils { public final class UnifiedDiffUtils {
private static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern private static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern
.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@$"); .compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@$");
@@ -124,10 +125,10 @@ public final class UnifiedDiffUtils {
return patch; return patch;
} }
/** /**
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format * generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format text representing
* text representing the Patch. * the Patch.
* *
* @param original - Filename of the original (unrevised file) * @param original - Filename of the original (unrevised file)
* @param revised - Filename of the revised file * @param revised - Filename of the revised file
@@ -195,10 +196,9 @@ public final class UnifiedDiffUtils {
} }
return new ArrayList<>(); return new ArrayList<>();
} }
/** /**
* processDeltas takes a list of Deltas and outputs them together in a single block of * processDeltas takes a list of Deltas and outputs them together in a single block of Unified-Diff-format text.
* Unified-Diff-format text.
* *
* @param origLines - the lines of the original file * @param origLines - the lines of the original file
* @param deltas - the Deltas to be output as a single block * @param deltas - the Deltas to be output as a single block
@@ -289,7 +289,7 @@ public final class UnifiedDiffUtils {
return buffer; return buffer;
} }
/** /**
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter * getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
* *
@@ -307,7 +307,7 @@ public final class UnifiedDiffUtils {
} }
return buffer; return buffer;
} }
private UnifiedDiffUtils() { private UnifiedDiffUtils() {
} }
} }

View File

@@ -22,6 +22,7 @@ import com.github.difflib.patch.DeltaType;
* @author toben * @author toben
*/ */
public class Change { public class Change {
public final DeltaType deltaType; public final DeltaType deltaType;
public final int startOriginal; public final int startOriginal;
public final int endOriginal; public final int endOriginal;

View File

@@ -31,8 +31,8 @@ import java.util.*;
public interface DiffAlgorithm<T> { public interface DiffAlgorithm<T> {
/** /**
* Computes the difference between the original sequence and the revised sequence and returns it * Computes the difference between the original sequence and the revised sequence and returns it as a {@link Patch}
* as a {@link Patch} object. * object.
* *
* @param original The original sequence. Must not be {@code null}. * @param original The original sequence. Must not be {@code null}.
* @param revised The revised sequence. Must not be {@code null}. * @param revised The revised sequence. Must not be {@code null}.
@@ -43,8 +43,8 @@ public interface DiffAlgorithm<T> {
} }
/** /**
* Computes the difference between the original sequence and the revised sequence and returns it * Computes the difference between the original sequence and the revised sequence and returns it as a {@link Patch}
* as a {@link Patch} object. * object.
* *
* @param original The original sequence. Must not be {@code null}. * @param original The original sequence. Must not be {@code null}.
* @param revised The revised sequence. Must not be {@code null}. * @param revised The revised sequence. Must not be {@code null}.

View File

@@ -19,12 +19,9 @@ limitations under the License.
*/ */
package com.github.difflib.algorithm; package com.github.difflib.algorithm;
import com.github.difflib.algorithm.DiffException;
/** /**
* Thrown whenever the differencing engine cannot produce the differences between two revisions of * Thrown whenever the differencing engine cannot produce the differences between two revisions of ta text.
* ta text. *
* @see MyersDiff * @see MyersDiff
* @see difflib.DiffAlgorithm * @see difflib.DiffAlgorithm
*/ */

View File

@@ -28,9 +28,8 @@ import org.eclipse.jgit.diff.Sequence;
import org.eclipse.jgit.diff.SequenceComparator; import org.eclipse.jgit.diff.SequenceComparator;
/** /**
* HistorgramDiff using JGit - Library. This one is much more performant than the * HistorgramDiff using JGit - Library. This one is much more performant than the orginal Myers implementation.
* orginal Myers implementation. *
*
* @author toben * @author toben
*/ */
public class HistogramDiff<T> implements DiffAlgorithm<T> { public class HistogramDiff<T> implements DiffAlgorithm<T> {
@@ -43,19 +42,19 @@ public class HistogramDiff<T> implements DiffAlgorithm<T> {
diffList.addAll(new org.eclipse.jgit.diff.HistogramDiff().diff(new DataListComparator<>(), new DataList<>(original), new DataList<>(revised))); diffList.addAll(new org.eclipse.jgit.diff.HistogramDiff().diff(new DataListComparator<>(), new DataList<>(original), new DataList<>(revised)));
List<Change> patch = new ArrayList<>(); List<Change> patch = new ArrayList<>();
for (Edit edit : diffList) { for (Edit edit : diffList) {
DeltaType type = DeltaType.EQUAL; DeltaType type = DeltaType.EQUAL;
switch (edit.getType()) { switch (edit.getType()) {
case DELETE: case DELETE:
type = DeltaType.DELETE; type = DeltaType.DELETE;
break; break;
case INSERT: case INSERT:
type = DeltaType.INSERT; type = DeltaType.INSERT;
break; break;
case REPLACE: case REPLACE:
type = DeltaType.CHANGE; type = DeltaType.CHANGE;
break; break;
} }
patch.add(new Change(type,edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB())); patch.add(new Change(type, edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB()));
} }
return patch; return patch;
} }

View File

@@ -20,9 +20,9 @@ limitations under the License.
package com.github.difflib.algorithm.myers; package com.github.difflib.algorithm.myers;
import com.github.difflib.algorithm.Change; import com.github.difflib.algorithm.Change;
import com.github.difflib.algorithm.DifferentiationFailedException;
import com.github.difflib.algorithm.DiffAlgorithm; import com.github.difflib.algorithm.DiffAlgorithm;
import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DiffException;
import com.github.difflib.algorithm.DifferentiationFailedException;
import com.github.difflib.patch.DeltaType; import com.github.difflib.patch.DeltaType;
import com.github.difflib.patch.Patch; import com.github.difflib.patch.Patch;
import java.util.ArrayList; import java.util.ArrayList;
@@ -35,16 +35,14 @@ import java.util.function.BiPredicate;
*/ */
public final class MyersDiff<T> implements DiffAlgorithm<T> { public final class MyersDiff<T> implements DiffAlgorithm<T> {
private final BiPredicate<T,T> DEFAULT_EQUALIZER = Object::equals; private final BiPredicate<T, T> DEFAULT_EQUALIZER = Object::equals;
private final BiPredicate<T,T> equalizer; private final BiPredicate<T, T> equalizer;
public MyersDiff() { public MyersDiff() {
equalizer = DEFAULT_EQUALIZER; equalizer = DEFAULT_EQUALIZER;
} }
public MyersDiff(final BiPredicate<T, T> equalizer) {
public MyersDiff(final BiPredicate<T,T> equalizer) {
Objects.requireNonNull(equalizer, "equalizer must not be null"); Objects.requireNonNull(equalizer, "equalizer must not be null");
this.equalizer = equalizer; this.equalizer = equalizer;
} }
@@ -64,9 +62,8 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
} }
/** /**
* Computes the minimum diffpath that expresses de differences between the * Computes the minimum diffpath that expresses de differences between the original and revised sequences, according
* original and revised sequences, according to Gene Myers differencing * to Gene Myers differencing algorithm.
* algorithm.
* *
* @param orig The original sequence. * @param orig The original sequence.
* @param rev The revised sequence. * @param rev The revised sequence.
@@ -138,8 +135,7 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
* @param orig The original sequence. * @param orig The original sequence.
* @param rev The revised sequence. * @param rev The revised sequence.
* @return A {@link Patch} script corresponding to the path. * @return A {@link Patch} script corresponding to the path.
* @throws DifferentiationFailedException if a {@link Patch} could not be * @throws DifferentiationFailedException if a {@link Patch} could not be built from the given path.
* built from the given path.
*/ */
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) { private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
Objects.requireNonNull(actualPath, "path is null"); Objects.requireNonNull(actualPath, "path is null");

View File

@@ -44,7 +44,7 @@ public final class PathNode {
public final PathNode prev; public final PathNode prev;
public final boolean snake; public final boolean snake;
public final boolean bootstrap; public final boolean bootstrap;
/** /**
@@ -61,7 +61,7 @@ public final class PathNode {
if (snake) { if (snake) {
this.prev = prev; this.prev = prev;
} else { } else {
this.prev = (prev == null ? null : prev.previousSnake()); this.prev = prev == null ? null : prev.previousSnake();
} }
this.snake = snake; this.snake = snake;
} }
@@ -82,11 +82,10 @@ public final class PathNode {
} }
/** /**
* Skips sequences of {@link DiffNode DiffNodes} until a {@link Snake} or bootstrap node is * Skips sequences of {@link DiffNode DiffNodes} until a {@link Snake} or bootstrap node is found, or the end of the
* found, or the end of the path is reached. * path is reached.
* *
* @return The next first {@link Snake} or bootstrap node in the path, or <code>null</code> if * @return The next first {@link Snake} or bootstrap node in the path, or <code>null</code> if none found.
* none found.
*/ */
public final PathNode previousSnake() { public final PathNode previousSnake() {
if (isBootstrap()) { if (isBootstrap()) {

View File

@@ -26,10 +26,9 @@ import java.util.List;
* Holds the information about the part of text involved in the diff process * Holds the information about the part of text involved in the diff process
* *
* <p> * <p>
* Text is represented as <code>Object[]</code> because the diff engine is capable of handling more * Text is represented as <code>Object[]</code> because the diff engine is capable of handling more than plain ascci. In
* than plain ascci. In fact, arrays or lists of any type that implements * fact, arrays or lists of any type that implements {@link java.lang.Object#hashCode hashCode()} and
* {@link java.lang.Object#hashCode hashCode()} and {@link java.lang.Object#equals equals()} * {@link java.lang.Object#equals equals()} correctly can be subject to differencing using this library.
* correctly can be subject to differencing using this library.
* </p> * </p>
* *
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a> * @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>

View File

@@ -48,7 +48,7 @@ public final class DeleteDelta<T> extends Delta<T> {
target.remove(position); target.remove(position);
} }
} }
@Override @Override
public void restore(List<T> target) { public void restore(List<T> target) {
int position = this.getRevised().getPosition(); int position = this.getRevised().getPosition();

View File

@@ -43,7 +43,7 @@ public abstract class Delta<T> {
Objects.requireNonNull(deltaType, "deltaType must not be null"); Objects.requireNonNull(deltaType, "deltaType must not be null");
Objects.requireNonNull(original, "original must not be null"); Objects.requireNonNull(original, "original must not be null");
Objects.requireNonNull(revised, "revised must not be null"); Objects.requireNonNull(revised, "revised must not be null");
this.deltaType = deltaType; this.deltaType = deltaType;
this.original = original; this.original = original;
this.revised = revised; this.revised = revised;

View File

@@ -31,8 +31,7 @@ public enum DeltaType {
/** /**
* An insert into the original. * An insert into the original.
*/ */
INSERT, INSERT,
/** /**
* An do nothing. * An do nothing.
*/ */

View File

@@ -48,7 +48,7 @@ public final class InsertDelta<T> extends Delta<T> {
target.add(position + i, lines.get(i)); target.add(position + i, lines.get(i));
} }
} }
@Override @Override
public void restore(List<T> target) { public void restore(List<T> target) {
int position = getRevised().getPosition(); int position = getRevised().getPosition();

View File

@@ -25,7 +25,6 @@ import static com.github.difflib.patch.DeltaType.INSERT;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import static java.util.Comparator.comparing; import static java.util.Comparator.comparing;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
@@ -37,7 +36,15 @@ import java.util.ListIterator;
*/ */
public final class Patch<T> { public final class Patch<T> {
private final List<Delta<T>> deltas = new LinkedList<>(); private final List<Delta<T>> deltas;
public Patch() {
this(10);
}
public Patch(int estimatedPatchSize) {
deltas = new ArrayList<>(estimatedPatchSize);
}
/** /**
* Apply this patch to the given target * Apply this patch to the given target
@@ -46,7 +53,7 @@ public final class Patch<T> {
* @throws PatchFailedException if can't apply patch * @throws PatchFailedException if can't apply patch
*/ */
public List<T> applyTo(List<T> target) throws PatchFailedException { public List<T> applyTo(List<T> target) throws PatchFailedException {
List<T> result = new LinkedList<>(target); List<T> result = new ArrayList<>(target);
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size()); ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) { while (it.hasPrevious()) {
Delta<T> delta = it.previous(); Delta<T> delta = it.previous();
@@ -62,7 +69,7 @@ public final class Patch<T> {
* @return the restored text * @return the restored text
*/ */
public List<T> restore(List<T> target) { public List<T> restore(List<T> target) {
List<T> result = new LinkedList<>(target); List<T> result = new ArrayList<>(target);
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size()); ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) { while (it.hasPrevious()) {
Delta<T> delta = it.previous(); Delta<T> delta = it.previous();
@@ -80,7 +87,7 @@ public final class Patch<T> {
deltas.add(delta); deltas.add(delta);
} }
/** /**
* Get the list of computed deltas * Get the list of computed deltas
* *
* @return the deltas * @return the deltas
@@ -94,9 +101,9 @@ public final class Patch<T> {
public String toString() { public String toString() {
return "Patch{" + "deltas=" + deltas + '}'; return "Patch{" + "deltas=" + deltas + '}';
} }
public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> changes) { public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> changes) {
Patch<T> patch = new Patch<>(); Patch<T> patch = new Patch<>(changes.size());
for (Change change : changes) { for (Change change : changes) {
Chunk<T> orgChunk = new Chunk<>(change.startOriginal, new ArrayList<>(original.subList(change.startOriginal, change.endOriginal))); Chunk<T> orgChunk = new Chunk<>(change.startOriginal, new ArrayList<>(original.subList(change.startOriginal, change.endOriginal)));
Chunk<T> revChunk = new Chunk<>(change.startRevised, new ArrayList<>(revised.subList(change.startRevised, change.endRevised))); Chunk<T> revChunk = new Chunk<>(change.startRevised, new ArrayList<>(revised.subList(change.startRevised, change.endRevised)));

View File

@@ -22,8 +22,7 @@ package com.github.difflib.text;
import java.io.Serializable; import java.io.Serializable;
/** /**
* Describes the diff row in form [tag, oldLine, newLine) for showing the difference between two * Describes the diff row in form [tag, oldLine, newLine) for showing the difference between two texts
* texts
* *
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a> * @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/ */

View File

@@ -35,32 +35,50 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* This class for generating DiffRows for side-by-sidy view. You can customize the way of * This class for generating DiffRows for side-by-sidy view. You can customize the way of generating. For example, show
* generating. For example, show inline diffs on not, ignoring white spaces or/and blank lines and * inline diffs on not, ignoring white spaces or/and blank lines and so on. All parameters for generating are optional.
* so on. All parameters for generating are optional. If you do not specify them, the class will use * If you do not specify them, the class will use the default values.
* the default values.
* *
* These values are: showInlineDiffs = false; ignoreWhiteSpaces = true; ignoreBlankLines = true; ... * These values are: showInlineDiffs = false; ignoreWhiteSpaces = true; ignoreBlankLines = true; ...
* *
* For instantiating the DiffRowGenerator you should use the its builder. Like in example <code> * For instantiating the DiffRowGenerator you should use the its builder. Like in example <code>
* DiffRowGenerator generator = new DiffRowGenerator.Builder().showInlineDiffs(true). * DiffRowGenerator generator = new DiffRowGenerator.Builder().showInlineDiffs(true).
* ignoreWhiteSpaces(true).columnWidth(100).build(); * ignoreWhiteSpaces(true).columnWidth(100).build();
* </code> * </code>
*/ */
public class DiffRowGenerator { public class DiffRowGenerator {
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
public static final BiPredicate<String,String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
public static final BiPredicate<String, String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
-> original.trim().replaceAll("\\s+", " ").equals(revised.trim().replaceAll("\\s+", " ")); -> original.trim().replaceAll("\\s+", " ").equals(revised.trim().replaceAll("\\s+", " "));
public static final BiPredicate<String,String> DEFAULT_EQUALIZER = Object::equals;
private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]"); public static final BiPredicate<String, String> DEFAULT_EQUALIZER = Object::equals;
/**
* Splitting lines by word to achieve word by word diff checking.
*/
public static final Function<String, List<String>> SPLITTER_BY_WORD = line -> splitStringPreserveDelimiter(line, SPLIT_BY_WORD_PATTERN);
/**
* Splitting lines by character to achieve char by char diff checking.
*/
public static final Function<String, List<String>> SPLITTER_BY_CHARACTER = line -> {
List<String> list = new ArrayList<>(line.length());
for (Character character : line.toCharArray()) {
list.add(character.toString());
}
return list;
};
private final boolean showInlineDiffs; private final boolean showInlineDiffs;
private final boolean ignoreWhiteSpaces; private final boolean ignoreWhiteSpaces;
private final Function<Boolean, String> oldTag; private final Function<Boolean, String> oldTag;
private final Function<Boolean, String> newTag; private final Function<Boolean, String> newTag;
private final boolean inlineDiffByWord; private final Function<String, List<String>> inlineDiffSplitter;
private final int columnWidth; private final int columnWidth;
private final BiPredicate<String, String> equalizer; private final BiPredicate<String, String> equalizer;
private final boolean mergeOriginalRevised; private final boolean mergeOriginalRevised;
private final boolean reportLinesUnchanged;
/** /**
* This class used for building the DiffRowGenerator. * This class used for building the DiffRowGenerator.
@@ -76,9 +94,10 @@ public class DiffRowGenerator {
private Function<Boolean, String> oldTag = f -> f ? "<span class=\"editOldInline\">" : "</span>"; private Function<Boolean, String> oldTag = f -> f ? "<span class=\"editOldInline\">" : "</span>";
private Function<Boolean, String> newTag = f -> f ? "<span class=\"editNewInline\">" : "</span>"; private Function<Boolean, String> newTag = f -> f ? "<span class=\"editNewInline\">" : "</span>";
private int columnWidth = 80; private int columnWidth = 0;
private boolean mergeOriginalRevised = false; private boolean mergeOriginalRevised = false;
private boolean inlineDiffByWord = false; private boolean reportLinesUnchanged = false;
private Function<String, List<String>> inlineDiffSplitter = SPLITTER_BY_CHARACTER;
private Builder() { private Builder() {
} }
@@ -105,6 +124,17 @@ public class DiffRowGenerator {
return this; return this;
} }
/**
* Give the originial old and new text lines to Diffrow without any additional processing.
*
* @param val the value to set. Default: false.
* @return builder with configured reportLinesUnWrapped parameter
*/
public Builder reportLinesUnchanged(final boolean val) {
reportLinesUnchanged = val;
return this;
}
/** /**
* Generator for Old-Text-Tags. * Generator for Old-Text-Tags.
* *
@@ -130,11 +160,11 @@ public class DiffRowGenerator {
/** /**
* Set the column with of generated lines of original and revised texts. * Set the column with 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 * @param width the width to set. Making it < 0 doesn't have any sense. Default 80. @return builder with config
* builder with config ured ignoreBlankLines parameter * ured ignoreBlankLines parameter
*/ */
public Builder columnWidth(int width) { public Builder columnWidth(int width) {
if (width > 0) { if (width >= 0) {
columnWidth = width; columnWidth = width;
} }
return this; return this;
@@ -150,8 +180,7 @@ public class DiffRowGenerator {
} }
/** /**
* Merge the complete result within the original text. This makes sense for one line * Merge the complete result within the original text. This makes sense for one line display.
* display.
* *
* @param mergeOriginalRevised * @param mergeOriginalRevised
* @return * @return
@@ -162,11 +191,17 @@ public class DiffRowGenerator {
} }
/** /**
* Per default each character is separatly processed. This variant introduces processing by * Per default each character is separatly processed. This variant introduces processing by word, which should
* word, which should deliver no in word changes. * deliver no in word changes.
*/ */
public Builder inlineDiffByWord(boolean inlineDiffByWord) { public Builder inlineDiffByWord(boolean inlineDiffByWord) {
this.inlineDiffByWord = inlineDiffByWord; inlineDiffSplitter = inlineDiffByWord?SPLITTER_BY_WORD:SPLITTER_BY_CHARACTER;
return this;
}
public Builder inlineDiffBySplitter(Function<String, List<String>> inlineDiffSplitter) {
this.inlineDiffSplitter = inlineDiffSplitter;
return this; return this;
} }
} }
@@ -174,7 +209,7 @@ public class DiffRowGenerator {
public static Builder create() { public static Builder create() {
return new Builder(); return new Builder();
} }
private DiffRowGenerator(Builder builder) { private DiffRowGenerator(Builder builder) {
showInlineDiffs = builder.showInlineDiffs; showInlineDiffs = builder.showInlineDiffs;
ignoreWhiteSpaces = builder.ignoreWhiteSpaces; ignoreWhiteSpaces = builder.ignoreWhiteSpaces;
@@ -182,13 +217,16 @@ public class DiffRowGenerator {
newTag = builder.newTag; newTag = builder.newTag;
columnWidth = builder.columnWidth; columnWidth = builder.columnWidth;
mergeOriginalRevised = builder.mergeOriginalRevised; mergeOriginalRevised = builder.mergeOriginalRevised;
inlineDiffByWord = builder.inlineDiffByWord; inlineDiffSplitter = builder.inlineDiffSplitter;
equalizer = ignoreWhiteSpaces?IGNORE_WHITESPACE_EQUALIZER:DEFAULT_EQUALIZER; equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
reportLinesUnchanged = builder.reportLinesUnchanged;
Objects.requireNonNull(inlineDiffSplitter);
} }
/** /**
* Get the DiffRows describing the difference between original and revised texts using the given * Get the DiffRows describing the difference between original and revised texts using the given patch. Useful for
* patch. Useful for displaying side-by-side diff. * displaying side-by-side diff.
* *
* @param original the original text * @param original the original text
* @param revised the revised text * @param revised the revised text
@@ -198,22 +236,34 @@ public class DiffRowGenerator {
return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer)); return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer));
} }
private String preprocessLine(String line) {
if (columnWidth == 0) {
return StringUtils.normalize(line);
} else {
return StringUtils.wrapText(StringUtils.normalize(line), columnWidth);
}
}
private DiffRow buildDiffRow(Tag type, String orgline, String newline) { private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
String wrapOrg = StringUtils.wrapText(StringUtils.normalize(orgline), columnWidth); if (reportLinesUnchanged) {
if (Tag.DELETE == type) { return new DiffRow(type, orgline, newline);
if (mergeOriginalRevised || showInlineDiffs) { } else {
wrapOrg = oldTag.apply(true) + wrapOrg + oldTag.apply(false); String wrapOrg = preprocessLine(orgline);
if (Tag.DELETE == type) {
if (mergeOriginalRevised || showInlineDiffs) {
wrapOrg = oldTag.apply(true) + wrapOrg + oldTag.apply(false);
}
} }
} String wrapNew = preprocessLine(newline);
String wrapNew = StringUtils.wrapText(StringUtils.normalize(newline), columnWidth); if (Tag.INSERT == type) {
if (Tag.INSERT == type) { if (mergeOriginalRevised) {
if (mergeOriginalRevised) { wrapOrg = newTag.apply(true) + wrapNew + newTag.apply(false);
wrapOrg = newTag.apply(true) + wrapNew + newTag.apply(false); } else if (showInlineDiffs) {
} else if (showInlineDiffs) { wrapNew = newTag.apply(true) + wrapNew + newTag.apply(false);
wrapNew = newTag.apply(true) + wrapNew + newTag.apply(false); }
} }
return new DiffRow(type, wrapOrg, wrapNew);
} }
return new DiffRow(type, wrapOrg, wrapNew);
} }
private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String newline) { private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String newline) {
@@ -223,8 +273,8 @@ public class DiffRowGenerator {
} }
/** /**
* Generates the DiffRows describing the difference between original and revised texts using the * Generates the DiffRows describing the difference between original and revised texts using the given patch. Useful
* given patch. Useful for displaying side-by-side diff. * for displaying side-by-side diff.
* *
* @param original the original text * @param original the original text
* @param revised the revised text * @param revised the revised text
@@ -291,20 +341,11 @@ public class DiffRowGenerator {
List<String> rev = StringUtils.normalize(delta.getRevised().getLines()); List<String> rev = StringUtils.normalize(delta.getRevised().getLines());
List<String> origList; List<String> origList;
List<String> revList; List<String> revList;
String joinedOrig = String.join("\n", orig);
String joinedRev = String.join("\n", rev);
if (inlineDiffByWord) { origList = inlineDiffSplitter.apply(joinedOrig);
origList = splitStringPreserveDelimiter(String.join("\n", orig)); revList = inlineDiffSplitter.apply(joinedRev);
revList = splitStringPreserveDelimiter(String.join("\n", rev));
} else {
origList = new LinkedList<>();
revList = new LinkedList<>();
for (Character character : String.join("\n", orig).toCharArray()) {
origList.add(character.toString());
}
for (Character character : String.join("\n", rev).toCharArray()) {
revList.add(character.toString());
}
}
List<Delta<String>> inlineDeltas = DiffUtils.diff(origList, revList).getDeltas(); List<Delta<String>> inlineDeltas = DiffUtils.diff(origList, revList).getDeltas();
@@ -367,8 +408,7 @@ public class DiffRowGenerator {
/** /**
* Wrap the elements in the sequence with the given tag * Wrap the elements in the sequence with the given tag
* *
* @param startPosition the position from which tag should start. The counting start from a * @param startPosition the position from which tag should start. The counting start from a zero.
* zero.
* @param endPosition the position before which tag should should be closed. * @param endPosition the position before which tag should should be closed.
* @param tag the tag name without angle brackets, just a word * @param tag the tag name without angle brackets, just a word
* @param cssClass the optional css class * @param cssClass the optional css class
@@ -379,7 +419,7 @@ public class DiffRowGenerator {
sequence.add(endPosition, generator.apply(false)); sequence.add(endPosition, generator.apply(false));
} }
protected final static List<String> splitStringPreserveDelimiter(String str) { protected final static List<String> splitStringPreserveDelimiter(String str, Pattern SPLIT_PATTERN) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
if (str != null) { if (str != null) {
Matcher matcher = SPLIT_PATTERN.matcher(str); Matcher matcher = SPLIT_PATTERN.matcher(str);

View File

@@ -58,8 +58,11 @@ final class StringUtils {
* @return the wrapped text * @return the wrapped text
*/ */
public static String wrapText(String line, int columnWidth) { public static String wrapText(String line, int columnWidth) {
if (columnWidth <= 0) { if (columnWidth < 0) {
throw new IllegalArgumentException("columnWidth may not be less or equal 0"); throw new IllegalArgumentException("columnWidth may not be less 0");
}
if (columnWidth == 0) {
return line;
} }
int length = line.length(); int length = line.length();
int delimiter = "<br/>".length(); int delimiter = "<br/>".length();

View File

@@ -1,6 +1,5 @@
package com.github.difflib; package com.github.difflib;
import com.github.difflib.DiffUtils;
import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.ChangeDelta; import com.github.difflib.patch.ChangeDelta;
import com.github.difflib.patch.Chunk; import com.github.difflib.patch.Chunk;
@@ -138,25 +137,25 @@ public class DiffUtilsTest {
@Ignore @Ignore
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException { public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException {
ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip"); ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip");
Patch<String> patch = DiffUtils.diff( Patch<String> patch = DiffUtils.diff(
readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta"))), readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta"))),
readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")))); readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb"))));
assertEquals(1, patch.getDeltas().size()); assertEquals(1, patch.getDeltas().size());
} }
public static List<String> readStringListFromInputStream(InputStream is) throws IOException { public static List<String> readStringListFromInputStream(InputStream is) throws IOException {
try (BufferedReader reader = new BufferedReader( try (BufferedReader reader = new BufferedReader(
new InputStreamReader(is, Charset.forName(StandardCharsets.UTF_8.name())))) { new InputStreamReader(is, Charset.forName(StandardCharsets.UTF_8.name())))) {
return reader.lines().collect(toList()); return reader.lines().collect(toList());
} }
} }
@Test @Test
public void testDiffMyersExample1() throws DiffException { public void testDiffMyersExample1() throws DiffException {
final Patch<String> patch = DiffUtils.diff(Arrays.asList("A","B","C","A","B","B","A"), Arrays.asList("C","B","A","B","A","C")); final Patch<String> patch = DiffUtils.diff(Arrays.asList("A", "B", "C", "A", "B", "B", "A"), Arrays.asList("C", "B", "A", "B", "A", "C"));
assertNotNull(patch); assertNotNull(patch);
assertEquals(4, patch.getDeltas().size()); assertEquals(4, patch.getDeltas().size());
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString()); assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());

View File

@@ -1,7 +1,5 @@
package com.github.difflib; package com.github.difflib;
import com.github.difflib.DiffUtils;
import com.github.difflib.UnifiedDiffUtils;
import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.Patch; import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException; import com.github.difflib.patch.PatchFailedException;

View File

@@ -7,6 +7,7 @@ package com.github.difflib;
* *
*/ */
public final class TestConstants { public final class TestConstants {
public static final String BASE_FOLDER_RESOURCES = "target/test-classes/"; public static final String BASE_FOLDER_RESOURCES = "target/test-classes/";
/** /**
* The base folder containing the test files. Ends with {@link #FS}. * The base folder containing the test files. Ends with {@link #FS}.

View File

@@ -15,44 +15,39 @@
*/ */
package com.github.difflib.algorithm.jgit; package com.github.difflib.algorithm.jgit;
import com.github.difflib.algorithm.jgit.HistogramDiff;
import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream;
import com.github.difflib.TestConstants;
import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.Patch; import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException; import com.github.difflib.patch.PatchFailedException;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.zip.ZipFile;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
/** /**
* *
* @author toben * @author toben
*/ */
public class HistogramDiffTest { public class HistogramDiffTest {
public HistogramDiffTest() { public HistogramDiffTest() {
} }
@BeforeClass @BeforeClass
public static void setUpClass() { public static void setUpClass() {
} }
@AfterClass @AfterClass
public static void tearDownClass() { public static void tearDownClass() {
} }
@Before @Before
public void setUp() { public void setUp() {
} }
@After @After
public void tearDown() { public void tearDown() {
} }
@@ -62,14 +57,14 @@ public class HistogramDiffTest {
*/ */
@Test @Test
public void testDiff() throws DiffException, PatchFailedException { public void testDiff() throws DiffException, PatchFailedException {
List<String> orgList = Arrays.asList("A","B","C","A","B","B","A"); List<String> orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
List<String> revList = Arrays.asList("C","B","A","B","A","C"); List<String> revList = Arrays.asList("C", "B", "A", "B", "A", "C");
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().diff(orgList, revList)); final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().diff(orgList, revList));
System.out.println(patch); System.out.println(patch);
assertNotNull(patch); assertNotNull(patch);
assertEquals(3, patch.getDeltas().size()); assertEquals(3, patch.getDeltas().size());
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [DeleteDelta, position: 3, lines: [A, B]], [InsertDelta, position: 7, lines: [B, A, C]]]}", patch.toString()); assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [DeleteDelta, position: 3, lines: [A, B]], [InsertDelta, position: 7, lines: [B, A, C]]]}", patch.toString());
List<String> patched = patch.applyTo(orgList); List<String> patched = patch.applyTo(orgList);
assertEquals(revList, patched); assertEquals(revList, patched);
} }

View File

@@ -15,61 +15,58 @@
*/ */
package com.github.difflib.algorithm.jgit; package com.github.difflib.algorithm.jgit;
import com.github.difflib.algorithm.jgit.HistogramDiff;
import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream; import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream;
import com.github.difflib.TestConstants; import com.github.difflib.TestConstants;
import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.Patch; import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException; import com.github.difflib.patch.PatchFailedException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
/** /**
* *
* @author toben * @author toben
*/ */
public class LRHistogramDiffTest { public class LRHistogramDiffTest {
public LRHistogramDiffTest() { public LRHistogramDiffTest() {
} }
@BeforeClass @BeforeClass
public static void setUpClass() { public static void setUpClass() {
} }
@AfterClass @AfterClass
public static void tearDownClass() { public static void tearDownClass() {
} }
@Before @Before
public void setUp() { public void setUp() {
} }
@After @After
public void tearDown() { public void tearDown() {
} }
@Test @Test
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException, PatchFailedException { public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException, PatchFailedException {
ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip"); ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip");
List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta"))); List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta")));
List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb"))); List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")));
Patch<String> patch = Patch.generate(original, revised, new HistogramDiff().diff(original, revised)); Patch<String> patch = Patch.generate(original, revised, new HistogramDiff().diff(original, revised));
assertEquals(34, patch.getDeltas().size()); assertEquals(34, patch.getDeltas().size());
List<String> created = patch.applyTo(original); List<String> created = patch.applyTo(original);
assertArrayEquals(revised.toArray(), created.toArray()); assertArrayEquals(revised.toArray(), created.toArray());
} }
} }

View File

@@ -15,18 +15,12 @@
*/ */
package com.github.difflib.algorithm.myers; package com.github.difflib.algorithm.myers;
import com.github.difflib.algorithm.myers.MyersDiff;
import com.github.difflib.DiffUtils;
import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.Patch; import com.github.difflib.patch.Patch;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Test;
/** /**
* *

View File

@@ -1,7 +1,5 @@
package com.github.difflib.patch; package com.github.difflib.patch;
import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException;
import com.github.difflib.DiffUtils; import com.github.difflib.DiffUtils;
import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DiffException;
import java.util.Arrays; import java.util.Arrays;

View File

@@ -1,10 +1,9 @@
package com.github.difflib.text; package com.github.difflib.text;
import com.github.difflib.text.DiffRow;
import com.github.difflib.text.DiffRowGenerator;
import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DiffException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
@@ -25,6 +24,20 @@ public class DiffRowGeneratorTest {
assertEquals(3, rows.size()); assertEquals(3, rows.size());
} }
@Test
public void testGenerator_Default2() throws DiffException {
String first = "anything \n \nother";
String second = "anything\n\nother";
DiffRowGenerator generator = DiffRowGenerator.create()
.columnWidth(0) // do not wrap
.build();
List<DiffRow> rows = generator.generateDiffRows(split(first), split(second));
print(rows);
assertEquals(3, rows.size());
}
@Test @Test
public void testGenerator_InlineDiff() throws DiffException { public void testGenerator_InlineDiff() throws DiffException {
String first = "anything \n \nother"; String first = "anything \n \nother";
@@ -69,14 +82,14 @@ public class DiffRowGeneratorTest {
System.out.println(row); System.out.println(row);
} }
} }
@Test @Test
public void testGeneratorWithWordWrap() throws DiffException { public void testGeneratorWithWordWrap() throws DiffException {
String first = "anything \n \nother"; String first = "anything \n \nother";
String second = "anything\n\nother"; String second = "anything\n\nother";
DiffRowGenerator generator = DiffRowGenerator.create() DiffRowGenerator generator = DiffRowGenerator.create()
.columnWidth(5) .columnWidth(5)
.build(); .build();
List<DiffRow> rows = generator.generateDiffRows(split(first), split(second)); List<DiffRow> rows = generator.generateDiffRows(split(first), split(second));
print(rows); print(rows);
@@ -86,7 +99,7 @@ public class DiffRowGeneratorTest {
assertEquals("[CHANGE, ,]", rows.get(1).toString()); assertEquals("[CHANGE, ,]", rows.get(1).toString());
assertEquals("[EQUAL,other,other]", rows.get(2).toString()); assertEquals("[EQUAL,other,other]", rows.get(2).toString());
} }
@Test @Test
public void testGeneratorWithMerge() throws DiffException { public void testGeneratorWithMerge() throws DiffException {
String first = "anything \n \nother"; String first = "anything \n \nother";
@@ -104,20 +117,20 @@ public class DiffRowGeneratorTest {
assertEquals("[CHANGE,<span class=\"editOldInline\"> </span>,]", rows.get(1).toString()); assertEquals("[CHANGE,<span class=\"editOldInline\"> </span>,]", rows.get(1).toString());
assertEquals("[EQUAL,other,other]", rows.get(2).toString()); assertEquals("[EQUAL,other,other]", rows.get(2).toString());
} }
@Test @Test
public void testGeneratorWithMerge2() throws DiffException { public void testGeneratorWithMerge2() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create() DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true) .showInlineDiffs(true)
.mergeOriginalRevised(true) .mergeOriginalRevised(true)
.build(); .build();
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test"),Arrays.asList("ester")); List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test"), Arrays.asList("ester"));
print(rows); print(rows);
assertEquals(1, rows.size()); assertEquals(1, rows.size());
assertEquals("[CHANGE,<span class=\"editOldInline\">T</span>est<span class=\"editNewInline\">er</span>,ester]", rows.get(0).toString()); assertEquals("[CHANGE,<span class=\"editOldInline\">T</span>est<span class=\"editNewInline\">er</span>,ester]", rows.get(0).toString());
} }
@Test @Test
public void testGeneratorWithMerge3() throws DiffException { public void testGeneratorWithMerge3() throws DiffException {
String first = "test\nanything \n \nother"; String first = "test\nanything \n \nother";
@@ -138,7 +151,7 @@ public class DiffRowGeneratorTest {
assertEquals("[INSERT,<span class=\"editNewInline\">test</span>,test]", rows.get(4).toString()); assertEquals("[INSERT,<span class=\"editNewInline\">test</span>,test]", rows.get(4).toString());
assertEquals("[INSERT,<span class=\"editNewInline\">test2</span>,test2]", rows.get(5).toString()); assertEquals("[INSERT,<span class=\"editNewInline\">test2</span>,test2]", rows.get(5).toString());
} }
@Test @Test
public void testGeneratorWithMergeByWord4() throws DiffException { public void testGeneratorWithMergeByWord4() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create() DiffRowGenerator generator = DiffRowGenerator.create()
@@ -146,51 +159,51 @@ public class DiffRowGeneratorTest {
.mergeOriginalRevised(true) .mergeOriginalRevised(true)
.inlineDiffByWord(true) .inlineDiffByWord(true)
.build(); .build();
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test"),Arrays.asList("ester")); List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test"), Arrays.asList("ester"));
print(rows); print(rows);
assertEquals(1, rows.size()); assertEquals(1, rows.size());
assertEquals("[CHANGE,<span class=\"editOldInline\">Test</span><span class=\"editNewInline\">ester</span>,ester]", rows.get(0).toString()); assertEquals("[CHANGE,<span class=\"editOldInline\">Test</span><span class=\"editNewInline\">ester</span>,ester]", rows.get(0).toString());
} }
@Test @Test
public void testGeneratorWithMergeByWord5() throws DiffException { public void testGeneratorWithMergeByWord5() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create() DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true) .showInlineDiffs(true)
.mergeOriginalRevised(true) .mergeOriginalRevised(true)
.inlineDiffByWord(true) .inlineDiffByWord(true)
.columnWidth(80)
.build(); .build();
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test feature"),Arrays.asList("ester feature best")); List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test feature"), Arrays.asList("ester feature best"));
print(rows); print(rows);
assertEquals(1, rows.size()); assertEquals(1, rows.size());
assertEquals("[CHANGE,<span class=\"editOldInline\">Test</span><span class=\"editNewInline\">ester</span> <br/>feature<span class=\"editNewInline\"> best</span>,ester feature best]", rows.get(0).toString()); assertEquals("[CHANGE,<span class=\"editOldInline\">Test</span><span class=\"editNewInline\">ester</span> <br/>feature<span class=\"editNewInline\"> best</span>,ester feature best]", rows.get(0).toString());
} }
@Test @Test
public void testSplitString() { public void testSplitString() {
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test,test2"); List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test,test2", DiffRowGenerator.SPLIT_BY_WORD_PATTERN);
assertEquals(3, list.size()); assertEquals(3, list.size());
assertEquals("[test, ,, test2]", list.toString()); assertEquals("[test, ,, test2]", list.toString());
} }
@Test @Test
public void testSplitString2() { public void testSplitString2() {
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test , test2"); List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test , test2", DiffRowGenerator.SPLIT_BY_WORD_PATTERN);
System.out.println(list); System.out.println(list);
assertEquals(5, list.size()); assertEquals(5, list.size());
assertEquals("[test, , ,, , test2]", list.toString()); assertEquals("[test, , ,, , test2]", list.toString());
} }
@Test @Test
public void testSplitString3() { public void testSplitString3() {
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test,test2,"); List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test,test2,", DiffRowGenerator.SPLIT_BY_WORD_PATTERN);
System.out.println(list); System.out.println(list);
assertEquals(4, list.size()); assertEquals(4, list.size());
assertEquals("[test, ,, test2, ,]", list.toString()); assertEquals("[test, ,, test2, ,]", list.toString());
} }
@Test @Test
public void testGeneratorExample1() throws DiffException { public void testGeneratorExample1() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create() DiffRowGenerator generator = DiffRowGenerator.create()
@@ -203,13 +216,13 @@ public class DiffRowGeneratorTest {
List<DiffRow> rows = generator.generateDiffRows( List<DiffRow> rows = generator.generateDiffRows(
Arrays.asList("This is a test senctence."), Arrays.asList("This is a test senctence."),
Arrays.asList("This is a test for diffutils.")); Arrays.asList("This is a test for diffutils."));
System.out.println(rows.get(0).getOldLine()); System.out.println(rows.get(0).getOldLine());
assertEquals(1, rows.size()); assertEquals(1, rows.size());
assertEquals("This is a test ~senctence~**for diffutils**.", rows.get(0).getOldLine()); assertEquals("This is a test ~senctence~**for diffutils**.", rows.get(0).getOldLine());
} }
@Test @Test
public void testGeneratorExample2() throws DiffException { public void testGeneratorExample2() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create() DiffRowGenerator generator = DiffRowGenerator.create()
@@ -221,15 +234,52 @@ public class DiffRowGeneratorTest {
List<DiffRow> rows = generator.generateDiffRows( List<DiffRow> rows = generator.generateDiffRows(
Arrays.asList("This is a test senctence.", "This is the second line.", "And here is the finish."), Arrays.asList("This is a test senctence.", "This is the second line.", "And here is the finish."),
Arrays.asList("This is a test for diffutils.", "This is the second line.")); Arrays.asList("This is a test for diffutils.", "This is the second line."));
System.out.println("|original|new|"); System.out.println("|original|new|");
System.out.println("|--------|---|"); System.out.println("|--------|---|");
for (DiffRow row : rows) { for (DiffRow row : rows) {
System.out.println("|" + row.getOldLine() + "|" + row.getNewLine() + "|"); System.out.println("|" + row.getOldLine() + "|" + row.getNewLine() + "|");
} }
assertEquals(3, rows.size()); assertEquals(3, rows.size());
assertEquals("This is a test ~senctence~.", rows.get(0).getOldLine()); assertEquals("This is a test ~senctence~.", rows.get(0).getOldLine());
assertEquals("This is a test **for diffutils**.", rows.get(0).getNewLine()); assertEquals("This is a test **for diffutils**.", rows.get(0).getNewLine());
} }
@Test
public void testGeneratorUnchanged() throws DiffException {
String first = "anything \n \nother";
String second = "anything\n\nother";
DiffRowGenerator generator = DiffRowGenerator.create()
.columnWidth(5)
.reportLinesUnchanged(true)
.build();
List<DiffRow> rows = generator.generateDiffRows(split(first), split(second));
print(rows);
assertEquals(3, rows.size());
assertEquals("[CHANGE,anything ,anything]", rows.get(0).toString());
assertEquals("[CHANGE, ,]", rows.get(1).toString());
assertEquals("[EQUAL,other,other]", rows.get(2).toString());
}
@Test
public void testGeneratorIssue14() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.mergeOriginalRevised(true)
.inlineDiffBySplitter(line -> DiffRowGenerator.splitStringPreserveDelimiter(line, Pattern.compile(",")))
.oldTag(f -> "~")
.newTag(f -> "**")
.build();
List<DiffRow> rows = generator.generateDiffRows(
Arrays.asList("J. G. Feldstein, Chair"),
Arrays.asList("T. P. Pastor, Chair"));
System.out.println(rows.get(0).getOldLine());
assertEquals(1, rows.size());
assertEquals("~J. G. Feldstein~**T. P. Pastor**, Chair", rows.get(0).getOldLine());
}
} }

View File

@@ -15,10 +15,9 @@
*/ */
package com.github.difflib.text; package com.github.difflib.text;
import com.github.difflib.text.StringUtils;
import java.util.Collections; import java.util.Collections;
import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Test;
/** /**
* *
@@ -39,7 +38,7 @@ public class StringUtilsTest {
*/ */
@Test @Test
public void testNormalize_String() { public void testNormalize_String() {
assertEquals(" test",StringUtils.normalize("\ttest")); assertEquals(" test", StringUtils.normalize("\ttest"));
} }
/** /**
@@ -47,7 +46,7 @@ public class StringUtilsTest {
*/ */
@Test @Test
public void testNormalize_List() { public void testNormalize_List() {
assertEquals(Collections.singletonList(" test"),StringUtils.normalize(Collections.singletonList("\ttest"))); assertEquals(Collections.singletonList(" test"), StringUtils.normalize(Collections.singletonList("\ttest")));
} }
/** /**
@@ -59,10 +58,10 @@ public class StringUtilsTest {
assertEquals("tes<br/>t", StringUtils.wrapText("test", 3)); assertEquals("tes<br/>t", StringUtils.wrapText("test", 3));
assertEquals("test", StringUtils.wrapText("test", 10)); assertEquals("test", StringUtils.wrapText("test", 10));
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testWrapText_String_int_zero() { public void testWrapText_String_int_zero() {
assertEquals("test", StringUtils.wrapText("test", 0)); assertEquals("test", StringUtils.wrapText("test", -1));
} }
} }