
fitnesse.testsystems.slim.tables.ScriptTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fitnesse Show documentation
Show all versions of fitnesse Show documentation
The fully integrated standalone wiki, and acceptance testing framework.
The newest version!
// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.testsystems.slim.tables;
import fitnesse.slim.converters.BooleanConverter;
import fitnesse.slim.converters.VoidConverter;
import fitnesse.slim.instructions.Instruction;
import fitnesse.testsystems.TestExecutionException;
import fitnesse.testsystems.TestResult;
import fitnesse.testsystems.slim.SlimTestContext;
import fitnesse.testsystems.slim.Table;
import fitnesse.testsystems.slim.results.SlimTestResult;
import fitnesse.util.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ScriptTable extends SlimTable {
public ScriptTable(Table table, String tableId, SlimTestContext context) {
super(table, tableId, context);
}
/**
* Template method to provide the keyword that identifies the table type.
*
* @return table type
*/
@Override
protected String getTableType() {
return "scriptTable";
}
/**
* Template method to provide the keyword that identifies the table type.
*
* @return keyword for script table
*/
protected String getTableKeyword() {
return "script";
}
/**
* Template method to provide the keyword for the {@code start} action.
*
* @return keyword for {@code start} action
*/
protected String getStartKeyword() {
return "start";
}
/**
* Template method to provide the keyword for the {@code check} action.
*
* @return keyword for {@code check} action
*/
protected String getCheckKeyword() {
return "check";
}
/**
* Template method to provide the keyword for the {@code checkNot} action.
*
* @return keyword for {@code checkNot} action
*/
protected String getCheckNotKeyword() {
return "check not";
}
/**
* Template method to provide the keyword for the {@code reject} action.
*
* @return keyword for {@code reject} action
*/
protected String getRejectKeyword() {
return "reject";
}
/**
* Template method to provide the keyword for the {@code ensure} action.
*
* @return keyword for {@code ensure} action
*/
protected String getEnsureKeyword() {
return "ensure";
}
/**
* Template method to provide the keyword for the {@code show} action.
*
* @return keyword for {@code show} action
*/
protected String getShowKeyword() {
return "show";
}
/**
* Template method to provide the keyword for the {@code note} action.
*
* @return keyword for {@code note} action
*/
protected String getNoteKeyword() {
return "note";
}
@Override
public List getAssertions() throws TestExecutionException {
List assertions = new ArrayList<>();
// TODO: Should take into account here that a table can be assigned as
if (isTopLevelTable()) {
getTestContext().setCurrentScriptClass(getClass());
List createAssertions = startActor();
if (createAssertions != null) {
assertions.addAll(createAssertions);
}
}
for (int row = 1; row < table.getRowCount(); row++)
assertions.addAll(instructionsForRow(row));
return assertions;
}
private boolean isTopLevelTable() {
return getParent() == null;
}
// returns a list of statements
protected List instructionsForRow(int row) throws TestExecutionException {
String firstCell = table.getCellContents(0, row).trim();
List assertions;
String match;
if (firstCell.equalsIgnoreCase(getStartKeyword()))
assertions = startActor(row);
else if (firstCell.equalsIgnoreCase(getCheckKeyword()))
assertions = checkAction(row);
else if (firstCell.equalsIgnoreCase(getCheckNotKeyword()))
assertions = checkNotAction(row);
else if (firstCell.equalsIgnoreCase(getRejectKeyword()))
assertions = reject(row);
else if (firstCell.equalsIgnoreCase(getEnsureKeyword()))
assertions = ensure(row);
else if (firstCell.equalsIgnoreCase(getShowKeyword()))
assertions = show(row);
else if (firstCell.equalsIgnoreCase(getNoteKeyword()))
assertions = note(row);
else if ((match = isSymbolAssignment(0, row)) != null)
assertions = actionAndAssign(match, row);
else if (firstCell.isEmpty())
assertions = note(row);
else if (firstCell.trim().startsWith("#") || firstCell.trim().startsWith("*"))
assertions = note(row);
else {
// action() is for now the only function that returns a list of statements
assertions = action(row);
}
return assertions;
}
protected List actionAndAssign(String symbolName, int row) throws SyntaxError {
List assertions = new ArrayList<>();
int lastCol = table.getColumnCountInRow(row) - 1;
String actionName = getActionNameStartingAt(1, lastCol, row);
if (!actionName.equals("")) {
String[] args = getArgumentsStartingAt(1 + 1, lastCol, row, assertions);
assertions.add(makeAssertion(callAndAssign(symbolName, getTableType() + "Actor", actionName, (Object[]) args),
new SymbolAssignmentExpectation(symbolName, 0, row)));
}
return assertions;
}
protected List action(int row) throws TestExecutionException {
List assertions = assertionsFromScenario(row);
if (assertions.isEmpty()) {
// Invoke fixture:
int lastCol = table.getColumnCountInRow(row) - 1;
return invokeAction(0, lastCol, row, new ScriptActionExpectation(0, row));
}
return assertions;
}
protected List assertionsFromScenario(int row) throws TestExecutionException {
int lastCol = table.getColumnCountInRow(row) - 1;
String scenarioName = getScenarioNameFromAlternatingCells(lastCol, row);
ScenarioTable scenario = getTestContext().getScenario(scenarioName);
String[] args = null;
List assertions = new ArrayList<>();
if (scenario != null) {
args = getArgumentsStartingAt(1, lastCol, row, assertions);
} else if (lastCol == 0) {
String cellContents = table.getCellContents(0, row);
scenario = getTestContext().getScenarioByPattern(cellContents);
if (scenario != null) {
args = scenario.matchParameters(cellContents);
}
}
if (scenario != null) {
scenario.setCustomComparatorRegistry(customComparatorRegistry);
assertions.addAll(scenario.call(args, this, row));
}
return assertions;
}
protected String getScenarioNameFromAlternatingCells(int endingCol, int row) throws SyntaxError {
return RowHelper.getScenarioNameFromAlternatingCells(table, endingCol, row);
}
protected List note(int row) {
return Collections.emptyList();
}
protected List show(int row) throws SyntaxError {
int lastCol = table.getColumnCountInRow(row) - 1;
return invokeAction(1, lastCol, row,
new ShowActionExpectation(0, row));
}
protected List ensure(int row) throws SyntaxError {
int lastCol = table.getColumnCountInRow(row) - 1;
return invokeAction(1, lastCol, row,
new EnsureActionExpectation(0, row));
}
protected List reject(int row) throws SyntaxError {
int lastCol = table.getColumnCountInRow(row) - 1;
return invokeAction(1, lastCol, row,
new RejectActionExpectation(0, row));
}
protected List checkAction(int row) throws SyntaxError {
int lastColInAction = table.getColumnCountInRow(row) - 1;
table.getCellContents(lastColInAction, row);
return invokeAction(1, lastColInAction - 1, row,
new ReturnedValueExpectation(lastColInAction, row));
}
protected List checkNotAction(int row) throws SyntaxError {
int lastColInAction = table.getColumnCountInRow(row) - 1;
table.getCellContents(lastColInAction, row);
return invokeAction(1, lastColInAction - 1, row,
new RejectedValueExpectation(lastColInAction, row));
}
protected List invokeAction(int startingCol, int endingCol, int row, SlimExpectation expectation) throws SyntaxError {
String actionName = getActionNameStartingAt(startingCol, endingCol, row);
List assertions = new ArrayList<>();
String[] args = getArgumentsStartingAt(startingCol + 1, endingCol, row, assertions);
assertions.add(makeAssertion(callFunction(getTableType() + "Actor", actionName, (Object[]) args),
expectation));
return assertions;
}
protected String getActionNameStartingAt(int startingCol, int endingCol, int row) throws SyntaxError {
return RowHelper.getActionNameStartingAt(table, startingCol, endingCol, row);
}
// Adds extra assertions to the "assertions" list!
protected String[] getArgumentsStartingAt(int startingCol, int endingCol, int row, List assertions) {
ArgumentExtractor extractor = new ArgumentExtractor(startingCol, endingCol, row);
while (extractor.hasMoreToExtract()) {
assertions.add(makeAssertion(Instruction.NOOP_INSTRUCTION,
new ArgumentExpectation(extractor.argumentColumn, row)));
extractor.extractNextArgument();
}
return extractor.getArguments();
}
protected boolean invokesSequentialArgumentProcessing(String cellContents) {
return RowHelper.invokesSequentialArgumentProcessing(cellContents);
}
protected List startActor() {
if (!StringUtils.isBlank(getFixtureName())) {
return startActor(0, getFixtureName(), 0);
} else if (table.getColumnCountInRow(0) > 1) {
return startActor(0);
}
return null;
}
protected List startActor(int row) {
int classNameColumn = 1;
String cellContents = table.getCellContents(classNameColumn, row);
return startActor(row, cellContents, classNameColumn);
}
protected List startActor(int row, String cellContents, int classNameColumn) {
List assertions = new ArrayList<>();
String className = Disgracer.disgraceClassName(cellContents);
String actorName = getTableType() + "Actor";
getTestContext().setCurrentScriptActor(actorName);
assertions.add(constructInstance(actorName, className, classNameColumn, row));
getArgumentsStartingAt(classNameColumn + 1, table.getColumnCountInRow(row) - 1, row, assertions);
return assertions;
}
public static class RowHelper {
private static final String SEQUENTIAL_ARGUMENT_PROCESSING_SUFFIX = ";";
public static String getScenarioNameFromAlternatingCells(Table table, int endingCol, int row) throws SyntaxError {
String actionName = getActionNameStartingAt(table, 0, endingCol, row);
String simpleName = StringUtils.replace(actionName, SEQUENTIAL_ARGUMENT_PROCESSING_SUFFIX, "");
return Disgracer.disgraceClassName(simpleName);
}
public static String getActionNameStartingAt(Table table, int startingCol, int endingCol, int row) throws SyntaxError {
StringBuilder actionName = new StringBuilder();
try {
actionName.append(table.getCellContents(startingCol, row));
} catch (IndexOutOfBoundsException e) {
throw new SyntaxError("Too few columns in row " + (row + 1) + ". Expected a function in column " + (startingCol + 1) + ".");
}
int actionNameCol = startingCol + 2;
while (actionNameCol <= endingCol &&
!invokesSequentialArgumentProcessing(actionName.toString())) {
actionName.append(" ").append(table.getCellContents(actionNameCol, row));
actionNameCol += 2;
}
return actionName.toString().trim();
}
public static boolean invokesSequentialArgumentProcessing(String cellContents) {
return cellContents.endsWith(SEQUENTIAL_ARGUMENT_PROCESSING_SUFFIX);
}
}
class ArgumentExtractor {
private int argumentColumn;
private int endingCol;
private int row;
private List arguments = new ArrayList<>();
private int increment = 2;
private boolean sequentialArguments = false;
ArgumentExtractor(int startingCol, int endingCol, int row) {
this.argumentColumn = startingCol;
this.endingCol = endingCol;
this.row = row;
}
public boolean hasMoreToExtract() {
return argumentColumn <= endingCol;
}
public void extractNextArgument() {
arguments.add(table.getCellContents(argumentColumn, row));
String argumentKeyword = table.getCellContents(argumentColumn - 1, row);
boolean argumentIsSequential = invokesSequentialArgumentProcessing(argumentKeyword);
sequentialArguments = (sequentialArguments || argumentIsSequential);
increment = sequentialArguments ? 1 : 2;
argumentColumn += increment;
}
public String[] getArguments() {
return arguments.toArray(new String[arguments.size()]);
}
}
private class ScriptActionExpectation extends RowExpectation {
private ScriptActionExpectation(int col, int row) {
super(col, row);
}
@Override
protected SlimTestResult createEvaluationMessage(String actual, String expected) {
if (actual == null)
return SlimTestResult.fail("null", expected);
else if (actual.equals(VoidConverter.VOID_TAG) || actual.equals("null"))
return SlimTestResult.plain();
else if (actual.equals(BooleanConverter.FALSE))
return SlimTestResult.fail();
else if (actual.equals(BooleanConverter.TRUE))
return SlimTestResult.pass();
else if (actual.equals("IGNORE_SCRIPT_TEST"))
return SlimTestResult.countTestNotRun();
else
return SlimTestResult.plain();
}
}
private class EnsureActionExpectation extends RowExpectation {
public EnsureActionExpectation(int col, int row) {
super(col, row);
}
@Override
protected SlimTestResult createEvaluationMessage(String actual, String expected) {
return (actual != null && actual.equals(BooleanConverter.TRUE)) ?
SlimTestResult.pass() : SlimTestResult.fail();
}
}
private class RejectActionExpectation extends RowExpectation {
public RejectActionExpectation(int col, int row) {
super(col, row);
}
@Override
protected SlimTestResult createEvaluationMessage(String actual, String expected) {
if (actual == null)
return SlimTestResult.pass();
else
return actual.equals(BooleanConverter.FALSE) ? SlimTestResult.pass() : SlimTestResult.fail();
}
}
private class ShowActionExpectation extends RowExpectation {
public ShowActionExpectation(int col, int row) {
super(col, row);
}
@Override
protected SlimTestResult createEvaluationMessage(String actual, String expected) {
try {
table.addColumnToRow(getRow(), actual);
} catch (Exception e) {
return SlimTestResult.fail(actual, e.getMessage());
}
return SlimTestResult.plain();
}
}
private class ArgumentExpectation extends RowExpectation {
private ArgumentExpectation(int col, int row) {
super(col, row);
}
@Override
public TestResult evaluateExpectation(Object returnValue) {
table.substitute(getCol(), getRow(), replaceSymbolsWithFullExpansion(getExpected()));
return null;
}
@Override
protected SlimTestResult createEvaluationMessage(String actual, String expected) {
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy