cucumber.table.TableDiffer Maven / Gradle / Ivy
package cucumber.table;
import difflib.Delta;
import difflib.DiffUtils;
import difflib.Patch;
import gherkin.formatter.model.DataTableRow;
import gherkin.formatter.model.Row;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TableDiffer {
private final DataTable orig;
private final DataTable other;
public TableDiffer(DataTable origTable, DataTable otherTable) {
checkColumns(origTable, otherTable);
this.orig = origTable;
this.other = otherTable;
}
private void checkColumns(DataTable a, DataTable b) {
if (a.topCells().size() != b.topCells().size()) {
throw new IllegalArgumentException("Tables must have equal number of columns:\n" + a + "\n" + b);
}
}
public void calculateDiffs() throws TableDiffException {
Patch patch = DiffUtils.diff(orig.diffableRows(), other.diffableRows());
List deltas = patch.getDeltas();
if (!deltas.isEmpty()) {
Map deltasByLine = createDeltasByLine(deltas);
throw new TableDiffException(createTableDiff(deltasByLine));
}
}
private DataTable createTableDiff(Map deltasByLine) {
List diffTableRows = new ArrayList();
List> rows = orig.raw();
for (int i = 0; i < rows.size(); i++) {
Delta delta = deltasByLine.get(i);
if (delta == null) {
diffTableRows.add(orig.getGherkinRows().get(i));
} else {
addRowsToTableDiff(diffTableRows, delta);
}
}
// Can have new lines at end
Delta remainingDelta = deltasByLine.get(rows.size());
if (remainingDelta != null) {
addRowsToTableDiff(diffTableRows, remainingDelta);
}
return new DataTable(diffTableRows, orig.getTableConverter());
}
private void addRowsToTableDiff(List diffTableRows, Delta delta) {
if (delta.getType() == Delta.TYPE.CHANGE || delta.getType() == Delta.TYPE.DELETE) {
List deletedLines = (List) delta.getOriginal().getLines();
for (DataTable.DiffableRow row : deletedLines) {
diffTableRows.add(new DataTableRow(row.row.getComments(), row.row.getCells(), row.row.getLine(), Row.DiffType.DELETE));
}
}
List insertedLines = (List) delta.getRevised().getLines();
for (DataTable.DiffableRow row : insertedLines) {
diffTableRows.add(new DataTableRow(row.row.getComments(), row.row.getCells(), row.row.getLine(), Row.DiffType.INSERT));
}
}
private Map createDeltasByLine(List deltas) {
Map deltasByLine = new HashMap();
for (Delta delta : deltas) {
deltasByLine.put(delta.getOriginal().getPosition(), delta);
}
return deltasByLine;
}
}