package fitnesse.testsystems.slim.tables;
import static fitnesse.slim.converters.VoidConverter.VOID_TAG;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import fitnesse.slim.instructions.CallAndAssignInstruction;
import fitnesse.slim.instructions.CallInstruction;
import fitnesse.slim.instructions.Instruction;
import fitnesse.slim.instructions.MakeInstruction;
import fitnesse.testsystems.slim.SlimCommandRunningClient;
public class DynamicDecisionTableTest extends SlimTableTestSupport<DynamicDecisionTable> {
private static final String TABLE_INSTANCE_NAME = "dynamicDecisionTable_id";
private final String simpleDynamicDecisionTable =
"|DDT:fixture|argument|\n" +
"|var|func?|\n" +
"|3|5|\n" +
"|7|9|\n";
private final String dynamicDecisionTableWithSameFunctionMultipleTimes= "|DDT:fixture|argument|\n" +
"|func?|func?|\n" +
"|3|5|\n" +
"|7|9|\n";
private DynamicDecisionTable dynamicDecisionTable;
private void makeDynamicDecisionTableAndBuildInstructions(String tableText) throws Exception {
dynamicDecisionTable = makeSlimTableAndBuildInstructions(tableText);
}
@Test(expected=SyntaxError.class)
public void aDecisionTableWithOnlyTwoRowsIsBad() throws Exception {
makeDynamicDecisionTableWithTwoRows();
}
private void assertTableIsBad(DynamicDecisionTable dynamicDecisionTable) {
assertTrue(firstCellOfTable(dynamicDecisionTable).contains("Bad table"));
}
private String firstCellOfTable(DynamicDecisionTable dynamicDecisionTable) {
return dynamicDecisionTable.getTable().getCellContents(0, 0);
}
private void makeDynamicDecisionTableWithTwoRows() throws Exception {
makeDynamicDecisionTableAndBuildInstructions("|DDT:x|\n|y|\n");
}
@Test(expected=SyntaxError.class)
public void wrongNumberOfColumns() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(
"|DDT:fixture|argument|\n" +
"|var|var2|\n" +
"|3|\n" +
"|7|9|\n"
);
assertTableIsBad(dynamicDecisionTable);
}
@Test
public void dynamicDecisionTableCanBeConstructorOnly() throws Exception {
makeDynamicDecisionTableAndBuildInstructions("|fixture|argument|\n");
List<Instruction> expectedInstructions = asList(
new MakeInstruction(id(0), TABLE_INSTANCE_NAME, "fixture", new Object[]{"argument"}),
new CallInstruction(id(1), TABLE_INSTANCE_NAME, "table", new Object[]{asList()})
);
assertEquals(expectedInstructions, instructions);
Map<String, Object> pseudoResults = SlimCommandRunningClient.resultToMap(
asList(
asList(id(0), "OK"),
asList(id(1), "OK")
)
);
SlimAssertion.evaluateExpectations(assertions, pseudoResults);
String colorizedTable = dynamicDecisionTable.getTable().toString();
String expectedColorizedTable =
"[[pass(fixture), argument]]";
assertEquals(expectedColorizedTable, colorizedTable);
}
@Test
public void canBuildInstructionsForSimpleDecisionTable() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(simpleDynamicDecisionTable);
int n = 0;
List<Instruction> expectedInstructions = asList(
new MakeInstruction(id(n++), TABLE_INSTANCE_NAME, "fixture", new Object[]{"argument"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "table", new Object[]{asList(asList("var", "func?"), asList("3", "5"), asList("7", "9"))}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "beginTable"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "3"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "7"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "endTable")
);
assertEquals(expectedInstructions, instructions);
}
@Test
public void canBuildInstructionsForMultipleCallsToSameSetter() throws Exception {
String decisionTableWithSameSetterMultipleTimes = "|DDT:fixture|argument|\n" +
"|var|var|\n" +
"|3|5|\n" +
"|7|9|\n";
makeDynamicDecisionTableAndBuildInstructions(decisionTableWithSameSetterMultipleTimes);
int n = 0;
List<Instruction> expectedInstructions = asList(
new MakeInstruction(id(n++), TABLE_INSTANCE_NAME, "fixture", new Object[]{"argument"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "table", new Object[]{asList(asList("var", "var"), asList("3", "5"), asList("7", "9"))}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "beginTable"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "3"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "5"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "7"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "9"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "endTable")
);
assertEquals(expectedInstructions, instructions);
}
@Test
public void canBuildInstructionsForMultipleCallsToSameFunction() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(dynamicDecisionTableWithSameFunctionMultipleTimes);
int n = 0;
List<Instruction> expectedInstructions = asList(
new MakeInstruction(id(n++), TABLE_INSTANCE_NAME, "fixture", new Object[]{"argument"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "table", new Object[]{asList(asList("func?", "func?"), asList("3", "5"), asList("7", "9"))}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "beginTable"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "endTable")
);
assertEquals(expectedInstructions, instructions);
}
private String id(int n) {
return TABLE_INSTANCE_NAME + "_" + n;
}
@Test
public void canUseBangToCallFunction() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(
"|DDT:fixture|argument|\n" +
"|var|func!|\n" +
"|3|5|\n" +
"|7|9|\n");
int n=0;
List<Instruction> expectedInstructions = asList(
new MakeInstruction(id(n++), TABLE_INSTANCE_NAME, "fixture", new Object[]{"argument"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "table", new Object[]{asList(asList("var", "func!"), asList("3", "5"), asList("7", "9"))}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "beginTable"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "3"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "7"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "endTable")
);
assertEquals(expectedInstructions, instructions);
}
@SuppressWarnings("unchecked")
@Test
public void settersAreFirstFunctionsAreLastLeftToRight() throws Exception {
makeDynamicDecisionTableAndBuildInstructions("|DDT:fixture|\n" +
"|a|fa?|b|fb?|c|fc?|d|e|f|fd?|fe?|ff?|\n" +
"|a|a|b|b|c|c|d|e|f|d|e|f|\n");
int n = 0;
List<Instruction> expectedInstructions = asList(
new MakeInstruction(id(n++), TABLE_INSTANCE_NAME, "fixture"),
new CallInstruction(id(n++),TABLE_INSTANCE_NAME, "table", new Object[] {asList(
asList("a", "fa?", "b", "fb?", "c", "fc?", "d", "e", "f", "fd?", "fe?", "ff?"),
asList("a", "a", "b", "b", "c", "c", "d", "e", "f", "d", "e", "f"))}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "beginTable"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"a", "a"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"b", "b"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"c", "c"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"d", "d"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"e", "e"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"f", "f"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"fa"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"fb"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"fc"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"fd"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"fe"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"ff"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "endTable")
);
assertEquals(expectedInstructions, instructions);
}
@Test
public void canBuildInstructionsForTableWithVariables() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(
"|DDT:fixture|\n" +
"|var|func?|\n" +
"|3|$V=|\n" +
"|$V|9|\n"
);
int n=0;
List<Instruction> expectedInstructions = asList(
new MakeInstruction(id(n++), TABLE_INSTANCE_NAME, "fixture"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "table", new Object[]{asList(asList("var", "func?"), asList("3", "$V="), asList("$V", "9"))}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "beginTable"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "3"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallAndAssignInstruction(id(n++), "V", TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "reset"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "set", new Object[]{"var", "$V"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "execute"),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "get", new Object[]{"func"}),
new CallInstruction(id(n++), TABLE_INSTANCE_NAME, "endTable")
);
assertEquals(expectedInstructions.toString(), instructions.toString());
}
@Test
public void canEvaluateReturnValuesAndColorizeTable() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(simpleDynamicDecisionTable);
Map<String, Object> pseudoResults = makePseudoResultsForSimpleTable();
SlimAssertion.evaluateExpectations(assertions, pseudoResults);
String colorizedTable = dynamicDecisionTable.getTable().toString();
String expectedColorizedTable =
"[" +
"[pass(DDT:fixture), argument], " +
"[var, func?], " +
"[3, pass(5)], " +
"[7, fail(a=5;e=9)]" +
"]";
assertEquals(expectedColorizedTable, colorizedTable);
}
@Test
public void translatesTestTablesIntoLiteralTables() throws Exception {
makeDynamicDecisionTableAndBuildInstructions("!" + simpleDynamicDecisionTable);
Map<String, Object> pseudoResults = makePseudoResultsForSimpleTable();
SlimAssertion.evaluateExpectations(assertions, pseudoResults);
String colorizedTable = dynamicDecisionTable.getTable().toString();
String expectedColorizedTable =
"[" +
"[pass(DDT:fixture), argument], " +
"[var, func?], " +
"[3, pass(5)], " +
"[7, fail(a=5;e=9)]" +
"]";
assertEquals(expectedColorizedTable, colorizedTable);
}
@Test
public void commentColumn() throws Exception {
String decisionTableWithComment =
"|DDT:fixture|argument||\n" +
"|var|func?|#comment|\n" +
"|3|5|comment|\n" +
"|7|9||\n";
makeDynamicDecisionTableAndBuildInstructions(decisionTableWithComment);
Map<String, Object> pseudoResults = makePseudoResultsForSimpleTable();
SlimAssertion.evaluateExpectations(assertions, pseudoResults);
String colorizedTable = dynamicDecisionTable.getTable().toString();
String expectedColorizedTable =
"[" +
"[pass(DDT:fixture), argument, ], " +
"[var, func?, #comment], " +
"[3, pass(5), comment], " +
"[7, fail(a=5;e=9), ]" +
"]";
assertEquals(expectedColorizedTable, colorizedTable);
}
private Map<String, Object> makePseudoResultsForSimpleTable() {
int n = 0;
return SlimCommandRunningClient.resultToMap(
asList(
asList(id(n++), "OK"),
asList(id(n++), VOID_TAG),
asList(id(n++), VOID_TAG), //beginTable
asList(id(n++), VOID_TAG), //reset
asList(id(n++), VOID_TAG), //set
asList(id(n++), VOID_TAG), //execute
asList(id(n++), "5"),
asList(id(n++), VOID_TAG),
asList(id(n++), VOID_TAG),
asList(id(n++), VOID_TAG),
asList(id(n++), "5"),
asList(id(n++), VOID_TAG) //endTable
)
);
}
@Test
public void canEvaluateReturnValuesAndColorizeTableForMultipleCallsToSameFunction() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(dynamicDecisionTableWithSameFunctionMultipleTimes);
int n = 0;
Map<String, Object> pseudoResults = SlimCommandRunningClient.resultToMap(
asList(
asList(id(n++), "OK"),
asList(id(n++), VOID_TAG),
asList(id(n++), VOID_TAG), // beginTable
asList(id(n++), VOID_TAG), //reset
asList(id(n++), VOID_TAG), //execute
asList(id(n++), "4"),
asList(id(n++), "5"),
asList(id(n++), VOID_TAG),
asList(id(n++), VOID_TAG),
asList(id(n++), "7"),
asList(id(n++), "5"),
asList(id(n++), VOID_TAG) //endTable
)
);
SlimAssertion.evaluateExpectations(assertions, pseudoResults);
String colorizedTable = dynamicDecisionTable.getTable().toString();
String expectedColorizedTable =
"[" +
"[pass(DDT:fixture), argument], " +
"[func?, func?], " +
"[fail(a=4;e=3), pass(5)], " +
"[pass(7), fail(a=5;e=9)]" +
"]";
assertEquals(expectedColorizedTable, colorizedTable);
}
@Test
public void usesDisgracedClassNames() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(
"|DDT:slim test|\n" +
"|x|\n" +
"|y|\n"
);
Instruction makeInstruction = new MakeInstruction(id(0), TABLE_INSTANCE_NAME, "SlimTest");
assertEquals(makeInstruction, instructions.get(0));
}
@Test
public void doesNotDisgraceColumnHeadersSinceTheyAreValues() throws Exception {
makeDynamicDecisionTableAndBuildInstructions(
"|DDT:fixture|\n" +
"|my var|my func?|\n" +
"|8|7|\n"
);
CallInstruction setInstruction = new CallInstruction(id(4), TABLE_INSTANCE_NAME, "set", new Object[]{"my var", "8"});
CallInstruction callInstruction = new CallInstruction(id(6), TABLE_INSTANCE_NAME, "get", new Object[]{"my func"});
assertEquals(setInstruction, instructions.get(4));
assertEquals(callInstruction, instructions.get(6));
}
}