From 65698baeefa9006b867a016b6154d60badf96eac Mon Sep 17 00:00:00 2001 From: kaklakariada Date: Thu, 15 Feb 2024 18:48:18 +0100 Subject: [PATCH] #377: Optionally render details section as open --- .../api/DetailsSectionFolding.java | 13 ++++ .../openfasttrace/api/ReportSettings.java | 69 ++++++++++++++----- .../openfasttrace/api/TestReportSettings.java | 23 +++++++ .../openfasttrace/core/cli/CliArguments.java | 28 ++++++++ .../core/cli/commands/TraceCommand.java | 5 +- .../core/cli/TestCliArguments.java | 32 +++++++-- doc/spec/design.md | 11 +++ doc/spec/system_requirements.md | 17 ++++- .../html/TestHtmlReportCssInlining.java | 14 ++-- .../openfasttrace/report/html/HtmlReport.java | 14 ++-- .../report/html/HtmlReporterFactory.java | 2 +- .../html/view/html/HtmlSpecificationItem.java | 17 ++++- .../html/view/html/HtmlViewFactory.java | 29 +++++--- .../report/html/TestHtmlReport.java | 6 +- .../view/html/AbstractTestHtmlRenderer.java | 4 +- .../view/html/TestHtmlSpecificationItem.java | 23 +++++++ .../html/view/html/TestHtmlViewFactory.java | 10 +-- 17 files changed, 258 insertions(+), 59 deletions(-) create mode 100644 api/src/main/java/org/itsallcode/openfasttrace/api/DetailsSectionFolding.java diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/DetailsSectionFolding.java b/api/src/main/java/org/itsallcode/openfasttrace/api/DetailsSectionFolding.java new file mode 100644 index 000000000..dea0944c9 --- /dev/null +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/DetailsSectionFolding.java @@ -0,0 +1,13 @@ +package org.itsallcode.openfasttrace.api; + +/** + * Determines if the details sections for specification items in the HTML report + * are folded (i.e. hidden) or unfolded (i.e. visible) by default. + */ +public enum DetailsSectionFolding +{ + /** Hide details section by default. */ + HIDE_DETAILS, + /** How details section by default. */ + SHOW_DETAILS; +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/ReportSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/ReportSettings.java index 53a938fc4..de5de9d94 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/ReportSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/ReportSettings.java @@ -1,11 +1,11 @@ package org.itsallcode.openfasttrace.api; +import java.util.Objects; + import org.itsallcode.openfasttrace.api.core.Newline; import org.itsallcode.openfasttrace.api.report.ReportConstants; import org.itsallcode.openfasttrace.api.report.ReportVerbosity; -import java.util.Objects; - /** * This class implements a parameter object to control the settings of OFT's * report mode. @@ -17,6 +17,7 @@ public class ReportSettings private final String outputFormat; private final Newline newline; private final ColorScheme colorScheme; + private final DetailsSectionFolding detailsSectionFolding; private ReportSettings(final Builder builder) { @@ -24,7 +25,8 @@ private ReportSettings(final Builder builder) this.showOrigin = builder.showOrigin; this.outputFormat = builder.outputFormat; this.newline = builder.newline; - this.colorScheme = Objects.requireNonNull(builder.colorScheme); + this.colorScheme = Objects.requireNonNull(builder.colorScheme, "colorScheme"); + this.detailsSectionFolding = Objects.requireNonNull(builder.detailsSectionFolding, "detailsSectionFolding"); } /** @@ -72,10 +74,21 @@ public Newline getNewline() * * @return color scheme */ - public ColorScheme getColorScheme() { + public ColorScheme getColorScheme() + { return this.colorScheme; } + /** + * Get the details section folding status. + * + * @return folding status + */ + public DetailsSectionFolding getDetailsSectionFolding() + { + return detailsSectionFolding; + } + /** * Create default report settings * @@ -101,6 +114,7 @@ public static Builder builder() */ public static class Builder { + private DetailsSectionFolding detailsSectionFolding = DetailsSectionFolding.HIDE_DETAILS; private Newline newline = Newline.UNIX; private String outputFormat = ReportConstants.DEFAULT_REPORT_FORMAT; private boolean showOrigin = false; @@ -109,7 +123,7 @@ public static class Builder private Builder() { - + // empty by intention } /** @@ -123,11 +137,12 @@ public ReportSettings build() } /** - * Set the report verbosity + * Set the report verbosity. Default: + * {@link ReportVerbosity#FAILURE_DETAILS}. * * @param verbosity * report verbosity - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder verbosity(final ReportVerbosity verbosity) { @@ -137,11 +152,11 @@ public Builder verbosity(final ReportVerbosity verbosity) /** * Set the whether the origin of specification items should be shown in - * the report + * the report. Default: {@code false}. * * @param showOrigin * set to {@code true} if the origin should be shown - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder showOrigin(final boolean showOrigin) { @@ -150,11 +165,12 @@ public Builder showOrigin(final boolean showOrigin) } /** - * Set the output format + * Set the output format. Default: + * {@link ReportConstants#DEFAULT_REPORT_FORMAT}. * * @param outputFormat * output format - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder outputFormat(final String outputFormat) { @@ -163,11 +179,11 @@ public Builder outputFormat(final String outputFormat) } /** - * Set the newline format + * Set the newline format. Default: {@link Newline#UNIX}. * * @param newline * newline format - * @return this for fluent programming + * @return {@code this} for fluent programming */ public Builder newline(final Newline newline) { @@ -176,13 +192,30 @@ public Builder newline(final Newline newline) } /** - * Set the desired color scheme + * Set the desired color scheme. Default: + * {@link ColorScheme#BLACK_AND_WHITE}. + * + * @param colorScheme + * color scheme to use + * @return {@code this} for fluent programming + */ + public Builder colorScheme(final ColorScheme colorScheme) + { + this.colorScheme = Objects.requireNonNull(colorScheme, "colorScheme"); + return this; + } + + /** + * Set the desired details section folding status. Default: + * {@link DetailsSectionFolding#HIDE_DETAILS}. * - * @param colorScheme color scheme to use - * @return this for fluent programming + * @param detailsSectionFolding + * folding status to use + * @return {@code this} for fluent programming */ - public Builder colorScheme(final ColorScheme colorScheme) { - this.colorScheme = Objects.requireNonNull(colorScheme); + public Builder detailsSectionFolding(final DetailsSectionFolding detailsSectionFolding) + { + this.detailsSectionFolding = Objects.requireNonNull(detailsSectionFolding, "detailsSectionFolding"); return this; } } diff --git a/api/src/test/java/org/itsallcode/openfasttrace/api/TestReportSettings.java b/api/src/test/java/org/itsallcode/openfasttrace/api/TestReportSettings.java index a27c6638e..8107da271 100644 --- a/api/src/test/java/org/itsallcode/openfasttrace/api/TestReportSettings.java +++ b/api/src/test/java/org/itsallcode/openfasttrace/api/TestReportSettings.java @@ -2,6 +2,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.itsallcode.openfasttrace.api.ReportSettings.Builder; import org.itsallcode.openfasttrace.api.core.Newline; @@ -69,4 +70,26 @@ void testBuildWithNewline() assertThat(this.builder.newline(Newline.OLDMAC).build().getNewline(), equalTo(Newline.OLDMAC)); } + + @Test + void testBuildDetailsFoldingStatusDefault() + { + assertThat(this.builder.build().getDetailsSectionFolding(), + equalTo(DetailsSectionFolding.HIDE_DETAILS)); + } + + @Test + void testBuildDetailsFoldingStatusNullNotAllowed() + { + assertThrows(NullPointerException.class, () -> this.builder.detailsSectionFolding(null)); + } + + @Test + void testBuildDetailsFoldingStatusCustom() + { + assertThat( + this.builder.detailsSectionFolding(DetailsSectionFolding.SHOW_DETAILS).build() + .getDetailsSectionFolding(), + equalTo(DetailsSectionFolding.SHOW_DETAILS)); + } } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java index 6efdfecf8..154baf125 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java @@ -5,6 +5,7 @@ import java.util.*; import org.itsallcode.openfasttrace.api.ColorScheme; +import org.itsallcode.openfasttrace.api.DetailsSectionFolding; import org.itsallcode.openfasttrace.api.cli.DirectoryService; import org.itsallcode.openfasttrace.api.core.Newline; import org.itsallcode.openfasttrace.api.report.ReportConstants; @@ -38,6 +39,9 @@ public class CliArguments private final DirectoryService directoryService; private ColorScheme colorScheme; + // [impl->dsn~reporting.html.details-folding~1] + private DetailsSectionFolding detailsSectionFolding; + /** * Create new {@link CliArguments}. * @@ -312,6 +316,19 @@ public ColorScheme getColorScheme() } } + /** + * Get the default folding status of HTML report details sections. + *

+ * Defaults to {@link DetailsSectionFolding#HIDE_DETAILS}. + *

+ * + * @return folding status + */ + public DetailsSectionFolding getDetailsSectionFolding() + { + return detailsSectionFolding == null ? DetailsSectionFolding.HIDE_DETAILS : detailsSectionFolding; + } + /** * Set a list of tags to be applied as filter during import * @@ -388,4 +405,15 @@ public void setC(final ColorScheme colorScheme) { this.setColorScheme(colorScheme); } + + /** + * Choose the details folding status. + * + * @param detailsSectionFolding + * folding status + */ + public void setDetailsSectionFolding(final DetailsSectionFolding detailsSectionFolding) + { + this.detailsSectionFolding = detailsSectionFolding; + } } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/TraceCommand.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/TraceCommand.java index 74401dbdf..d735cbb94 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/TraceCommand.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/TraceCommand.java @@ -5,9 +5,7 @@ import java.util.List; import org.itsallcode.openfasttrace.api.ReportSettings; -import org.itsallcode.openfasttrace.api.core.LinkedSpecificationItem; -import org.itsallcode.openfasttrace.api.core.SpecificationItem; -import org.itsallcode.openfasttrace.api.core.Trace; +import org.itsallcode.openfasttrace.api.core.*; import org.itsallcode.openfasttrace.core.Oft; import org.itsallcode.openfasttrace.core.cli.CliArguments; @@ -72,6 +70,7 @@ private ReportSettings convertCommandLineArgumentsToReportSettings() .newline(this.arguments.getNewline()) // .showOrigin(this.arguments.getShowOrigin()) // .colorScheme(this.arguments.getColorScheme()) // + .detailsSectionFolding(this.arguments.getDetailsSectionFolding()) // .build(); } } \ No newline at end of file diff --git a/core/src/test/java/org/itsallcode/openfasttrace/core/cli/TestCliArguments.java b/core/src/test/java/org/itsallcode/openfasttrace/core/cli/TestCliArguments.java index 1a0904eb8..aee76e22b 100644 --- a/core/src/test/java/org/itsallcode/openfasttrace/core/cli/TestCliArguments.java +++ b/core/src/test/java/org/itsallcode/openfasttrace/core/cli/TestCliArguments.java @@ -8,6 +8,7 @@ import java.util.List; import org.itsallcode.openfasttrace.api.ColorScheme; +import org.itsallcode.openfasttrace.api.DetailsSectionFolding; import org.itsallcode.openfasttrace.api.core.Newline; import org.itsallcode.openfasttrace.api.report.ReportConstants; import org.itsallcode.openfasttrace.api.report.ReportVerbosity; @@ -234,8 +235,8 @@ void testSetS() assertThat(this.arguments.getShowOrigin(), is(true)); } - // [dsn~reporting.plain-text.ansi-color~1] - // [dsn~reporting.plain-text.ansi-font-style~1] + // [utest->dsn~reporting.plain-text.ansi-color~1] + // [utest->dsn~reporting.plain-text.ansi-font-style~1] @Test void testSetColorScheme() { @@ -243,8 +244,8 @@ void testSetColorScheme() assertThat(this.arguments.getColorScheme(), is(ColorScheme.MONOCHROME)); } - // [dsn~reporting.plain-text.ansi-color~1] - // [dsn~reporting.plain-text.ansi-font-style~1] + // [utest->dsn~reporting.plain-text.ansi-color~1] + // [utest->dsn~reporting.plain-text.ansi-font-style~1] @Test void testSetC() { @@ -266,4 +267,27 @@ void testSetOutputFileOverridesColorSchemeSetting() this.arguments.setOutputFile("something"); assertThat(this.arguments.getColorScheme(), is(ColorScheme.BLACK_AND_WHITE)); } + + // [utest->dsn~reporting.html.details-folding~1] + @Test + void testDetailsSectionFoldingDefaultsToHidden() + { + assertThat(this.arguments.getDetailsSectionFolding(), is(DetailsSectionFolding.HIDE_DETAILS)); + } + + // [utest->dsn~reporting.html.details-folding~1] + @Test + void testDetailsSectionFoldingNullDefaultsToHidden() + { + this.arguments.setDetailsSectionFolding(null); + assertThat(this.arguments.getDetailsSectionFolding(), is(DetailsSectionFolding.HIDE_DETAILS)); + } + + // [utest->dsn~reporting.html.details-folding~1] + @Test + void testDetailsSectionFoldingCustomValue() + { + this.arguments.setDetailsSectionFolding(DetailsSectionFolding.SHOW_DETAILS); + assertThat(this.arguments.getDetailsSectionFolding(), is(DetailsSectionFolding.SHOW_DETAILS)); + } } \ No newline at end of file diff --git a/doc/spec/design.md b/doc/spec/design.md index 245a2c6f9..11f4a07b2 100644 --- a/doc/spec/design.md +++ b/doc/spec/design.md @@ -397,6 +397,17 @@ Covers: Needs: impl, itest +#### HTML Reports Allows Configuring Details Folding Status +`dsn~reporting.html.details-folding~1` + +OFT allows configuring the specification item detail section folding status (open or closed). Default is closed. + +Covers: + +* `req~reporting.html.details-folding~1` + +Needs: impl, utest, itest + ## Requirement Format Conversion ### ReqM2 Export diff --git a/doc/spec/system_requirements.md b/doc/spec/system_requirements.md index a503a697d..4d1dd15a5 100644 --- a/doc/spec/system_requirements.md +++ b/doc/spec/system_requirements.md @@ -569,7 +569,22 @@ OFT creates the HTML Report as a single file. Rationale: -It makes exchanging reports with other people easier if everything is contained in a single file. +It makes exchanging reports with other people easier if everything is contained in a single file. + +Covers: + +* [feat~html-report~1](#html-report) + +Needs: dsn + +##### HTML Report Renders Details Opened or Closed by Default +`req~reporting.html.details-folding~1` + +OFT allows configuring the folding status of specification item details to open or closed by default. + +Rationale: + +Allowing the details section to be opened and visible allows rendering the HTML report to a PDF document that contains all details. Covers: diff --git a/product/src/test/java/org/itsallcode/openfasttrace/report/html/TestHtmlReportCssInlining.java b/product/src/test/java/org/itsallcode/openfasttrace/report/html/TestHtmlReportCssInlining.java index 534957777..e25c72579 100644 --- a/product/src/test/java/org/itsallcode/openfasttrace/report/html/TestHtmlReportCssInlining.java +++ b/product/src/test/java/org/itsallcode/openfasttrace/report/html/TestHtmlReportCssInlining.java @@ -1,17 +1,15 @@ package org.itsallcode.openfasttrace.report.html; import static org.hamcrest.MatcherAssert.assertThat; - import static org.hamcrest.core.StringContains.containsString; import static org.junit.jupiter.api.Assertions.assertThrows; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Path; +import org.itsallcode.openfasttrace.api.DetailsSectionFolding; import org.itsallcode.openfasttrace.api.report.ReportException; import org.itsallcode.openfasttrace.report.html.view.ViewableContainer; import org.itsallcode.openfasttrace.report.html.view.html.HtmlViewFactory; @@ -31,7 +29,8 @@ void testHtmlReportContainsInlineCSS(@TempDir final Path tempDir) throws IOExcep final File cssFile = tempDir.resolve("test.css").toFile(); writeTextFile(cssFile, CSS); final ByteArrayOutputStream stream = new ByteArrayOutputStream(); - final HtmlViewFactory factory = HtmlViewFactory.create(stream, cssFile.toURI().toURL()); + final HtmlViewFactory factory = HtmlViewFactory.create(stream, cssFile.toURI().toURL(), + DetailsSectionFolding.HIDE_DETAILS); final ViewableContainer view = factory.createView("foo", "bar"); view.render(); assertThat(stream.toString(), containsString(CSS)); @@ -41,7 +40,7 @@ void testHtmlReportContainsInlineCSS(@TempDir final Path tempDir) throws IOExcep void testInliningNonExistentCssThrowsException() throws MalformedURLException { final HtmlViewFactory factory = HtmlViewFactory.create(System.out, - new URL("file:///this_file_does_not_exist.css")); + new URL("file:///this_file_does_not_exist.css"), DetailsSectionFolding.HIDE_DETAILS); final ViewableContainer view = factory.createView("foo", "bar"); assertThrows(ReportException.class, () -> view.render()); } @@ -52,7 +51,8 @@ void testInliningUnreadableCssThrowsException(@TempDir final Path tempDir) throw OsDetector.assumeRunningOnUnix(); final File cssFile = tempDir.resolve("test.css").toFile(); cssFile.setReadable(false); - final HtmlViewFactory factory = HtmlViewFactory.create(System.out, cssFile.toURI().toURL()); + final HtmlViewFactory factory = HtmlViewFactory.create(System.out, cssFile.toURI().toURL(), + DetailsSectionFolding.HIDE_DETAILS); final ViewableContainer view = factory.createView("foo", "bar"); assertThrows(ReportException.class, () -> view.render()); } diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReport.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReport.java index b8bb743a2..b36649dc8 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReport.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReport.java @@ -5,12 +5,11 @@ import java.util.Comparator; import java.util.List; +import org.itsallcode.openfasttrace.api.ReportSettings; import org.itsallcode.openfasttrace.api.core.LinkedSpecificationItem; import org.itsallcode.openfasttrace.api.core.Trace; import org.itsallcode.openfasttrace.api.report.Reportable; -import org.itsallcode.openfasttrace.report.html.view.ViewFactory; -import org.itsallcode.openfasttrace.report.html.view.Viewable; -import org.itsallcode.openfasttrace.report.html.view.ViewableContainer; +import org.itsallcode.openfasttrace.report.html.view.*; import org.itsallcode.openfasttrace.report.html.view.html.HtmlViewFactory; /** @@ -20,16 +19,20 @@ public class HtmlReport implements Reportable { private final Trace trace; private static final String REPORT_CSS_FILE = "/css/report.css"; + private final ReportSettings settings; /** * Create a new instance of an {@link HtmlReport} * * @param trace * trace to be reported on + * @param settings + * report settings to use */ - public HtmlReport(final Trace trace) + public HtmlReport(final Trace trace, final ReportSettings settings) { this.trace = trace; + this.settings = settings; } /** @@ -45,7 +48,8 @@ public static URL getCssUrl() @Override public void renderToStream(final OutputStream outputStream) { - final ViewFactory factory = HtmlViewFactory.create(outputStream, getCssUrl()); + final ViewFactory factory = HtmlViewFactory.create(outputStream, getCssUrl(), + settings.getDetailsSectionFolding()); final ViewableContainer view = factory.createView("", "Specification items by artifact type"); final ViewableContainer details = createDetails(factory); diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReporterFactory.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReporterFactory.java index c52a192cc..f69100804 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReporterFactory.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReporterFactory.java @@ -29,6 +29,6 @@ public boolean supportsFormat(String format) @Override public Reportable createImporter(Trace trace) { - return new HtmlReport(trace); + return new HtmlReport(trace, getContext().getSettings()); } } diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java index 14ec30dd5..db6cac9c9 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java @@ -9,6 +9,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.itsallcode.openfasttrace.api.DetailsSectionFolding; import org.itsallcode.openfasttrace.api.core.*; import org.itsallcode.openfasttrace.report.html.view.IndentationHelper; import org.itsallcode.openfasttrace.report.html.view.Viewable; @@ -19,11 +20,14 @@ class HtmlSpecificationItem implements Viewable private final LinkedSpecificationItem item; private final PrintStream stream; private final MarkdownConverter converter = new MarkdownConverter(); + private final DetailsSectionFolding detailsFolding; - HtmlSpecificationItem(final PrintStream stream, final LinkedSpecificationItem item) + HtmlSpecificationItem(final PrintStream stream, final LinkedSpecificationItem item, + final DetailsSectionFolding detailsFolding) { this.stream = stream; this.item = item; + this.detailsFolding = detailsFolding; } @Override @@ -50,7 +54,16 @@ protected void renderStart(final String indentation, final SpecificationItemId i this.stream.print(id); this.stream.println("\">"); this.stream.print(indentation); - this.stream.println("
"); + this.stream.println(" "); + } + + private String detailsAttributes() + { + if (detailsFolding == DetailsSectionFolding.SHOW_DETAILS) + { + return " open"; + } + return ""; } private void renderId(final String indentation, final SpecificationItemId id) diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlViewFactory.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlViewFactory.java index 202135d6b..6aa14f180 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlViewFactory.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlViewFactory.java @@ -1,18 +1,15 @@ package org.itsallcode.openfasttrace.report.html.view.html; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.net.URL; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import org.itsallcode.openfasttrace.api.DetailsSectionFolding; import org.itsallcode.openfasttrace.api.core.LinkedSpecificationItem; import org.itsallcode.openfasttrace.api.core.Trace; import org.itsallcode.openfasttrace.api.exporter.ExporterException; -import org.itsallcode.openfasttrace.report.html.view.AbstractViewFactory; -import org.itsallcode.openfasttrace.report.html.view.Viewable; -import org.itsallcode.openfasttrace.report.html.view.ViewableContainer; +import org.itsallcode.openfasttrace.report.html.view.*; /** * Factory that creates an HTML OFT view (e.g. for reports) and provides an @@ -22,11 +19,13 @@ public class HtmlViewFactory extends AbstractViewFactory { private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; private final URL cssUrl; + private final DetailsSectionFolding foldingStatus; - private HtmlViewFactory(final PrintStream stream, final URL cssUrl) + private HtmlViewFactory(final PrintStream stream, final URL cssUrl, final DetailsSectionFolding foldingStatus) { super(stream); this.cssUrl = cssUrl; + this.foldingStatus = foldingStatus; } /** @@ -36,17 +35,25 @@ private HtmlViewFactory(final PrintStream stream, final URL cssUrl) * the output stream. * @param cssURL * the URL of the CSS file to include in the HTML report. + * @param foldingStatus + * the folding status of the {@code <details>} element. * @return a new {@link HtmlViewFactory}. */ - public static HtmlViewFactory create(final OutputStream stream, final URL cssURL) + public static HtmlViewFactory create(final OutputStream stream, final URL cssURL, + final DetailsSectionFolding foldingStatus) + { + return new HtmlViewFactory(createPrintStream(stream), cssURL, foldingStatus); + } + + private static PrintStream createPrintStream(final OutputStream stream) { if (stream instanceof PrintStream) { - return new HtmlViewFactory((PrintStream) stream, cssURL); + return (PrintStream) stream; } else { - return new HtmlViewFactory(createPrintStream(stream, DEFAULT_CHARSET), cssURL); + return createPrintStream(stream, DEFAULT_CHARSET); } } @@ -83,7 +90,7 @@ public ViewableContainer createSection(final String id, final String title) @Override public Viewable createSpecificationItem(final LinkedSpecificationItem item) { - return new HtmlSpecificationItem(this.outputStream, item); + return new HtmlSpecificationItem(this.outputStream, item, foldingStatus); } @Override diff --git a/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/TestHtmlReport.java b/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/TestHtmlReport.java index 2b832d30f..49f0bb28c 100644 --- a/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/TestHtmlReport.java +++ b/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/TestHtmlReport.java @@ -9,8 +9,10 @@ import java.io.OutputStream; import java.util.Arrays; +import org.itsallcode.openfasttrace.api.ReportSettings; import org.itsallcode.openfasttrace.api.core.*; import org.itsallcode.openfasttrace.api.report.Reportable; +import org.itsallcode.openfasttrace.api.report.ReporterContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -34,7 +36,9 @@ void testRenderEmptyTrace() protected String renderToString() { final OutputStream outputStream = new ByteArrayOutputStream(); - final Reportable report = new HtmlReporterFactory().createImporter(traceMock); + final HtmlReporterFactory htmlReporterFactory = new HtmlReporterFactory(); + htmlReporterFactory.init(new ReporterContext(ReportSettings.createDefault())); + final Reportable report = htmlReporterFactory.createImporter(traceMock); report.renderToStream(outputStream); final String outputAsString = outputStream.toString(); return outputAsString; diff --git a/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/AbstractTestHtmlRenderer.java b/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/AbstractTestHtmlRenderer.java index 20e0dfb7f..152b22d8c 100644 --- a/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/AbstractTestHtmlRenderer.java +++ b/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/AbstractTestHtmlRenderer.java @@ -7,6 +7,7 @@ import java.io.OutputStream; import java.util.regex.Pattern; +import org.itsallcode.openfasttrace.api.DetailsSectionFolding; import org.itsallcode.openfasttrace.report.html.HtmlReport; import org.itsallcode.openfasttrace.report.html.view.ViewFactory; import org.junit.jupiter.api.BeforeEach; @@ -20,7 +21,8 @@ class AbstractTestHtmlRenderer void prepareEachTest() { this.outputStream = new ByteArrayOutputStream(); - this.factory = HtmlViewFactory.create(this.outputStream, HtmlReport.getCssUrl()); + this.factory = HtmlViewFactory.create(this.outputStream, HtmlReport.getCssUrl(), + DetailsSectionFolding.HIDE_DETAILS); } protected void assertOutputLines(final String... lines) diff --git a/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/TestHtmlSpecificationItem.java b/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/TestHtmlSpecificationItem.java index e971c6c70..41eccaa90 100644 --- a/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/TestHtmlSpecificationItem.java +++ b/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/TestHtmlSpecificationItem.java @@ -1,5 +1,7 @@ package org.itsallcode.openfasttrace.report.html.view.html; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.itsallcode.openfasttrace.report.html.view.html.CharacterConstants.CHECK_MARK; import static org.itsallcode.openfasttrace.report.html.view.html.CharacterConstants.CROSS_MARK; import static org.itsallcode.openfasttrace.testutil.core.SampleArtifactTypes.IMPL; @@ -7,11 +9,15 @@ import static org.itsallcode.openfasttrace.testutil.core.SampleArtifactTypes.UTEST; import static org.mockito.Mockito.lenient; +import org.itsallcode.openfasttrace.api.DetailsSectionFolding; import org.itsallcode.openfasttrace.api.core.*; +import org.itsallcode.openfasttrace.report.html.HtmlReport; import org.itsallcode.openfasttrace.report.html.view.Viewable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -65,6 +71,23 @@ void testRenderMinimalItem() ""); } + // [utest->dsn~reporting.html.details-folding~1] + @ParameterizedTest + @CsvSource(nullValues = "NULL", value = + { "NULL,
", "HIDE_DETAILS,
", "SHOW_DETAILS,
" }) + void testRenderDetailsDefaultValue(final DetailsSectionFolding foldingStatus, final String expectedDetailsElement) + { + this.factory = HtmlViewFactory.create(this.outputStream, HtmlReport.getCssUrl(), + foldingStatus); + final SpecificationItem item = SpecificationItem.builder() // + .id(ITEM_A_ID) // + .title("Item A title") // + .description("Single line description") // + .build(); + renderItemOnIndentationLevel(item, 1); + assertThat(this.outputStream.toString(), containsString(expectedDetailsElement)); + } + @Test void testRenderMultiLineItem() { diff --git a/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/TestHtmlViewFactory.java b/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/TestHtmlViewFactory.java index 47a99c715..36eb68109 100644 --- a/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/TestHtmlViewFactory.java +++ b/reporter/html/src/test/java/org/itsallcode/openfasttrace/report/html/view/html/TestHtmlViewFactory.java @@ -7,12 +7,11 @@ import java.io.*; import java.nio.charset.StandardCharsets; +import org.itsallcode.openfasttrace.api.DetailsSectionFolding; import org.itsallcode.openfasttrace.api.core.LinkedSpecificationItem; import org.itsallcode.openfasttrace.api.core.Trace; import org.itsallcode.openfasttrace.report.html.HtmlReport; -import org.itsallcode.openfasttrace.report.html.view.ViewFactory; -import org.itsallcode.openfasttrace.report.html.view.Viewable; -import org.itsallcode.openfasttrace.report.html.view.ViewableContainer; +import org.itsallcode.openfasttrace.report.html.view.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,14 +25,15 @@ class TestHtmlViewFactory void beforeEach() { this.outputStream = new ByteArrayOutputStream(); - this.factory = HtmlViewFactory.create(this.outputStream, HtmlReport.getCssUrl()); + this.factory = HtmlViewFactory.create(this.outputStream, HtmlReport.getCssUrl(), + DetailsSectionFolding.HIDE_DETAILS); } @Test void testCreateFactoryWithPrintStream() throws UnsupportedEncodingException { factory = HtmlViewFactory.create(new PrintStream(outputStream, true, StandardCharsets.UTF_8), - HtmlReport.getCssUrl()); + HtmlReport.getCssUrl(), DetailsSectionFolding.HIDE_DETAILS); assertThat(factory, notNullValue()); }