/*******************************************************************************
* Copyright (c) 2012 BMW Car IT and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.jnario.lib;
import static java.lang.Math.max;
import static java.lang.String.format;
import java.util.List;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.jnario.lib.internal.RowFailed;
import org.jnario.lib.internal.RowPassed;
import org.jnario.lib.internal.RowResult;
import org.jnario.lib.internal.RowResults;
/**
* @author Sebastian Benz - Initial contribution and API
*/
public class ExampleTableIterators<T extends ExampleTableRow> {
/**
* Performs an assertion on each row in an {@link ExampleTable}. All
* failures are collected and merged into a readable representation.
*
* @param table a table with examples
* @param assertion a closure which performs an assertion on each row.
*/
public static <T extends ExampleTableRow> void forEach(ExampleTable<T> table, Procedure1<T> assertion) {
new ExampleTableIterators<T>(table, assertion).perform();
}
private static final String INDENT = " ";
private final ExampleTable<T> table;
private final Procedure1<T> assertion;
protected ExampleTableIterators(ExampleTable<T> table, Procedure1<T> assertion) {
super();
this.table = table;
this.assertion = assertion;
}
public void perform() {
if(table.getRows().isEmpty()){
return;
}
RowResults results = new RowResults();
for (T row : table.getRows()) {
try {
assertion.apply(row);
results.add(new RowPassed(row));
} catch (Throwable e) {
results.add(new RowFailed(row, e));
}
}
if(results.hasFailed()){
throw newAssertionError(results);
}
}
private AssertionError newAssertionError(RowResults results) {
AssertionError error = new AssertionError(createMessage(results));
error.setStackTrace(results.getStackTrace());
return error;
}
private String createMessage(RowResults results) {
String formatString = createFormatString();
StringBuilder causes = new StringBuilder();
StringBuilder message = new StringBuilder(table.getName());
message.append(" failed\n\n");
describeColumns(formatString, message);
int i = 1;
for (RowResult result : results) {
message.append(INDENT);
describeRow(formatString, message, result);
if (result instanceof RowFailed) {
message.append(" (");
message.append(i);
message.append(")");
describeCause(formatString, causes, i, (RowFailed) result);
i++;
}
message.append("\n");
}
message.append(causes);
return message.toString();
}
private String createFormatString() {
StringBuilder formatString = new StringBuilder("|");
List<String> columns = table.getColumnNames();
for(int i = 0; i < columns.size(); i++){
int length = columns.get(i).length();
for (T row : table.getRows()) {
String cell = row.getCells().get(i);
int cellLength = cell == null ? 0 : cell.length();
length = max(length, cellLength);
}
formatString.append(" %" + (i + 1) + "$-" + (length+5) + "s|");
}
return formatString.toString();
}
private void describeColumns(String formatString, StringBuilder message) {
message.append(INDENT);
message.append(format(formatString, table.getColumnNames().toArray()));
message.append("\n");
}
protected void describeRow(String formatString, StringBuilder message, RowResult result) {
List<String> cells = result.getValue().getCells();
message.append(format(formatString, cells.toArray()));
message.append(" ");
message.append(result);
}
protected void describeCause(String formatString, StringBuilder causes, int i, RowFailed result) {
causes.append("\n(");
causes.append(i);
causes.append(") ");
describeRow(formatString, causes, result);
causes.append("\n");
Throwable cause = result.getCause();
causes.append(cause.toString());
}
}