Skip to content

Commit 68c62f0

Browse files
sarinagurungjkozlowski
authored andcommitted
closes #9: Implement diffr.
1 parent b5761ce commit 68c62f0

File tree

28 files changed

+346
-8
lines changed

28 files changed

+346
-8
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package diffr.diff;
2+
3+
import com.google.common.collect.Lists;
4+
import diffr.suffixtree.SuffixTree;
5+
import diffr.suffixtree.SuffixTree.Matcher;
6+
import diffr.suffixtree.SuffixTrees;
7+
import diffr.util.instruction.CopyInstruction;
8+
import diffr.util.instruction.InsertInstruction;
9+
import diffr.util.instruction.Instruction;
10+
11+
import java.util.List;
12+
13+
import static com.google.common.base.Preconditions.checkNotNull;
14+
15+
/**
16+
* Generates a list of {@link Instruction}s to transform original file into a new file.
17+
*
18+
* @author Sarina Gurung
19+
* @author Jakub D Kozlowski
20+
* @since 0.3
21+
*/
22+
public final class Diffr {
23+
24+
private final List<String> originalFile;
25+
26+
private final List<String> newFile;
27+
28+
/**
29+
* Default constructor.
30+
*
31+
* @param originalFile original file to be transform.
32+
* @param newFile new file to transform {@code originalFile} to.
33+
*
34+
* @throws NullPointerException if any parameter is null.
35+
*/
36+
public Diffr(final List<String> originalFile, final List<String> newFile) {
37+
this.originalFile = checkNotNull(originalFile);
38+
this.newFile = checkNotNull(newFile);
39+
}
40+
41+
/**
42+
* Gets the list of {@link Instruction}s to transform {@code originalFile} to {@code newFile}.
43+
*
44+
* @return list of {@link Instruction}s.
45+
*/
46+
public List<Instruction> diff() {
47+
48+
final List<Instruction> instructions = Lists.newArrayList();
49+
final SuffixTree<String> suffixTree = SuffixTrees.newSuffixTree(this.originalFile);
50+
51+
Matcher<String> matcher = suffixTree.matcher();
52+
53+
for (final String newFileLine : newFile) {
54+
55+
if (!matcher.matchNext(newFileLine).isMatched()) {
56+
if (!matcher.isRoot()) {
57+
instructions.add(new CopyInstruction(matcher.range()));
58+
}
59+
instructions.add(new InsertInstruction(newFileLine));
60+
matcher = suffixTree.matcher();
61+
}
62+
}
63+
64+
if (!matcher.isRoot()) {
65+
instructions.add(new CopyInstruction(matcher.range()));
66+
}
67+
68+
return instructions;
69+
}
70+
71+
}
Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
package diffr.diff;
22

3+
import com.google.common.io.Files;
4+
import diffr.util.instruction.Instruction;
5+
import diffr.util.instruction.InstructionComposer;
6+
7+
import java.io.File;
8+
import java.io.IOException;
9+
import java.nio.charset.Charset;
10+
import java.util.List;
11+
312
/**
413
* Main entry point to diffr's DIFF tool.
514
*
@@ -12,6 +21,7 @@
1221
* </p>
1322
*
1423
* @author Jakub D Kozlowski
24+
* @author Sarina Gurung
1525
* @since 0.1
1626
*/
1727
public final class Main {
@@ -20,21 +30,51 @@ public final class Main {
2030
* Prints the usage of this tool.
2131
*/
2232
private static void printUsage() {
23-
System.out.println("diffr-diff <original-file> <new-file>");
33+
System.out.println("Usage: diffr <original-file> <new-file>");
2434
}
2535

2636
/**
2737
* Runs the diff tool on two files.
2838
*
2939
* @param args arguments to this tool.
3040
*/
31-
public static void main(String... args) {
41+
public static void main(String... args) throws IOException {
3242

33-
if (args.length != 2) {
34-
printUsage();
35-
System.exit(-1);
36-
}
43+
try {
44+
45+
if (args.length != 2) {
46+
printUsage();
47+
System.exit(-1);
48+
}
49+
50+
final File firstFile = new File(args[0]);
51+
final File secondFile = new File(args[1]);
52+
53+
if (!firstFile.exists()) {
54+
System.err.println("File " + firstFile + " not found.");
55+
System.exit(-1);
56+
}
3757

38-
System.exit(0);
58+
if (!secondFile.exists()) {
59+
System.err.println("File " + secondFile + " not found.");
60+
System.exit(-1);
61+
}
62+
63+
final List<String> originalFile = Files.readLines(firstFile, Charset.defaultCharset());
64+
final List<String> newFile = Files.readLines(secondFile, Charset.defaultCharset());
65+
66+
final List<Instruction> instructions = new Diffr(originalFile, newFile).diff();
67+
68+
for (final Instruction instruction : instructions) {
69+
System.out.println(InstructionComposer.composeString(instruction));
70+
}
71+
72+
System.out.flush();
73+
74+
System.exit(0);
75+
}
76+
catch (final IOException io) {
77+
System.err.println("There was a problem reading the files: " + io);
78+
}
3979
}
4080
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package diffr.diff;
2+
3+
import com.google.common.collect.Lists;
4+
import com.google.common.io.Files;
5+
import com.google.common.io.LineProcessor;
6+
import com.google.common.io.Resources;
7+
import diffr.util.instruction.Instruction;
8+
import diffr.util.instruction.InstructionComposer;
9+
import diffr.util.instruction.InstructionParser;
10+
import org.testng.annotations.DataProvider;
11+
import org.testng.annotations.Test;
12+
13+
import java.io.File;
14+
import java.io.IOException;
15+
import java.net.URISyntaxException;
16+
import java.nio.charset.Charset;
17+
import java.util.Collections;
18+
import java.util.Iterator;
19+
import java.util.List;
20+
21+
import static org.hamcrest.MatcherAssert.assertThat;
22+
import static org.hamcrest.Matchers.is;
23+
24+
/**
25+
* Tests {@link Diffr}.
26+
*
27+
* @author Sarina Gurung
28+
* @author Jakub D Kozlowski
29+
* @since 0.3
30+
*/
31+
public class DiffrTest {
32+
33+
private static final String DEFAULT_PROVIDER = "default-provider";
34+
35+
@DataProvider(name = "default-provider")
36+
public Object[][] getFiles() throws URISyntaxException, IOException {
37+
38+
final List<Object[]> files = Lists.newArrayList();
39+
40+
final File originalDir = new File(Resources.getResource("original").toURI());
41+
for (final File originalFile : originalDir.listFiles()) {
42+
final File newFile = new File(Resources.getResource("new/" + originalFile.getName()).toURI());
43+
final File patchFile = new File(Resources.getResource("patch/" + originalFile.getName()).toURI());
44+
files.add(new Object[]{
45+
Files.readLines(originalFile, Charset.defaultCharset()),
46+
Files.readLines(newFile, Charset.defaultCharset()),
47+
Files.readLines(patchFile, Charset.defaultCharset(), new LineProcessor<List<Instruction>>() {
48+
49+
private List<Instruction> instructions = Lists.newArrayList();
50+
51+
@Override
52+
public boolean processLine(String s) throws IOException {
53+
instructions.add(InstructionParser.parseInstruction(s).get());
54+
return true;
55+
}
56+
57+
@Override
58+
public List<Instruction> getResult() {
59+
return instructions;
60+
}
61+
})
62+
});
63+
}
64+
65+
return files.toArray(new Object[][]{});
66+
}
67+
68+
@Test(expectedExceptions = NullPointerException.class)
69+
public void testConstructorNullOriginalFile() {
70+
new Diffr(null, Collections.EMPTY_LIST);
71+
}
72+
73+
@Test(expectedExceptions = NullPointerException.class)
74+
public void testConstructorNullNewFile() {
75+
new Diffr(Collections.EMPTY_LIST, null);
76+
}
77+
78+
@Test(dataProvider = DEFAULT_PROVIDER)
79+
public void testDiff(final List<String> originalFile,
80+
final List<String> newFile,
81+
final List<Instruction> patchFile)
82+
throws IOException, URISyntaxException {
83+
84+
85+
final Diffr d = new Diffr(originalFile, newFile);
86+
87+
final Iterator<Instruction> actualInstructions = d.diff().iterator();
88+
89+
for (final Instruction expected : patchFile) {
90+
final Instruction actual = actualInstructions.next();
91+
assertThat(InstructionComposer.composeString(actual),
92+
is(InstructionComposer.composeString(expected)));
93+
}
94+
}
95+
}

diff/src/test/resources/new/test1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
One
2+
Two
3+
Three
4+
Five
5+
Seven

diff/src/test/resources/new/test2

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
One
2+
Two
3+
Three
4+
Five
5+
Seven
6+
Eight
7+
Nine

diff/src/test/resources/new/test3

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
One
2+
Two
3+
Three
4+
Five
5+
Seven
6+
Eight
7+
Nine
8+
Ten

diff/src/test/resources/new/test4

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
One
2+
Two
3+
Three
4+
Five
5+
Seven
6+
Eight
7+
Nine
8+
Ten
9+
Twelve
10+
Thirteen

diff/src/test/resources/new/test5

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
One
2+
Two
3+
Three
4+
Five
5+
Seven
6+
Eight
7+
Nine
8+
Ten
9+
Twelve
10+
Thirteen
11+
Fifteen

diff/src/test/resources/new/test6

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hi

diff/src/test/resources/new/test7

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hi

diff/src/test/resources/new/test9

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
January
2+
February
3+
March
4+
5+
April
6+
May
7+
June
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
One
2+
Two
3+
Three
4+
Four
5+
Six
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
One
2+
Two
3+
Three
4+
Four
5+
Six
6+
Eight
7+
Nine
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Some other line
2+
Two
3+
Three
4+
Four
5+
Six
6+
Eight
7+
Nine
8+
Elevan
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
One
2+
Two
3+
Three
4+
Four
5+
Six
6+
Eight
7+
Nine
8+
Elevan
9+
Twelve
10+
Thirteen
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
One
2+
Two
3+
Three
4+
Four
5+
Six
6+
Eight
7+
Nine
8+
Elevan
9+
Twelve
10+
Thirteen
11+
Fourteen
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hi
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
April
2+
May
3+
June
4+
5+
April
6+
May
7+
June

diff/src/test/resources/patch/test1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
0,2
2+
> Five
3+
> Seven

diff/src/test/resources/patch/test2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0,2
2+
> Five
3+
> Seven
4+
5,6

diff/src/test/resources/patch/test3

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
> One
2+
1,2
3+
> Five
4+
> Seven
5+
5,6
6+
> Ten

0 commit comments

Comments
 (0)