
sft.report.HtmlReport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sft-core Show documentation
Show all versions of sft-core Show documentation
A JUnit extension to easily adopt functional testing and acceptance testing
The newest version!
/*******************************************************************************
* Copyright (c) 2013, 2014 Sylvain Lézier.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sylvain Lézier - initial implementation
*******************************************************************************/
package sft.report;
import sft.*;
import sft.decorators.*;
import sft.environment.TargetFolder;
import sft.report.decorators.*;
import sft.result.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
public class HtmlReport extends Report {
public static final String HTML_DEPENDENCIES_FOLDER = "sft-html-default";
private final RelativePathResolver pathResolver = new RelativePathResolver();
public String useCaseTemplate =
"\n" +
" \n" +
" @@@useCase.name@@@ \n" +
"@@@useCase.css@@@" +
"@@@useCase.js@@@" +
" \n" +
" \n" +
" \n" +
" \n" +
" \n" +
" @@@useCase.name@@@
\n" +
" \n" +
"@@@useCaseCommentTemplate@@@" +
" \n" +
"@@@beforeUseCaseTemplate@@@" +
"@@@scenarioTemplates@@@" +
"@@@afterUseCaseTemplate@@@" +
"@@@relatedUseCasesTemplates@@@" +
" \n" +
" \n" +
"";
public String useCaseCommentTemplate =
" \n" +
"@@@comment.text@@@" +
" \n";
public String beforeUseCaseTemplate =
" \n" +
" \n" +
"@@@contextInstructionTemplates@@@" +
" \n" +
"@@@exceptionTemplate@@@" +
" \n";
public String scenarioTemplate =
" \n" +
" \n" +
" @@@scenario.name@@@
\n" +
" \n" +
"@@@scenarioCommentTemplate@@@" +
"@@@beforeScenarioTemplate@@@" +
" \n" +
"@@@scenarioInstructionTemplates@@@" +
" \n" +
"@@@afterScenarioTemplate@@@" +
"@@@displayedContextsTemplates@@@" +
"@@@exceptionTemplate@@@" +
" \n";
public String scenarioCommentTemplate =
" \n" +
"@@@comment.text@@@" +
" \n";
public String exceptionTemplate =
" \n" +
" \n" +
" @@@failure.className@@@: @@@failure.message@@@\n" +
" @@@failure.stacktrace@@@
\n" +
" \n" +
" \n";
public String beforeScenarioTemplate =
" \n" +
"@@@contextInstructionTemplates@@@" +
"
\n" +
" ";
public String scenarioInstructionTemplate =
" @@@instruction.emptyLines@@@" +
" \n" +
" @@@instruction.text@@@" +
" \n";
public String afterScenarioTemplate =
" \n" +
"
\n " +
"@@@contextInstructionTemplates@@@" +
" ";
public String displayedContextsTemplate =
" \n" +
"@@@displayedContextTemplates@@@" +
" \n";
public String displayedContextTemplate =
" \n" +
"@@@displayedContext.text@@@" +
" \n";
public String afterUseCaseTemplate =
" \n" +
" \n" +
"@@@contextInstructionTemplates@@@" +
" \n" +
"@@@exceptionTemplate@@@" +
" \n";
public String contextInstructionTemplate =
" \n" +
" @@@instruction.text@@@\n" +
" \n";
public String relatedUseCasesTitleTemplate =
" \n" +
" @@@relatedUseCasesTitle@@@
\n" +
" \n";
public String relatedUseCasesTemplate =
" \n" +
"@@@relatedUseCasesTitleTemplates@@@" +
" \n" +
" \n" +
"@@@relatedUseCaseTemplates@@@" +
"
\n" +
" \n" +
" \n";
public String relatedUseCaseTemplate =
" \n" +
" @@@relatedUseCase.name@@@\n" +
" \n";
public String parameterTemplate = "@@@parameter.value@@@";
public String ignoredClass = "ignored";
public String failedClass = "failed";
public String successClass = "succeeded";
private HtmlResources htmlResources;
private Map, DecoratorReportImplementation> decorators= new HashMap, DecoratorReportImplementation>();
private TargetFolder reportFolder;
private static final String TARGET_SFT_RESULT = "target/sft-result/";
public HtmlReport(DefaultConfiguration configuration) {
super(configuration);
reportFolder = configuration.getProjectFolder().getTargetFolder(TARGET_SFT_RESULT);
setResourcePath(HTML_DEPENDENCIES_FOLDER);
decorators.put(Style.class,new HtmlStyle(configuration));
decorators.put(Breadcrumb.class,new HtmlBreadcrumb(configuration));
decorators.put(Group.class,new HtmlGroup(configuration));
decorators.put(Table.class,new HtmlTable(configuration));
decorators.put(TableOfContent.class,new HtmlTableOfContent(configuration));
decorators.put(Synthesis.class,new HtmlSynthesis(configuration));
decorators.put(NullDecorator.class,new HtmlNullDecorator(configuration));
}
@Override
public void addDecorator(Class extends Decorator> decoratorClass, DecoratorReportImplementation decoratorImplementation){
decorators.put(decoratorClass, decoratorImplementation);
}
public void setReportPath(String reportPath) {
if( ! reportPath.equals( reportFolder.path)){
reportFolder = new TargetFolder(reportFolder.path,reportPath);
}
}
@Override
public DecoratorReportImplementation getDecoratorImplementation(Decorator decorator) {
if( decorators.containsKey(decorator.getClass())){
return decorators.get(decorator.getClass());
}
System.out.println("Decorator " + decorator.getClass().getCanonicalName() + " not Managed by " + this.getClass().getCanonicalName() + " using default decorator");
return new HtmlNullDecorator(configuration);
}
public void setResourcePath(String resourcePath) {
htmlResources = new HtmlResources(configuration, this,resourcePath);
}
@Override
public void report(UseCaseResult useCaseResult) throws Exception {
final Decorator decorator = useCaseResult.useCase.useCaseDecorator;
String useCaseReport = getDecoratorImplementation(decorator).applyOnUseCase(useCaseResult, decorator.parameters);
File htmlFile = reportFolder.createFileFromClass(useCaseResult.useCase.classUnderTest, ".html");
Writer html = new OutputStreamWriter(new FileOutputStream(htmlFile));
html.write(useCaseReport);
html.close();
System.out.println("Report wrote: " + htmlFile.getCanonicalPath());
}
public String applyOnUseCase(UseCaseResult useCaseResult) {
Class> classUnderTest = useCaseResult.useCase.classUnderTest;
try {
return new TemplateString(useCaseTemplate)
.replace("@@@useCase.name@@@", useCaseResult.useCase.getName())
.replace("@@@useCase.css@@@", htmlResources.getIncludeCssDirectives(classUnderTest))
.replace("@@@useCase.js@@@", htmlResources.getIncludeJsDirectives(classUnderTest))
.replace("@@@useCase.issue@@@", htmlResources.convertIssue(useCaseResult.getIssue()))
.replace("@@@useCaseCommentTemplate@@@", getUseCaseComment(useCaseResult.useCase))
.replace("@@@beforeUseCaseTemplate@@@", getBeforeUseCase(useCaseResult))
.replace("@@@scenarioTemplates@@@", getScenarios(useCaseResult))
.replace("@@@afterUseCaseTemplate@@@", getAfterUseCase(useCaseResult))
.replace("@@@relatedUseCasesTemplates@@@", getRelatedUseCases(useCaseResult))
.getText();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public String applyOnScenario(ScenarioResult scenarioResult) {
return new TemplateString(scenarioTemplate)
.replace("@@@scenario.issue@@@", htmlResources.convertIssue(scenarioResult.issue))
.replace("@@@scenario.name@@@", scenarioResult.scenario.getName())
.replace("@@@scenarioCommentTemplate@@@", getScenarioComment(scenarioResult))
.replace("@@@beforeScenarioTemplate@@@", getBeforeScenario(scenarioResult))
.replace("@@@scenarioInstructionTemplates@@@", getScenarioInstructions(scenarioResult))
.replace("@@@afterScenarioTemplate@@@", getAfterScenario(scenarioResult))
.replace("@@@displayedContextsTemplates@@@", extractDisplayedContexts(scenarioResult))
.replace("@@@exceptionTemplate@@@", getStackTrace(scenarioResult.failure))
.getText();
}
public String generateFixtureCall(FixtureCallResult fixtureCallResult) {
return new TemplateString(scenarioInstructionTemplate)
.replace("@@@instruction.emptyLines@@@", generateEmptyLines(fixtureCallResult.fixtureCall.emptyLine))
.replace("@@@instruction.issue@@@", htmlResources.convertIssue(fixtureCallResult.issue))
.replace("@@@instruction.text@@@", generateInstructionWithParameter(fixtureCallResult.fixtureCall))
.getText();
}
private String generateEmptyLines(int emptyLine) {
String result = "";
for (int i = 0; i < emptyLine; i++) {
result += "
";
}
return result;
}
private String getRelatedUseCases(UseCaseResult useCaseResult) {
if (!useCaseResult.subUseCaseResults.isEmpty()) {
return getRelatedUseCase(useCaseResult);
}
return "";
}
private String getRelatedUseCase(UseCaseResult useCaseResult) {
String result = "";
Decorator decorator = null;
ArrayList subUseCaseResults = new ArrayList();
for (SubUseCaseResult subUseCaseResult : useCaseResult.subUseCaseResults) {
if (decorator == null) {
decorator = subUseCaseResult.subUseCase.decorator;
} else if (!decorator.comply(subUseCaseResult.subUseCase.decorator)) {
result += getDecoratorImplementation(decorator).applyOnSubUseCases(subUseCaseResults, decorator.parameters);
decorator = subUseCaseResult.subUseCase.decorator;
subUseCaseResults = new ArrayList();
}
subUseCaseResults.add(subUseCaseResult);
}
if (!subUseCaseResults.isEmpty()) {
result += getDecoratorImplementation(decorator).applyOnSubUseCases(subUseCaseResults, decorator.parameters);
}
return result;
}
public String applyOnSubUseCases(String title, List subUseCaseResults) {
String relatedUseCase = "";
for (SubUseCaseResult subUseCaseResult : subUseCaseResults) {
relatedUseCase += new TemplateString(relatedUseCaseTemplate)
.replace("@@@relatedUseCase.issue@@@", htmlResources.convertIssue(subUseCaseResult.useCaseResult.getIssue()))
.replace("@@@relatedUseCase.link@@@", pathResolver.getRelativePathAsFile(subUseCaseResult.subUseCase.parentUseCase.classUnderTest, subUseCaseResult.useCaseResult.useCase.classUnderTest, ".html"))
.replace("@@@relatedUseCase.name@@@", subUseCaseResult.useCaseResult.useCase.getName())
.getText();
}
final TemplateString replace = new TemplateString(relatedUseCasesTemplate)
.replace("@@@relatedUseCaseTemplates@@@", relatedUseCase);
if (title != null) {
return replace.replace("@@@relatedUseCasesTitleTemplates@@@", new TemplateString(relatedUseCasesTitleTemplate).replace("@@@relatedUseCasesTitle@@@", title).getText()).getText();
} else {
return replace.replace("@@@relatedUseCasesTitleTemplates@@@", "").getText();
}
}
private String getScenarios(UseCaseResult useCaseResult) {
String result = "";
Decorator decorator = new NullDecorator(configuration);
final ArrayList scenarioResults= new ArrayList();
for( ScenarioResult scenarioResult : useCaseResult.scenarioResults ){
final Scenario scenario = scenarioResult.scenario;
if(decorator != null && !decorator.comply(scenario.decorator)) {
result += getDecoratorImplementation(decorator).applyOnScenarios(scenarioResults, decorator.parameters);
scenarioResults.clear();
}
decorator = scenario.decorator;
scenarioResults.add(scenarioResult);
}
result += getDecoratorImplementation(decorator).applyOnScenarios(scenarioResults, decorator.parameters);
return result;
}
private String getScenarioInstructions(ScenarioResult scenarioResult) {
String result = "";
Decorator decorator = null;
final ArrayList fixtureCallResults = new ArrayList();
for (FixtureCallResult fixtureCallResult : scenarioResult.fixtureCallResults) {
final Fixture fixture = fixtureCallResult.fixtureCall.fixture;
if (decorator != null && !decorator.comply(fixture.decorator)) {
result += getDecoratorImplementation(decorator).applyOnFixtures(fixtureCallResults, decorator.parameters);
fixtureCallResults.clear();
}
decorator = fixture.decorator;
fixtureCallResults.add(fixtureCallResult);
}
result += getDecoratorImplementation(decorator).applyOnFixtures(fixtureCallResults, decorator.parameters);
return result;
}
private String getBeforeScenario(ScenarioResult scenarioResult) {
if (scenarioResult.scenario.useCase.beforeScenario != null) {
String instructions = getContextInstructions(scenarioResult.scenario.useCase.beforeScenario);
return new TemplateString(beforeScenarioTemplate)
.replace("@@@contextInstructionTemplates@@@", instructions)
.getText();
}
return "";
}
private String getAfterScenario(ScenarioResult scenarioResult) {
if (scenarioResult.scenario.useCase.afterScenario != null) {
String instructions = getContextInstructions(scenarioResult.scenario.useCase.afterScenario);
return new TemplateString(afterScenarioTemplate)
.replace("@@@contextInstructionTemplates@@@", instructions)
.getText();
}
return "";
}
private String getScenarioComment(ScenarioResult scenarioResult) {
String comment = "";
if (scenarioResult.scenario.getComment() != null) {
comment = new TemplateString(scenarioCommentTemplate)
.replace("@@@comment.text@@@", scenarioResult.scenario.getComment())
.getText();
}
return comment;
}
private String extractDisplayedContexts(ScenarioResult scenarioResult) {
List values = scenarioResult.contextToDisplay;
if (!values.isEmpty()) {
String htmlText = "";
for (String value : values) {
htmlText += extractDisplayedContext(value);
}
return new TemplateString(displayedContextsTemplate)
.replace("@@@displayedContextTemplates@@@", htmlText)
.getText();
}
return "";
}
private String getStackTrace(Throwable failure) {
if (failure != null) {
StringWriter stringWriter = new StringWriter();
failure.printStackTrace(new PrintWriter(stringWriter));
return new TemplateString(exceptionTemplate)
.replace("@@@failure.className@@@", failure.getClass().getSimpleName())
.replace("@@@failure.message@@@", failure.getMessage())
.replace("@@@failure.stacktrace@@@", stringWriter.toString())
.getText();
}
return "";
}
private String extractDisplayedContext(String value) {
return new TemplateString(displayedContextTemplate)
.replace("@@@displayedContext.text@@@", value)
.getText();
}
private String getBeforeUseCase(UseCaseResult useCaseResult) {
UseCase useCase = useCaseResult.useCase;
if (useCase.beforeUseCase != null) {
return new TemplateString(beforeUseCaseTemplate)
.replace("@@@beforeUseCase.issue@@@", htmlResources.convertIssue(useCaseResult.beforeResult.issue))
.replace("@@@contextInstructionTemplates@@@", getContextInstructions(useCase.beforeUseCase))
.replace("@@@exceptionTemplate@@@", getStackTrace(useCaseResult.beforeResult))
.getText();
} else {
return "";
}
}
private String getAfterUseCase(UseCaseResult useCaseResult) throws IOException {
UseCase useCase = useCaseResult.useCase;
if (useCase.afterUseCase != null) {
return new TemplateString(afterUseCaseTemplate)
.replace("@@@afterUseCase.issue@@@", htmlResources.convertIssue(useCaseResult.afterResult.issue))
.replace("@@@contextInstructionTemplates@@@", getContextInstructions(useCase.afterUseCase))
.replace("@@@exceptionTemplate@@@", getStackTrace(useCaseResult.afterResult))
.getText();
} else {
return "";
}
}
private String getStackTrace(ContextResult contextResult) {
if (contextResult.isSuccessful()) {
return "";
} else {
return getStackTrace(contextResult.exception);
}
}
private String getContextInstructions(ContextHandler context) {
String instructions = "";
for (FixtureCall fixtureCall : context.fixtureCalls) {
instructions += new TemplateString(contextInstructionTemplate)
.replace("@@@instruction.text@@@", generateInstructionWithParameter(fixtureCall))
.getText();
}
return instructions;
}
public String generateInstructionWithParameter(FixtureCall testFixture) {
String instruction = testFixture.fixture.getText();
for (Map.Entry parameter : testFixture.getParameters().entrySet()) {
String value = Matcher.quoteReplacement(getParameter(parameter.getValue()));
instruction = instruction.replaceAll("\\$\\{" + parameter.getKey() + "\\}", value);
}
return instruction;
}
private String getParameter(String value) {
return new TemplateString(parameterTemplate)
.replace("@@@parameter.value@@@", value)
.getText();
}
private String getUseCaseComment(UseCase useCase) {
String comment = "";
if (useCase.haveComment()) {
return new TemplateString(useCaseCommentTemplate)
.replace("@@@comment.text@@@", useCase.getComment())
.getText();
}
return comment;
}
public HtmlResources getHtmlResources() {
return htmlResources;
}
public String getIssueConverter(Issue issue) {
switch (issue) {
case IGNORED:
return ignoredClass;
case FAILED:
return failedClass;
default:
case SUCCEEDED:
return successClass;
}
}
public String applyOnFixtures(List fixtureCallResults) {
String result = "";
for (FixtureCallResult fixture : fixtureCallResults) {
result += generateFixtureCall(fixture);
}
return result;
}
public String applyOnScenarios(List scenarioResults) {
String scenarioTxt = "";
for (ScenarioResult scenarioResult : scenarioResults) {
scenarioTxt += applyOnScenario(scenarioResult);
}
return scenarioTxt;
}
public void setReportFolder(String targetPath) {
reportFolder = configuration.getProjectFolder().getTargetFolder(targetPath);
}
public TargetFolder getReportFolder() {
return reportFolder;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy