All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sft.report.HtmlReport Maven / Gradle / Ivy

Go to download

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 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