package fitnesse.plugins.slimcoverage;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import fitnesse.slim.instructions.Instruction;
import fitnesse.testrunner.WikiTestPage;
import fitnesse.testsystems.TestExecutionException;
import fitnesse.testsystems.TestPage;
import fitnesse.testsystems.TestSummary;
import fitnesse.testsystems.UnableToStopException;
import fitnesse.testsystems.slim.CustomComparatorRegistry;
import fitnesse.testsystems.slim.HtmlSlimTestSystem;
import fitnesse.testsystems.slim.SlimClient;
import fitnesse.testsystems.slim.SlimTestContextImpl;
import fitnesse.testsystems.slim.tables.SlimTable;
import fitnesse.testsystems.slim.tables.SlimTableFactory;
import fitnesse.wiki.WikiPageDummy;
public class SlimCoverageTestSystem extends HtmlSlimTestSystem {
private final SlimScenarioUsage usage;
public SlimCoverageTestSystem(String testSystemName, SlimTableFactory slimTableFactory, CustomComparatorRegistry customComparatorRegistry) {
super(testSystemName, dummySlimClient(), slimTableFactory, customComparatorRegistry);
this.usage = new SlimScenarioUsage();
}
private static SlimClient dummySlimClient() {
return new SlimClient() {
@Override
public void start() {
}
@Override
public Map<String, Object> invokeAndGetResponse(List<Instruction> statements) {
return null;
}
@Override
public void connect() {
}
@Override
public void bye() {
}
@Override
public void kill() {
}
};
}
public SlimScenarioUsage getUsage() {
return usage;
}
@Override
protected SlimTestContextImpl createTestContext(TestPage testPage) {
String fullPath = testPage.getFullPath();
SlimScenarioUsagePer usageByPage = usage.getUsageByPage(fullPath);
return new SlimCoverageTestContextImpl(testPage, usageByPage);
}
@Override
protected void processTable(SlimTable table, boolean isSuiteTearDownPage) throws TestExecutionException {
table.getAssertions();
}
@Override
protected void testStarted(TestPage testPage) {
super.testStarted(testPage);
// ensure we have a single test passed, which is sometimes a requirement
// (i.e. when run by FitNesseRunner)
getTestContext().incrementPassedTestsCount();
}
@Override
public void bye() throws UnableToStopException {
try {
reportScenarioUsage();
} finally {
super.bye();
}
}
protected void reportScenarioUsageHeader(String header) {
testOutputChunk("<h4>" + header + "</h4>");
}
protected void reportScenarioUsageNewline() {
testOutputChunk("<br/>");
}
protected void reportScenarioUsage() {
WikiPageDummy pageDummy = new WikiPageDummy("Scenario Usage Report", "Scenario Usage Report Content", null);
WikiTestPage testPage = new WikiTestPage(pageDummy);
testStarted(testPage);
Map<String, Integer> totalUsage = usage.getScenarioUsage().getUsage();
if (totalUsage.isEmpty()) {
testOutputChunk("No scenarios in run");
} else {
Collection<String> unused = usage.getUnusedScenarios();
if (!unused.isEmpty()) {
reportScenarioUsageHeader("Unused scenarios:");
testOutputChunk("<ul>");
for (String scenarioName : unused) {
testOutputChunk("<li>" + scenarioName + "</li>");
}
testOutputChunk("</ul>");
reportScenarioUsageNewline();
}
reportScenarioUsageHeader("Total usage count per scenario:");
testOutputChunk("<table>");
testOutputChunk("<tr><th>Scenario</th><th>Count</th></tr>");
for (Map.Entry<String, Integer> totalUsageEntry : totalUsage.entrySet()) {
testOutputChunk("<tr>");
testOutputChunk("<td>");
testOutputChunk(totalUsageEntry.getKey()
+ "</td><td>"
+ totalUsageEntry.getValue());
testOutputChunk("</td>");
testOutputChunk("</tr>");
}
testOutputChunk("</table>");
reportScenarioUsageNewline();
reportScenarioUsageHeader("Scenarios grouped by usage scope:");
testOutputChunk("<ul>");
for (Map.Entry<String, Collection<String>> sByScopeEntry : usage.getScenariosBySmallestScope().entrySet()) {
String scope = sByScopeEntry.getKey();
testOutputChunk("<li>");
testOutputChunk(scope);
testOutputChunk("<ul>");
for (String scenario : sByScopeEntry.getValue()) {
testOutputChunk("<li>" + scenario + "</li>");
}
testOutputChunk("</ul>");
testOutputChunk("</li>");
}
testOutputChunk("</ul>");
reportScenarioUsageNewline();
reportScenarioUsageHeader("Usage count per scenario per page:");
testOutputChunk("<table>");
testOutputChunk("<tr><th>Page</th><th>Scenario</th><th>Count</th></tr>");
for (SlimScenarioUsagePer usagePerPage : usage.getUsage()) {
String pageName = usagePerPage.getGroupName();
for (Map.Entry<String, Integer> usagePerScenario : usagePerPage.getUsage().entrySet()) {
testOutputChunk("<tr>");
testOutputChunk("<td>");
testOutputChunk(pageName
+ "</td><td>"
+ usagePerScenario.getKey()
+ "</td><td>"
+ usagePerScenario.getValue());
testOutputChunk("</td>");
testOutputChunk("</tr>");
}
}
testOutputChunk("</table>");
Map<String, Collection<String>> overriddenPerPage = usage.getOverriddenScenariosPerPage();
if (!overriddenPerPage.isEmpty()) {
reportScenarioUsageNewline();
reportScenarioUsageHeader("Overridden scenario(s) per page:");
testOutputChunk("<ul>");
for (Map.Entry<String, Collection<String>> overriddenForPage : overriddenPerPage.entrySet()) {
String pageName = overriddenForPage.getKey();
testOutputChunk("<li>");
testOutputChunk(pageName);
testOutputChunk("<ul>");
for (String scenario : overriddenForPage.getValue()) {
testOutputChunk("<li>" + scenario + "</li>");
}
testOutputChunk("</ul>");
testOutputChunk("</li>");
}
testOutputChunk("</ul>");
}
}
testComplete(testPage, new TestSummary(0, 0, 1, 0));
}
}