// 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.responders.run;
import java.io.File;
import java.io.FileInputStream;
import fitnesse.FitNesseContext;
import fitnesse.http.MockRequest;
import fitnesse.http.MockResponseSender;
import fitnesse.http.Response;
import fitnesse.reporting.BaseFormatter;
import fitnesse.responders.run.TestResponderTest.JunitTestUtilities;
import fitnesse.responders.run.TestResponderTest.XmlTestUtilities;
import fitnesse.testsystems.TestSummary;
import fitnesse.testutil.FitNesseUtil;
import fitnesse.util.Clock;
import fitnesse.util.DateAlteringClock;
import fitnesse.util.DateTimeUtil;
import fitnesse.util.XmlUtil;
import fitnesse.wiki.PageData;
import fitnesse.wiki.PathParser;
import fitnesse.wiki.WikiPage;
import fitnesse.wiki.WikiPageUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import static org.junit.Assert.*;
import static util.RegexTestCase.*;
public class SuiteResponderTest {
private static final String TEST_TIME = "12/5/2008 01:19:00";
private MockRequest request;
private SuiteResponder responder;
private WikiPage root;
private WikiPage suite;
private FitNesseContext context;
private final String fitPassFixture = "|!-fitnesse.testutil.PassFixture-!|\n";
private final String fitFailFixture = "|!-fitnesse.testutil.FailFixture-!|\n";
private final String simpleSlimDecisionTable = "!define TEST_SYSTEM {slim}\n" +
"|!-DT:fitnesse.slim.test.TestSlim-!|\n" +
"|string|get string arg?|\n" +
"|wow|wow|\n";
@Before
public void setUp() throws Exception {
String suitePageName = "SuitePage";
context = FitNesseUtil.makeTestContext();
root = context.getRootPage();
PageData data = root.getData();
data.setContent(classpathWidgets());
root.commit(data);
suite = WikiPageUtil.addPage(root, PathParser.parse(suitePageName), "This is the test suite\n");
addTestToSuite("TestOne", fitPassFixture);
request = new MockRequest();
request.setResource(suitePageName);
request.addInput("debug", "");
responder = new SuiteResponder();
responder.page = suite;
new DateAlteringClock(DateTimeUtil.getDateFromString(TEST_TIME)).freeze();
}
@After
public void restoreDefaultClock() {
Clock.restoreDefaultClock();
}
private WikiPage addTestToSuite(String name, String content) {
return addTestPage(suite, name, content);
}
private WikiPage addTestPage(WikiPage page, String name, String content) {
WikiPage testPage = WikiPageUtil.addPage(page, PathParser.parse(name), content);
PageData data = testPage.getData();
data.setAttribute("Test");
testPage.commit(data);
return testPage;
}
@After
public void tearDown() throws Exception {
FitNesseUtil.destroyTestContext();
}
private String runSuite() throws Exception {
Response response = responder.makeResponse(context, request);
MockResponseSender sender = new MockResponseSender();
sender.doSending(response);
String results = sender.sentData();
return results;
}
@Test
public void testWithOneTest() throws Exception {
String results = runSuite();
assertSubString("href=\\\"#TestOne1\\\"", results);
assertSubString("1 right", results);
assertSubString("name=\"TestOne1\"", results);
assertSubString(" href=\"SuitePage.TestOne\"", results);
assertSubString("PassFixture", results);
}
@Test
public void testPageWithXref() throws Exception {
PageData data = suite.getData();
data.setContent("!see XrefOne\r\n!see XrefTwo\n!see XrefThree\n");
suite.commit(data);
addTestPage(root, "XrefOne", fitPassFixture);
addTestPage(root, "XrefTwo", fitPassFixture);
String results = runSuite();
assertSubString("href=\\\"#XrefOne2\\\"", results);
assertSubString("href=\\\"#XrefTwo3\\\"", results);
}
@Test
public void testWithTwoTests() throws Exception {
addTestToSuite("TestTwo", "|!-fitnesse.testutil.FailFixture-!|\n\n|!-fitnesse.testutil.FailFixture-!|\n");
String results = runSuite();
assertSubString("href=\\\"#TestOne1\\\"", results);
assertSubString("href=\\\"#TestTwo2\\\"", results);
assertSubString("1 right", results);
assertSubString("2 wrong", results);
assertSubString("name=\"TestOne1\"", results);
assertSubString("name=\"TestTwo2\"", results);
assertSubString("PassFixture", results);
assertSubString("FailFixture", results);
}
@Test
public void testWithPrunedPage() throws Exception {
WikiPage pageTwo = addTestToSuite("TestTwo",
"|!-fitnesse.testutil.FailFixture-!|\n\n|!-fitnesse.testutil.FailFixture-!|\n"
);
PageData data = pageTwo.getData();
data.setAttribute("Prune");
pageTwo.commit(data);
String results = runSuite();
assertSubString("href=\\\"#TestOne1\\\"", results);
assertNotSubString("href=\\\"#TestTwo2\\\"", results);
assertSubString("1 right", results);
assertSubString("0 wrong", results);
assertSubString("name=\"TestOne1\"", results);
assertNotSubString("id=\"TestTwo2\"", results);
assertSubString("PassFixture", results);
assertNotSubString("FailFixture", results);
}
@Test
public void testSuiteWithOneTestWithoutTable() throws Exception {
addTestToSuite("TestWithoutTable", "This test has not table");
addTestToSuite("TestTwo", fitPassFixture);
addTestToSuite("TestThree", fitPassFixture);
String results = runSuite();
assertSubString("TestOne", results);
assertSubString("TestTwo", results);
assertSubString("TestThree", results);
assertSubString("TestWithoutTable", results);
}
@Test
public void testExitCodeHeader() throws Exception {
String results = runSuite();
assertSubString("Exit-Code: 0", results);
}
@Test
public void exitCodeHeaderIsErrorCount() throws Exception {
addTestToSuite("TestFailingTest", fitFailFixture);
String results = runSuite();
assertSubString("Exit-Code: 1", results);
}
@Test
public void testNoExitCodeHeaderIfNotChunked() throws Exception {
responder.turnOffChunking();
String results = runSuite();
assertFalse(results.contains("Exit-Code: 0"));
}
@Test
public void testExecutionLogLinkAppears() throws Exception {
String results = runSuite();
// Lots of escaping: the content is escaped, since it's written from Javascript.
// Everything needs to be double escaped because it's handled as a regexp.
assertHasRegexp("class=\\\\\"ok\\\\\">Execution Log", results);
}
@Test
public void testTestSummaryInformationIncludesPageSummary() throws Exception {
String results = runSuite();
assertHasRegexp(".*?Test Pages:.*? .*?Assertions:.*?", results);
}
@Test
public void testFormatTestSummaryInformation() throws Exception {
String results = runSuite();
assertHasRegexp(".*?<strong>Test Pages:</strong>.*?<strong>Assertions:</strong>.*?", results);
}
private String classpathWidgets() {
return "!path classes\n" +
"!path lib/dummy.jar\n";
}
@Test
public void testNonMatchingSuiteFilter() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("suiteFilter=xxx");
String results = runSuite();
assertDoesntHaveRegexp(".*href=\\\"#TestOne\\\".*", results);
assertDoesntHaveRegexp(".*href=\\\"#TestTwo\\\".*", results);
assertDoesntHaveRegexp(".*href=\\\"#TestThree\\\".*", results);
}
@Test
public void testSimpleMatchingSuiteQuery() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("suiteFilter=foo");
String results = runSuite();
assertDoesntHaveRegexp(".*href=\\\"#TestOne.*", results);
assertSubString("href=\\\"#TestTwo1\\\"", results);
assertDoesntHaveRegexp(".*href=\\\"#TestThree.*", results);
}
@Test
public void testEmptySuiteFilter() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("suiteFilter=");
String results = runSuite();
assertSubString("href=\\\"#TestTwo3\\\"", results);
assertSubString("href=\\\"#TestThree2\\\"", results);
}
@Test
public void testSecondMatchingSuiteQuery() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("suiteFilter=smoke");
String results = runSuite();
assertDoesntHaveRegexp(".*href=\\\"#TestOne.*", results);
assertDoesntHaveRegexp(".*href=\\\"#TestTwo.*", results);
assertSubString("href=\\\"#TestThree1\\\"", results);
}
@Test
public void multipleSuiteQuery() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("suiteFilter=smoke,foo");
String results = runSuite();
assertDoesntHaveRegexp("#TestOne", results);
assertHasRegexp("#TestTwo", results);
assertHasRegexp("#TestThree", results);
}
@Test
public void excludeSuiteQuery() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("excludeSuiteFilter=foo");
String results = runSuite();
assertHasRegexp("#TestOne", results);
assertDoesntHaveRegexp("#TestTwo", results);
assertHasRegexp("#TestThree", results);
}
@Test
public void excludeSuiteWithSuiteFilterQuery() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("excludeSuiteFilter=bar&suiteFilter=smoke,foo");
String results = runSuite();
assertDoesntHaveRegexp("#TestOne", results);
assertHasRegexp("#TestTwo", results);
assertDoesntHaveRegexp("#TestThree", results);
}
@Test
public void testFirstTest() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("firstTest=TestThree");
String results = runSuite();
assertDoesntHaveRegexp("#TestOne", results);
assertHasRegexp("#TestTwo", results);
assertHasRegexp("#TestThree", results);
}
@Test
public void testFirstTestWholePath() throws Exception {
addTestPagesWithSuiteProperty();
request.setQueryString("firstTest=SuitePage.TestThree");
String results = runSuite();
assertDoesntHaveRegexp("#TestOne", results);
assertHasRegexp("#TestTwo", results);
assertHasRegexp("#TestThree", results);
}
@Test
public void testTagsShouldBeInheritedFromSuite() throws Exception {
PageData suiteData = suite.getData();
suiteData.setAttribute(PageData.PropertySUITES, "tag");
suite.commit(suiteData);
addTestToSuite("TestInheritsTag", fitPassFixture);
request.setQueryString("suiteFilter=tag");
String results = runSuite();
assertHasRegexp("#TestInheritsTag", results);
}
private void addTestPagesWithSuiteProperty() throws Exception {
WikiPage test2 = addTestToSuite("TestTwo", fitPassFixture);
WikiPage test3 = addTestToSuite("TestThree", fitPassFixture);
PageData data2 = test2.getData();
PageData data3 = test3.getData();
data2.setAttribute(PageData.PropertySUITES, "foo");
data3.setAttribute(PageData.PropertySUITES, "bar, smoke");
test2.commit(data2);
test3.commit(data3);
}
@Test
public void testCanMixSlimAndFitTests() throws Exception {
addTestToSuite("SlimTest", simpleSlimDecisionTable);
String results = runSuite();
assertHasRegexp("<td>fitnesse.testutil.PassFixture</td>", results);
assertHasRegexp("<td><span class=\"pass\">wow</span></td>", results);
assertHasRegexp("<h3>fit:fit.FitServer</h3>", results);
assertHasRegexp("<h3>slim:in-process", results);
}
@Test
public void xmlFormat() throws Exception {
responder.turnOffChunking();
request.addInput("format", "xml");
addTestToSuite("SlimTest", simpleSlimDecisionTable);
String results = runSuite();
Document testResultsDocument = XmlTestUtilities.getXmlDocumentFromResults(results);
Element testResultsElement = testResultsDocument.getDocumentElement();
assertEquals("testResults", testResultsElement.getNodeName());
NodeList resultList = testResultsElement.getElementsByTagName("result");
assertEquals(2, resultList.getLength());
Element testResult;
for (int elementIndex = 0; elementIndex < 2; elementIndex++) {
testResult = (Element) resultList.item(elementIndex);
String pageName = XmlUtil.getTextValue(testResult, "relativePageName");
assertSubString(pageName + "?pageHistory&resultDate=", XmlUtil.getTextValue(testResult, "pageHistoryLink"));
if ("SlimTest".equals(pageName)) {
XmlTestUtilities.assertCounts(testResult, "1", "0", "0", "0");
} else if ("TestOne".equals(pageName)) {
XmlTestUtilities.assertCounts(testResult, "1", "0", "0", "0");
} else {
fail(pageName);
}
}
Element finalCounts = XmlUtil.getElementByTagName(testResultsElement, "finalCounts");
XmlTestUtilities.assertCounts(finalCounts, "2", "0", "0", "0");
}
@Test
public void junitFormat() throws Exception {
responder.turnOffChunking();
request.addInput("format", "junit");
addTestToSuite("SlimTest", simpleSlimDecisionTable);
String results = runSuite();
Document testResultsDocument = JunitTestUtilities.getXmlDocumentFromResults(results);
Element testResultsElement = testResultsDocument.getDocumentElement();
assertEquals("testsuite", testResultsElement.getNodeName());
assertEquals("SuitePage",testResultsElement.getAttribute("name"));
assertEquals("2",testResultsElement.getAttribute("tests"));
assertEquals("0",testResultsElement.getAttribute("failures"));
assertEquals("0",testResultsElement.getAttribute("disabled"));
assertEquals("0",testResultsElement.getAttribute("errors"));
NodeList resultList = testResultsElement.getElementsByTagName("testcase");
assertEquals(2, resultList.getLength());
Element testResult;
for (int elementIndex = 0; elementIndex < 2; elementIndex++) {
testResult = (Element) resultList.item(elementIndex);
String pageName = testResult.getAttribute("name");
assertSubString(pageName + "?pageHistory&resultDate=", XmlUtil.getTextValue(testResult,"system-out"));
assertEquals("1",testResult.getAttribute("assertions"));
}
}
@Test
public void normalSuiteRunWithThreePassingTestsProducesSuiteResultFile() throws Exception {
File xmlResultsFile = expectedXmlResultsFile();
if (xmlResultsFile.exists())
xmlResultsFile.delete();
addTestToSuite("SlimTestOne", simpleSlimDecisionTable);
addTestToSuite("SlimTestTwo", simpleSlimDecisionTable);
runSuite();
FileInputStream xmlResultsStream = new FileInputStream(xmlResultsFile);
XmlUtil.newDocument(xmlResultsStream);
xmlResultsStream.close();
xmlResultsFile.delete();
}
@Test
public void NoHistory_avoidsProducingSuiteResultFile() throws Exception {
File xmlResultsFile = expectedXmlResultsFile();
if (xmlResultsFile.exists())
xmlResultsFile.delete();
request.addInput("nohistory", "true");
addTestToSuite("SlimTestOne", simpleSlimDecisionTable);
addTestToSuite("SlimTestTwo", simpleSlimDecisionTable);
runSuite();
assertFalse(xmlResultsFile.exists());
}
@Test
public void Includehtml_producesHTMLResultsInXMLSuite() throws Exception {
request.addInput("format", "xml");
request.addInput("includehtml", "true");
addTestToSuite("SlimTestOne", simpleSlimDecisionTable);
addTestToSuite("SlimTestTwo", simpleSlimDecisionTable);
String results = runSuite();
assertSubString("<content>", results);
}
@Test
public void Default_producesNoHTMLResultsInXMLSuite() throws Exception {
request.addInput("format", "xml");
addTestToSuite("SlimTestOne", simpleSlimDecisionTable);
addTestToSuite("SlimTestTwo", simpleSlimDecisionTable);
String results = runSuite();
assertNotSubString("<content>", results);
}
private File expectedXmlResultsFile() {
TestSummary counts = new TestSummary(3, 0, 0, 0);
String resultsFileName = String.format("%s/SuitePage/20081205011900_%d_%d_%d_%d.xml",
context.getTestHistoryDirectory(), counts.getRight(), counts.getWrong(), counts.getIgnores(), counts.getExceptions());
File xmlResultsFile = new File(resultsFileName);
return xmlResultsFile;
}
@Test
public void normalSuiteRunProducesIndivualTestHistoryFile() throws Exception {
TestSummary counts = new TestSummary(1, 0, 0, 0);
String resultsFileName = String.format("%s/SuitePage.SlimTest/20081205011900_%d_%d_%d_%d.xml",
context.getTestHistoryDirectory(), counts.getRight(), counts.getWrong(), counts.getIgnores(), counts.getExceptions());
File xmlResultsFile = new File(resultsFileName);
if (xmlResultsFile.exists())
xmlResultsFile.delete();
addTestToSuite("SlimTest", simpleSlimDecisionTable);
runSuite();
assertTrue(resultsFileName, xmlResultsFile.exists());
FileInputStream xmlResultsStream = new FileInputStream(xmlResultsFile);
XmlUtil.newDocument(xmlResultsStream);
xmlResultsStream.close();
xmlResultsFile.delete();
}
@Test
public void exitCodeHeaderIsErrorCountForXml() throws Exception {
request.addInput("format", "xml");
addTestToSuite("TestFailingTest", fitFailFixture);
String results = runSuite();
assertSubString("Exit-Code: 1", results);
}
@Test
public void showExecutionLogInXmlFormat() throws Exception {
request.addInput("format", "xml");
request.addInput("nochunk", "nochunk");
addTestToSuite("SlimTest", simpleSlimDecisionTable);
String results = runSuite();
assertHasRegexp("<executionLog>", results);
assertHasRegexp("<testSystem>fit:fit.FitServer</testSystem>", results);
assertHasRegexp("<testSystem>slim:in-process</testSystem>", results);
assertHasRegexp("<exitCode>0</exitCode>", results);
assertHasRegexp("<stdOut>.*</stdOut>", results);
assertHasRegexp("<stdErr>.*</stdErr>", results);
}
@Test
public void loadsCustomFormatters() throws Exception {
context.formatterFactory.registerFormatter(FooFormatter.class);
FooFormatter.initialized = false;
addTestToSuite("SlimTestOne", simpleSlimDecisionTable);
runSuite();
assertTrue(FooFormatter.initialized);
}
public static class FooFormatter extends BaseFormatter {
private static boolean initialized;
public FooFormatter() {
initialized = true;
}
}
}