package fitnesse.slimTables; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.junit.Before; import org.junit.Test; import fitnesse.responders.run.slimResponder.MockSlimTestContext; import fitnesse.responders.run.slimResponder.SlimTestContext; import fitnesse.slim.SlimClient; import fitnesse.slim.converters.VoidConverter; import fitnesse.wiki.InMemoryPage; import fitnesse.wiki.WikiPage; import fitnesse.wiki.WikiPageUtil; import fitnesse.wikitext.Utils; import static util.ListUtility.*; public abstract class QueryTableBaseTest { private WikiPage root; private List<Object> instructions; private String queryTableHeader; public QueryTable qt; private MockSlimTestContext testContext; protected String headRow; @Before public void setUp() throws Exception { root = InMemoryPage.makeRoot("root"); instructions = new ArrayList<Object>(); queryTableHeader = "|" + tableType() + ":fixture|argument|\n" + "|n|2n|\n"; headRow = "[pass(" + tableType() + ":fixture), argument], "; } protected abstract String tableType(); protected abstract Class<? extends QueryTable> queryTableClass(); private QueryTable makeQueryTableAndBuildInstructions(String pageContents) throws Exception { qt = makeQueryTable(pageContents); qt.appendInstructions(instructions); return qt; } private QueryTable makeQueryTable(String tableText) throws Exception { WikiPageUtil.setPageContents(root, tableText); TableScanner ts = new HtmlTableScanner(root.getData().getHtml()); Table t = ts.getTable(0); testContext = new MockSlimTestContext(); return constructQueryTable(t); } private QueryTable constructQueryTable(Table t) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Class<? extends QueryTable> queryTableClass = queryTableClass(); Constructor<? extends QueryTable> constructor = queryTableClass.getConstructor(Table.class, String.class, SlimTestContext.class); return constructor.newInstance(t, "id", testContext); } protected void assertQueryResults(String queryRows, List<Object> queryResults, String table) throws Exception { makeQueryTableAndBuildInstructions(queryTableHeader + queryRows); Map<String, Object> pseudoResults = SlimClient.resultToMap(list( list("queryTable_id_0", "OK"), list("queryTable_id_1", "blah"), list("queryTable_id_2", queryResults) ) ); testContext.evaluateExpectations(pseudoResults); qt.evaluateReturnValues(pseudoResults); org.junit.Assert.assertEquals(table, qt.getTable().toString()); } @Test public void instructionsForQueryTable() throws Exception { makeQueryTableAndBuildInstructions(queryTableHeader); List<Object> expectedInstructions = list( list("queryTable_id_0", "make", "queryTable_id", "fixture", "argument"), list("queryTable_id_1", "call", "queryTable_id", "table", list(list("n", "2n"))), list("queryTable_id_2", "call", "queryTable_id", "query") ); org.junit.Assert.assertEquals(expectedInstructions, instructions); } @Test public void nullResultsForNullTable() throws Exception { assertQueryResults("", list(), "[" + headRow + "[n, 2n]" + "]" ); } @Test public void oneRowThatMatches() throws Exception { assertQueryResults("|2|4|\n", list( list(list("n", "2"), list("2n", "4")) ), "[" + headRow + "[n, 2n], " + "[pass(2), pass(4)]" + "]" ); } @Test public void oneRowFirstCellMatchesSecondCellBlank() throws Exception { assertQueryResults("|2||\n", list( list(list("n", "2"), list("2n", "4")) ), "[" + headRow + "[n, 2n], " + "[pass(2), ignore(4)]" + "]" ); } @Test public void oneRowThatFails() throws Exception { assertQueryResults("|2|4|\n", list( list(list("n", "3"), list("2n", "5")) ), "[" + headRow + "[n, 2n], " + "[[2] fail(missing), 4], " + "[[3] fail(surplus), 5]" + "]" ); } @Test public void oneRowWithPartialMatch() throws Exception { assertQueryResults("|2|4|\n", list( list(list("n", "2"), list("2n", "5")) ), "[" + headRow + "[n, 2n], " + "[pass(2), [5] fail(expected [4])]" + "]" ); } @Test public void twoMatchingRows() throws Exception { assertQueryResults( "|2|4|\n" + "|3|6|\n", list( list(list("n", "2"), list("2n", "4")), list(list("n", "3"), list("2n", "6")) ), "[" + headRow + "[n, 2n], " + "[pass(2), pass(4)], " + "[pass(3), pass(6)]" + "]" ); } @Test public void twoRowsFirstMatchesSecondDoesnt() throws Exception { assertQueryResults( "|3|6|\n" + "|99|99|\n", list( list(list("n", "2"), list("2n", "4")), list(list("n", "3"), list("2n", "6")) ), "[" + headRow + "[n, 2n], " + "[pass(3), pass(6)], " + "[[99] fail(missing), 99], " + "[[2] fail(surplus), 4]" + "]" ); } @Test public void twoRowsSecondMatchesFirstDoesnt() throws Exception { assertQueryResults( "|99|99|\n" + "|2|4|\n", list( list(list("n", "2"), list("2n", "4")), list(list("n", "3"), list("2n", "6")) ), "[" + headRow + "[n, 2n], " + "[[99] fail(missing), 99], " + "[pass(2), pass(4)], " + "[[3] fail(surplus), 6]" + "]" ); } @Test public void fieldInMatchingRowDoesntExist() throws Exception { assertQueryResults( "|3|4|\n", list( list(list("n", "3")) ), "[" + headRow + "[n, 2n], " + "[pass(3), [4] fail(field 2n not present)]" + "]" ); } @Test public void fieldInSurplusRowDoesntExist() throws Exception { assertQueryResults( "", list( list(list("n", "3")) ), "[" + headRow + "[n, 2n], " + "[[3] fail(surplus), fail(field 2n not present)]" + "]" ); } @Test public void variablesAreReplacedInMatch() throws Exception { makeQueryTableAndBuildInstructions(queryTableHeader + "|2|$V|\n"); qt.setSymbol("V", "4"); Map<String, Object> pseudoResults = SlimClient.resultToMap( list( list("queryTable_id_0", "OK"), list("queryTable_id_1", VoidConverter.VOID_TAG), list("queryTable_id_2", list( list(list("n", "2"), list("2n", "4")) ) ) ) ); testContext.evaluateExpectations(pseudoResults); qt.evaluateReturnValues(pseudoResults); org.junit.Assert.assertEquals( "[" + headRow + "[n, 2n], " + "[pass(2), pass($V->[4])]" + "]", Utils.unescapeWiki(qt.getTable().toString()) ); } @Test public void variablesAreReplacedInExpected() throws Exception { makeQueryTableAndBuildInstructions(queryTableHeader + "|2|$V|\n"); qt.setSymbol("V", "5"); Map<String, Object> pseudoResults = SlimClient.resultToMap( list( list("queryTable_id_0", "OK"), list("queryTable_id_1", VoidConverter.VOID_TAG), list("queryTable_id_2", list( list(list("n", "2"), list("2n", "4")) ) ) ) ); testContext.evaluateExpectations(pseudoResults); qt.evaluateReturnValues(pseudoResults); org.junit.Assert.assertEquals( "[" + headRow + "[n, 2n], " + "[pass(2), [4] fail(expected [$V->[5]])]" + "]", Utils.unescapeWiki(qt.getTable().toString()) ); } @Test public void variablesAreReplacedInMissing() throws Exception { makeQueryTableAndBuildInstructions(queryTableHeader + "|3|$V|\n"); qt.setSymbol("V", "5"); Map<String, Object> pseudoResults = SlimClient.resultToMap( list( list("queryTable_id_0", "OK"), list("queryTable_id_1", VoidConverter.VOID_TAG), list("queryTable_id_2", list( ) ) ) ); testContext.evaluateExpectations(pseudoResults); qt.evaluateReturnValues(pseudoResults); org.junit.Assert.assertEquals( "[" + headRow + "[n, 2n], " + "[[3] fail(missing), $V->[5]]" + "]", qt.getTable().toString() ); } @Test public void oneRowThatMatchesExpression() throws Exception { assertQueryResults("|<5|4|\n", list( list(list("n", "2"), list("2n", "4")) ), "[" + headRow + "[n, 2n], " + "[pass(2<5), pass(4)]" + "]" ); } }