Skip to content

Commit

Permalink
change algorithm for duplicate lines
Browse files Browse the repository at this point in the history
  • Loading branch information
yoelb committed Jun 12, 2014
1 parent ecd847d commit 8a76735
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 41 deletions.
78 changes: 37 additions & 41 deletions core/src/main/java/cucumber/runtime/table/TableDiffer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cucumber.runtime.table;

import com.google.common.collect.Sets;
import cucumber.api.DataTable;
import cucumber.deps.difflib.Delta;
import cucumber.deps.difflib.DiffUtils;
Expand All @@ -9,10 +8,10 @@
import gherkin.formatter.model.Row;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class TableDiffer {

Expand Down Expand Up @@ -41,18 +40,46 @@ public void calculateDiffs() throws TableDiffException {
}

public void calculateUnorderedDiffs() throws TableDiffException {
Set<List<String>> rowsSet = Sets.newHashSet(from.raw());
Set<List<String>> otherRowsSet = Sets.newHashSet(to.raw());
boolean isDifferent = false;
List<DataTableRow> diffTableRows = new ArrayList<DataTableRow>();
List<List<String>> missingRow = new ArrayList<List<String>>();

ArrayList<List<String>> extraRows = new ArrayList<List<String>>();

// missing rows from origin
Set<List<String>> missingRows = Sets.difference(rowsSet, otherRowsSet);
// 1. add all "to" row in extra table
// 2. iterate over "from", when a common row occurs, remove it from extraRows
// finally, only extra rows are kept and in same order that in "to".
extraRows.addAll(to.raw());

// missing rows
Set<List<String>> extraRows = Sets.difference(otherRowsSet, rowsSet);
int i = 1;
for (DataTableRow r : from.getGherkinRows()) {
if (!to.raw().contains(r.getCells())) {
missingRow.add(r.getCells());
diffTableRows.add(
new DataTableRow(r.getComments(),
r.getCells(),
i,
Row.DiffType.DELETE));
isDifferent = true;
} else {
diffTableRows.add(
new DataTableRow(r.getComments(),
r.getCells(),
i++));
extraRows.remove(r.getCells());
}
}

for (List<String> e : extraRows) {
diffTableRows.add(new DataTableRow(Collections.EMPTY_LIST,
e,
i++,
Row.DiffType.INSERT));
isDifferent = true;
}

if (!missingRows.isEmpty() || !extraRows.isEmpty()){
throw new TableDiffException(from, to, createTableDiffSet(missingRows, extraRows));
if (isDifferent) {
throw new TableDiffException(from, to, new DataTable(diffTableRows, from.getTableConverter()));
}
}

Expand Down Expand Up @@ -107,35 +134,4 @@ private void markChangedAndInsertedRowsInRevisedAsNew(List<DataTableRow> diffTab
diffTableRows.add(new DataTableRow(row.row.getComments(), row.row.getCells(), row.row.getLine(), Row.DiffType.INSERT));
}
}

private DataTable createTableDiffSet(Set<List<String>> rowDiffOther, Set<List<String>> extraRows) {
List<DataTableRow> diffTableRows = new ArrayList<DataTableRow>();

// iterate over from to detect missing rows
for (int i = 0; i < from.raw().size(); i++) {
DataTableRow currentGerkinRow = from.getGherkinRows().get(i);
if (rowDiffOther.contains(from.raw().get(i))) {
diffTableRows.add(
new DataTableRow(currentGerkinRow.getComments(),
currentGerkinRow.getCells(),
currentGerkinRow.getLine(),
Row.DiffType.DELETE));
} else {
diffTableRows.add(from.getGherkinRows().get(i));
}
}

// iterate over to, to detect extra rows
for (int i = 0; i < to.raw().size(); i++) {
DataTableRow currentGerkinRow = to.getGherkinRows().get(i);
if (extraRows.contains(to.raw().get(i))) {
diffTableRows.add(
new DataTableRow(currentGerkinRow.getComments(),
currentGerkinRow.getCells(),
currentGerkinRow.getLine(),
Row.DiffType.INSERT));
}
}
return new DataTable(diffTableRows, from.getTableConverter());
}
}
78 changes: 78 additions & 0 deletions core/src/test/java/cucumber/runtime/table/TableDifferTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ private DataTable table() {
return TableParser.parse(source, null);
}

private DataTable tableWithDuplicate() {
String source = "" +
"| Aslak | aslak@email.com | 123 |\n" +
"| Joe | joe@email.com | 234 |\n" +
"| Bryan | bryan@email.org | 456 |\n" +
"| Joe | joe@email.com | 234 |\n" +
"| Ni | ni@email.com | 654 |\n" +
"| Ni | ni@email.com | 654 |\n" ;
return TableParser.parse(source, null);
}

private DataTable otherTableWithTwoConsecutiveRowsDeleted() {
String source = "" +
"| Aslak | aslak@email.com | 123 |\n" +
Expand Down Expand Up @@ -78,6 +89,31 @@ private DataTable otherTableWithDifferentOrder() {
return TableParser.parse(source, null);
}

private DataTable otherTableWithDifferentOrderAndDuplicate() {
String source = "" +
"| Joe | joe@email.com | 234 |\n" +
"| Aslak | aslak@email.com | 123 |\n" +
"| Bryan | bryan@email.org | 456 |\n" +
"| Ni | ni@email.com | 654 |\n"+
"| Ni | ni@email.com | 654 |\n" +
"| Joe | joe@email.com | 234 |\n" ;
return TableParser.parse(source, null);
}

private DataTable otherTableWithDifferentOrderDuplicateAndDeleted() {
String source = "" +
"| Joe | joe@email.com | 234 |\n" +
"| Bryan | bryan@email.org | 456 |\n" +
"| Bryan | bryan@email.org | 456 |\n" +
"| Ni | ni@email.com | 654 |\n" +
"| Bob | bob.email.com | 555 |\n" +
"| Bryan | bryan@email.org | 456 |\n" +
"| Ni | ni@email.com | 654 |\n" +
"| Joe | joe@email.com | 234 |\n" ;

return TableParser.parse(source, null);
}

private DataTable otherTableWithDeletedAndInsertedDifferentOrder() {
String source = "" +
"| Doe | joe@email.com | 234 |\n" +
Expand Down Expand Up @@ -347,4 +383,46 @@ public void unordered_diff_with_list_of_pojos_and_camelcase_header_mapping() {
actual.add(new TestPojo(1, "me", 123));
expected.unorderedDiff(actual);
}

@Test(expected = TableDiffException.class)
public void unordered_diff_with_added_duplicate_in_other() {
DataTable other = otherTableWithDifferentOrderAndDuplicate();
try {
table().unorderedDiff(other);
} catch (TableDiffException e) {
System.out.println(e.getMessage());
String expected = "" +
"Tables were not identical:\n" +
" | Aslak | aslak@email.com | 123 |\n" +
" | Joe | joe@email.com | 234 |\n" +
" | Bryan | bryan@email.org | 456 |\n" +
" | Ni | ni@email.com | 654 |\n" +
" + | Ni | ni@email.com | 654 |\n" +
" + | Joe | joe@email.com | 234 |\n" ;
assertEquals(expected, e.getMessage());
throw e;
}
}

@Test(expected = TableDiffException.class)
public void unordered_diff_with_added_duplicate_and_deleted_in_other() {
DataTable other = otherTableWithDifferentOrderDuplicateAndDeleted();
try {
tableWithDuplicate().unorderedDiff(other);
} catch (TableDiffException e) {
String expected = "" +
"Tables were not identical:\n" +
" - | Aslak | aslak@email.com | 123 |\n" +
" | Joe | joe@email.com | 234 |\n" +
" | Bryan | bryan@email.org | 456 |\n" +
" | Joe | joe@email.com | 234 |\n" +
" | Ni | ni@email.com | 654 |\n" +
" | Ni | ni@email.com | 654 |\n" +
" + | Bryan | bryan@email.org | 456 |\n" +
" + | Bob | bob.email.com | 555 |\n" +
" + | Bryan | bryan@email.org | 456 |\n" ;
assertEquals(expected, e.getMessage());
throw e;
}
}
}

0 comments on commit 8a76735

Please sign in to comment.