diff --git a/build.gradle b/build.gradle
index dab51eb5..b14f9bb5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -146,7 +146,8 @@ configure(subprojects.findAll({
"com.github.nagyesta.abortmission.testkit.vanilla.ParachuteDropTestAssets",
"com.github.nagyesta.abortmission.testkit.NoOpMatcher",
"com.github.nagyesta.abortmission.booster.junit4.support.LaunchAbortTestWatcher.1",
- "com.github.nagyesta.abortmission.reporting.AbortMissionFlightEvaluationReportApp"
+ "com.github.nagyesta.abortmission.reporting.AbortMissionFlightEvaluationReportApp",
+ "org.springframework.boot.loader.JarLauncher"
]
}
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index a288a8e5..00987110 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,6 +1,8 @@
[versions]
spring = "5.3.21"
springBoot = "2.7.1"
+thymeleaf = "3.0.15.RELEASE"
+thymeleafExtrasTime = "3.0.4.RELEASE"
logback = "1.2.11"
jsonSchemaValidator = "1.0.71"
gson = "2.9.0"
@@ -9,6 +11,7 @@ h2 = "2.1.214"
jdbi3 = "3.30.0"
lombok = "1.18.24"
+findbugs = "3.0.2"
junit4 = "4.13.2"
jupiter = "5.8.2"
@@ -18,7 +21,6 @@ cucumber = "7.4.1"
testNg = "7.6.1"
lombokPlugin = "6.5.0.3"
-springBootPlugin = "2.7.2"
minifyPlugin = "1.3.1"
gitVersionerPlugin = "1.6.7"
indexScanPlugin = "2.3.0"
@@ -30,15 +32,14 @@ jacoco = "0.8.2"
[libraries]
spring-core = { module = "org.springframework:spring-core", version.ref = "spring" }
spring-context = { module = "org.springframework:spring-context", version.ref = "spring" }
-spring-web = { module = "org.springframework:spring-web", version.ref = "spring" }
spring-test = { module = "org.springframework:spring-test", version.ref = "spring" }
spring-boot-starter = { module = "org.springframework.boot:spring-boot-starter", version.ref = "springBoot" }
-spring-boot-starter-json = { module = "org.springframework.boot:spring-boot-starter-json", version.ref = "springBoot" }
-spring-boot-starter-thymeleaf = { module = "org.springframework.boot:spring-boot-starter-thymeleaf", version.ref = "springBoot" }
-spring-boot-configuration-processor = { module = "org.springframework.boot:spring-boot-configuration-processor", version.ref = "springBoot" }
spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test", version.ref = "springBoot" }
+thymeleaf = { module = "org.thymeleaf:thymeleaf", version.ref = "thymeleaf" }
+thymeleaf-extras-java8time = { module = "org.thymeleaf.extras:thymeleaf-extras-java8time", version.ref = "thymeleafExtrasTime" }
+
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
logback-core = { module = "ch.qos.logback:logback-core", version.ref = "logback" }
@@ -51,6 +52,7 @@ h2 = { module = "com.h2database:h2", version.ref = "h2" }
jdbi3-sqlobject = { module = "org.jdbi:jdbi3-sqlobject", version.ref = "jdbi3" }
lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" }
+findbugs-jsr305 = { module = "com.google.code.findbugs:jsr305", version.ref = "findbugs" }
junit = { module = "junit:junit", version.ref = "junit4" }
@@ -69,13 +71,10 @@ cucumber-junit = { module = "io.cucumber:cucumber-junit", version.ref = "cucumbe
cucumber-spring = { module = "io.cucumber:cucumber-spring", version.ref = "cucumber" }
[bundles]
-spring-boot-report = ["spring-boot-starter", "spring-boot-starter-json", "spring-boot-starter-thymeleaf"]
-spring-web = ["spring-core", "spring-context", "spring-web"]
spring-test = ["spring-core", "spring-context", "spring-test"]
logback = ["logback-classic", "logback-core"]
[plugins]
-spring-boot = { id = "org.springframework.boot", version.ref = "springBootPlugin" }
lombok = { id = "io.freefair.lombok", version.ref = "lombokPlugin" }
minify = { id = "org.gradlewebtools.minify", version.ref = "minifyPlugin" }
versioner = { id = "io.toolebox.git-versioner", version.ref = "gitVersionerPlugin" }
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index c085dd6a..c824031d 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -142,22 +142,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -166,24 +150,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -506,14 +477,6 @@
-
-
-
-
-
-
-
-
@@ -762,11 +725,6 @@
-
-
-
-
-
@@ -893,22 +851,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -949,24 +891,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1124,14 +1053,6 @@
-
-
-
-
-
-
-
-
@@ -1140,21 +1061,11 @@
-
-
-
-
-
-
-
-
-
-
@@ -1165,24 +1076,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -2043,11 +1941,6 @@
-
-
-
-
-
@@ -2064,11 +1957,6 @@
-
-
-
-
-
@@ -2077,19 +1965,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -2106,29 +1981,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -2137,14 +1989,6 @@
-
-
-
-
-
-
-
-
@@ -2161,14 +2005,6 @@
-
-
-
-
-
-
-
-
@@ -2201,14 +2037,6 @@
-
-
-
-
-
-
-
-
@@ -2217,14 +2045,6 @@
-
-
-
-
-
-
-
-
diff --git a/mission-report/flight-evaluation-report/build.gradle b/mission-report/flight-evaluation-report/build.gradle
index 10c9256f..75c2f994 100644
--- a/mission-report/flight-evaluation-report/build.gradle
+++ b/mission-report/flight-evaluation-report/build.gradle
@@ -1,5 +1,4 @@
plugins {
- alias(libs.plugins.spring.boot)
id 'java'
//noinspection SpellCheckingInspection
alias(libs.plugins.lombok)
@@ -14,17 +13,14 @@ project.ext {
}
dependencies {
- implementation libs.bundles.spring.boot.report
implementation libs.json.schema.validator
+ implementation libs.thymeleaf
+ implementation libs.thymeleaf.extras.java8time
implementation libs.bundles.logback
+ implementation libs.findbugs.jsr305
annotationProcessor libs.lombok
- annotationProcessor libs.spring.boot.configuration.processor
- testImplementation libs.spring.boot.starter.test
testImplementation libs.jupiter.core
- constraints {
- implementation libs.bundles.spring.web
- testImplementation libs.bundles.spring.test
- }
+ testImplementation libs.mockito.core
}
minification {
@@ -119,11 +115,17 @@ task processTemplates {
}
jar {
- enabled = false
+ manifest {
+ attributes "Main-Class": "com.github.nagyesta.abortmission.reporting.AbortMissionFlightEvaluationReportApp"
+ }
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE
+ from {
+ configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
+ }
}
processResources.finalizedBy processTemplates
-bootJarMainClassName.dependsOn processTemplates
+jar.dependsOn processTemplates
checkstyleMain.dependsOn processTemplates
compileTestJava.dependsOn processTemplates
javadoc.dependsOn processTemplates
@@ -136,7 +138,6 @@ publishing {
publications {
mavenJava(MavenPublication) {
from components.java
- artifact bootJar
artifactId = "abort.${project.name}"
pom {
name = "${project.artifactDisplayName}"
diff --git a/mission-report/flight-evaluation-report/lombok.config b/mission-report/flight-evaluation-report/lombok.config
index 189c0bef..6a902c83 100644
--- a/mission-report/flight-evaluation-report/lombok.config
+++ b/mission-report/flight-evaluation-report/lombok.config
@@ -1,3 +1,4 @@
# This file is generated by the 'io.freefair.lombok' Gradle plugin
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
+lombok.nonnull.exceptiontype=IllegalArgumentException
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/AbortMissionAppContext.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/AbortMissionAppContext.java
new file mode 100644
index 00000000..bf1d8944
--- /dev/null
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/AbortMissionAppContext.java
@@ -0,0 +1,40 @@
+package com.github.nagyesta.abortmission.reporting;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.nagyesta.abortmission.reporting.config.ConversionProperties;
+import com.github.nagyesta.abortmission.reporting.controller.ConversionController;
+import com.github.nagyesta.abortmission.reporting.html.converter.ClassJsonToHtmlConverter;
+import com.github.nagyesta.abortmission.reporting.html.converter.LaunchJsonToHtmlConverter;
+import com.github.nagyesta.abortmission.reporting.html.converter.StageLaunchStatsJsonToHtmlConverter;
+import com.github.nagyesta.abortmission.reporting.html.converter.StatsJsonToHtmlConverter;
+import org.thymeleaf.TemplateEngine;
+
+public class AbortMissionAppContext {
+ private final ConversionController controller;
+
+ public AbortMissionAppContext(final ConversionProperties properties) {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ final StatsJsonToHtmlConverter statsConverter = new StatsJsonToHtmlConverter();
+ final StageLaunchStatsJsonToHtmlConverter stageConverter = new StageLaunchStatsJsonToHtmlConverter(statsConverter);
+ final ClassJsonToHtmlConverter classConverter = new ClassJsonToHtmlConverter(statsConverter, stageConverter);
+ final LaunchJsonToHtmlConverter launchConverter = new LaunchJsonToHtmlConverter(statsConverter, classConverter);
+ final TemplateEngine templateEngine = new TemplateEngine();
+ controller = new ConversionController(properties, objectMapper, launchConverter, templateEngine);
+ }
+
+ /**
+ * Returns the controller.
+ *
+ * @return controller
+ */
+ public ConversionController controller() {
+ return controller;
+ }
+
+ /**
+ * Exits with an error code (1).
+ */
+ public void exitWithError() {
+ System.exit(1);
+ }
+}
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/AbortMissionFlightEvaluationReportApp.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/AbortMissionFlightEvaluationReportApp.java
index c914adbb..4a93c945 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/AbortMissionFlightEvaluationReportApp.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/AbortMissionFlightEvaluationReportApp.java
@@ -1,16 +1,33 @@
package com.github.nagyesta.abortmission.reporting;
-import com.github.nagyesta.abortmission.reporting.controller.ConversionController;
+import com.github.nagyesta.abortmission.reporting.config.ConversionProperties;
import com.github.nagyesta.abortmission.reporting.exception.RenderException;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Arrays;
+import java.util.List;
-@SpringBootApplication
@SuppressWarnings("checkstyle:HideUtilityClassConstructor")
-public class AbortMissionFlightEvaluationReportApp {
+@Slf4j
+public final class AbortMissionFlightEvaluationReportApp {
public static void main(final String[] args) throws RenderException {
- SpringApplication.run(AbortMissionFlightEvaluationReportApp.class, args)
- .getBean(ConversionController.class).convert();
+ final AbortMissionFlightEvaluationReportApp app = new AbortMissionFlightEvaluationReportApp();
+ app.execute(app.bootstrap(Arrays.asList(args)));
+ }
+
+ AbortMissionAppContext bootstrap(final List args) {
+ final ConversionProperties properties = new PropertiesParser(args).parseArguments();
+ return new AbortMissionAppContext(properties);
}
+
+ void execute(final AbortMissionAppContext context) {
+ try {
+ context.controller().convert();
+ } catch (final RenderException ex) {
+ log.error(ex.getMessage(), ex);
+ context.exitWithError();
+ }
+ }
+
}
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/PropertiesParser.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/PropertiesParser.java
new file mode 100644
index 00000000..07672eec
--- /dev/null
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/PropertiesParser.java
@@ -0,0 +1,40 @@
+package com.github.nagyesta.abortmission.reporting;
+
+import com.github.nagyesta.abortmission.reporting.config.ConversionProperties;
+
+import java.io.File;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+
+public final class PropertiesParser {
+
+ private static final String INPUT = "--report.input";
+ private static final String OUTPUT = "--report.output";
+ private static final String RELAXED = "--report.relaxed";
+ private static final String FAIL_ON_ERROR = "--report.failOnError";
+ private static final String EQUALS = "=";
+ private static final String EMPTY = "";
+
+ private final List args;
+
+ public PropertiesParser(final List args) {
+ this.args = List.copyOf(args);
+ }
+
+ public ConversionProperties parseArguments() {
+ final ConversionProperties.ConversionPropertiesBuilder builder = ConversionProperties.builder();
+ parse(INPUT, File::new, builder::input);
+ parse(OUTPUT, File::new, builder::output);
+ parse(RELAXED, Boolean::valueOf, builder::relaxed);
+ parse(FAIL_ON_ERROR, Boolean::valueOf, builder::failOnError);
+ return builder.build();
+ }
+
+ private void parse(final String parameter, final Function mapper, final Consumer consumer) {
+ args.stream().filter(s -> s.startsWith(parameter)).findFirst()
+ .map(s -> s.replaceFirst(Pattern.quote(parameter + EQUALS), EMPTY))
+ .map(mapper).ifPresent(consumer);
+ }
+}
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/config/ConversionProperties.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/config/ConversionProperties.java
index 830b9c62..92e174d3 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/config/ConversionProperties.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/config/ConversionProperties.java
@@ -1,22 +1,61 @@
package com.github.nagyesta.abortmission.reporting.config;
import lombok.Data;
-import lombok.NoArgsConstructor;
import lombok.NonNull;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
+import javax.annotation.Nonnull;
import java.io.File;
@Data
-@NoArgsConstructor
-@Component
-@ConfigurationProperties(prefix = "report", ignoreInvalidFields = false, ignoreUnknownFields = false)
-public class ConversionProperties {
- @NonNull
+public final class ConversionProperties {
private File input;
- @NonNull
private File output;
- private boolean relaxed = false;
- private boolean failOnError = false;
+ private boolean relaxed;
+ private boolean failOnError;
+
+ private ConversionProperties(@NonNull final File input, @NonNull final File output, final boolean relaxed, final boolean failOnError) {
+ this.input = input;
+ this.output = output;
+ this.relaxed = relaxed;
+ this.failOnError = failOnError;
+ }
+
+ public static ConversionPropertiesBuilder builder() {
+ return new ConversionPropertiesBuilder();
+ }
+
+ @SuppressWarnings("checkstyle:HiddenField")
+ public static final class ConversionPropertiesBuilder {
+ private File input;
+ private File output;
+ private boolean relaxed = false;
+ private boolean failOnError = false;
+
+ ConversionPropertiesBuilder() {
+ }
+
+ public ConversionPropertiesBuilder input(@Nonnull final File input) {
+ this.input = input;
+ return this;
+ }
+
+ public ConversionPropertiesBuilder output(@Nonnull final File output) {
+ this.output = output;
+ return this;
+ }
+
+ public ConversionPropertiesBuilder relaxed(final boolean relaxed) {
+ this.relaxed = relaxed;
+ return this;
+ }
+
+ public ConversionPropertiesBuilder failOnError(final boolean failOnError) {
+ this.failOnError = failOnError;
+ return this;
+ }
+
+ public ConversionProperties build() {
+ return new ConversionProperties(input, output, relaxed, failOnError);
+ }
+ }
}
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/controller/ConversionController.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/controller/ConversionController.java
index c95ac03c..ffe04507 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/controller/ConversionController.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/controller/ConversionController.java
@@ -13,18 +13,16 @@
import com.networknt.schema.SpecVersion;
import com.networknt.schema.ValidationMessage;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-import org.springframework.util.StreamUtils;
+import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
-import org.thymeleaf.spring5.SpringTemplateEngine;
+import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
+import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import java.io.*;
import java.nio.charset.StandardCharsets;
+import java.util.Objects;
import java.util.Set;
-@Component
@Slf4j
public class ConversionController {
private static final String ROOT_NODE = "$";
@@ -32,17 +30,18 @@ public class ConversionController {
private final ConversionProperties properties;
private final ObjectMapper objectMapper;
private final LaunchJsonToHtmlConverter converter;
- private final SpringTemplateEngine templateEngine;
+ private final TemplateEngine templateEngine;
- @Autowired
public ConversionController(final ConversionProperties properties,
final ObjectMapper objectMapper,
final LaunchJsonToHtmlConverter converter,
- final SpringTemplateEngine templateEngine) {
+ final TemplateEngine templateEngine) {
this.properties = properties;
this.objectMapper = objectMapper;
this.converter = converter;
this.templateEngine = templateEngine;
+ templateEngine.addDialect(new Java8TimeDialect());
+ templateEngine.setTemplateResolver(new ClassLoaderTemplateResolver());
}
/**
@@ -51,7 +50,9 @@ public ConversionController(final ConversionProperties properties,
* @throws RenderException When the conversion fails for any reason.
*/
public void convert() throws RenderException {
- Assert.isTrue(properties.getInput().exists(), "Input file does not exist.");
+ if (!properties.getInput().exists()) {
+ throw new IllegalArgumentException("Input file does not exist.");
+ }
final LaunchJson json = readValidJson();
render(prepareContext(json));
if (properties.isFailOnError() && json.getStats().getWorstResult() == StageResultJson.FAILURE) {
@@ -64,7 +65,7 @@ public void convert() throws RenderException {
private void render(final Context context) {
try (FileOutputStream stream = new FileOutputStream(properties.getOutput());
OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8)) {
- templateEngine.process("html/launch-report", context, writer);
+ templateEngine.process("/templates/html/launch-report.html", context, writer);
} catch (final Exception e) {
log.error(e.getMessage(), e);
throw new RenderException();
@@ -72,7 +73,7 @@ private void render(final Context context) {
}
private Context prepareContext(final LaunchJson launchJson) {
- final LaunchHtml launchHtml = converter.convert(launchJson);
+ final LaunchHtml launchHtml = converter.apply(launchJson);
final Context context = new Context();
context.setVariable("launchModel", launchHtml);
context.setVariable("allCss", readResource("/templates/css/all.min.css"));
@@ -81,8 +82,9 @@ private Context prepareContext(final LaunchJson launchJson) {
}
private String readResource(final String input) throws RenderException {
- try {
- return StreamUtils.copyToString(ConversionController.class.getResourceAsStream(input), StandardCharsets.UTF_8);
+ //noinspection LocalCanBeFinal
+ try (InputStream stream = ConversionController.class.getResourceAsStream(input)) {
+ return new String(Objects.requireNonNull(stream).readAllBytes(), StandardCharsets.UTF_8);
} catch (final IOException e) {
log.error(e.getMessage(), e);
throw new RenderException();
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/exception/RenderException.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/exception/RenderException.java
index 5992fd7e..056c025e 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/exception/RenderException.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/exception/RenderException.java
@@ -1,10 +1,4 @@
package com.github.nagyesta.abortmission.reporting.exception;
-import org.springframework.boot.ExitCodeGenerator;
-
-public class RenderException extends RuntimeException implements ExitCodeGenerator {
- @Override
- public int getExitCode() {
- return 1;
- }
+public class RenderException extends RuntimeException {
}
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/ClassHtml.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/ClassHtml.java
index 93916132..6cf798a1 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/ClassHtml.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/ClassHtml.java
@@ -1,8 +1,8 @@
package com.github.nagyesta.abortmission.reporting.html;
import lombok.Data;
-import org.springframework.lang.NonNull;
+import javax.annotation.Nonnull;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
@@ -22,7 +22,7 @@ public final class ClassHtml implements Comparable {
private StatsHtml stats;
private Map launches;
- private ClassHtml(@NonNull final ClassHtmlBuilder builder) {
+ private ClassHtml(@Nonnull final ClassHtmlBuilder builder) {
this.classNameText = builder.classNameText;
this.countdown = builder.countdown;
this.stats = builder.stats;
@@ -61,7 +61,7 @@ public long startTimeEpochMillis() {
}
@Override
- public int compareTo(@NonNull final ClassHtml o) {
+ public int compareTo(@Nonnull final ClassHtml o) {
return Comparator.comparing(ClassHtml::startTimeEpochMillis)
.thenComparing(ClassHtml::getClassNameText)
.compare(this, o);
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/LaunchHtml.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/LaunchHtml.java
index 7bf51532..438ea23f 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/LaunchHtml.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/LaunchHtml.java
@@ -1,8 +1,8 @@
package com.github.nagyesta.abortmission.reporting.html;
import lombok.Data;
-import org.springframework.lang.NonNull;
+import javax.annotation.Nonnull;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
@@ -29,7 +29,7 @@ public final class LaunchHtml {
private StatsHtml countdownStats;
private StatsHtml missionStats;
- private LaunchHtml(@NonNull final LaunchHtmlBuilder builder) {
+ private LaunchHtml(@Nonnull final LaunchHtmlBuilder builder) {
this.classes = builder.classes;
this.stats = builder.stats;
this.countdownStats = builder.countdownStats;
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/StageLaunchStatsHtml.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/StageLaunchStatsHtml.java
index dbe8996c..5916706e 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/StageLaunchStatsHtml.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/StageLaunchStatsHtml.java
@@ -3,6 +3,7 @@
import lombok.Data;
import lombok.NonNull;
+import javax.annotation.Nonnull;
import java.util.Optional;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -19,7 +20,7 @@ public final class StageLaunchStatsHtml {
@NonNull
private StatsHtml stats;
- private StageLaunchStatsHtml(@org.springframework.lang.NonNull final StageLaunchStatsHtmlBuilder builder) {
+ private StageLaunchStatsHtml(@Nonnull final StageLaunchStatsHtmlBuilder builder) {
this.displayName = builder.displayName;
this.titleName = builder.titleName;
this.matcherNames = builder.matcherNames;
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/StatsHtml.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/StatsHtml.java
index 459b6fac..587e40a2 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/StatsHtml.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/StatsHtml.java
@@ -1,8 +1,8 @@
package com.github.nagyesta.abortmission.reporting.html;
import lombok.Data;
-import org.springframework.lang.NonNull;
+import javax.annotation.Nonnull;
import java.time.LocalDateTime;
import java.util.Optional;
@@ -25,7 +25,7 @@ public final class StatsHtml {
private int abort;
private int suppressed;
- private StatsHtml(@NonNull final StatsHtmlBuilder builder) {
+ private StatsHtml(@Nonnull final StatsHtmlBuilder builder) {
this.minStart = builder.minStart;
this.maxEnd = builder.maxEnd;
this.worstResult = builder.worstResult;
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/ClassJsonToHtmlConverter.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/ClassJsonToHtmlConverter.java
index 023d19e0..6143b5d4 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/ClassJsonToHtmlConverter.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/ClassJsonToHtmlConverter.java
@@ -3,11 +3,8 @@
import com.github.nagyesta.abortmission.reporting.html.ClassHtml;
import com.github.nagyesta.abortmission.reporting.html.StageLaunchStatsHtml;
import com.github.nagyesta.abortmission.reporting.json.ClassJson;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Component;
+import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
@@ -16,15 +13,13 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-@Component
-public class ClassJsonToHtmlConverter implements Converter {
+public class ClassJsonToHtmlConverter implements Function {
private static final String TEST_METHOD_REGEX = "^test(?[a-zA-Z0-9]+)Should(?[a-zA-Z0-9]+)When(?[a-zA-Z0-9]+)$";
private final StatsJsonToHtmlConverter statsConverter;
private final StageLaunchStatsJsonToHtmlConverter stageConverter;
- @Autowired
public ClassJsonToHtmlConverter(final StatsJsonToHtmlConverter statsConverter,
final StageLaunchStatsJsonToHtmlConverter stageConverter) {
this.statsConverter = statsConverter;
@@ -32,13 +27,13 @@ public ClassJsonToHtmlConverter(final StatsJsonToHtmlConverter statsConverter,
}
@Override
- public ClassHtml convert(@NonNull final ClassJson source) {
+ public ClassHtml apply(@Nonnull final ClassJson source) {
final Map launchMap = convertLaunchMap(source);
return ClassHtml.builder(source.getClassName())
.countdown(Optional.ofNullable(source.getCountdown())
- .map(c -> stageConverter.convert(Function.identity(), "Countdown", c))
+ .map(c -> stageConverter.apply(Function.identity(), "Countdown", c))
.orElse(null))
- .stats(statsConverter.convert(source.getStats()))
+ .stats(statsConverter.apply(source.getStats()))
.launches(launchMap)
.build();
}
@@ -49,7 +44,7 @@ public ClassHtml convert(@NonNull final ClassJson source) {
* @param s The name of the test method.
* @return The tooltip
*/
- protected String convertTestMethod(@NonNull final String s) {
+ protected String convertTestMethod(@Nonnull final String s) {
final Pattern pattern = Pattern.compile(TEST_METHOD_REGEX);
final Matcher matcher = pattern.matcher(s);
if (!matcher.matches()) {
@@ -65,7 +60,7 @@ private Map convertLaunchMap(final ClassJson sourc
.map(Collection::stream)
.map(stream -> stream.collect(
Collectors.toMap(Map.Entry::getKey,
- e -> stageConverter.convert(this::convertTestMethod, e.getKey(), e.getValue()))))
+ e -> stageConverter.apply(this::convertTestMethod, e.getKey(), e.getValue()))))
.orElse(null);
}
}
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/LaunchJsonToHtmlConverter.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/LaunchJsonToHtmlConverter.java
index c344c500..8c246cd7 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/LaunchJsonToHtmlConverter.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/LaunchJsonToHtmlConverter.java
@@ -4,25 +4,21 @@
import com.github.nagyesta.abortmission.reporting.html.StageResultHtml;
import com.github.nagyesta.abortmission.reporting.html.StatsHtml;
import com.github.nagyesta.abortmission.reporting.json.LaunchJson;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
+import com.github.nagyesta.abortmission.reporting.json.StatsJson;
+import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.TreeSet;
+import java.util.function.Function;
import java.util.stream.Collectors;
-@Component
-public class LaunchJsonToHtmlConverter implements Converter {
+public class LaunchJsonToHtmlConverter implements Function {
private final StatsJsonToHtmlConverter statsConverter;
private final ClassJsonToHtmlConverter classConverter;
- @Autowired
public LaunchJsonToHtmlConverter(final StatsJsonToHtmlConverter statsConverter,
final ClassJsonToHtmlConverter classConverter) {
this.statsConverter = statsConverter;
@@ -30,20 +26,24 @@ public LaunchJsonToHtmlConverter(final StatsJsonToHtmlConverter statsConverter,
}
@Override
- public LaunchHtml convert(@NonNull final LaunchJson source) {
- Assert.notNull(source.getStats(), "Stats cannot be null.");
+ public LaunchHtml apply(@Nonnull final LaunchJson source) {
+ final StatsJson stats = source.getStats();
+ if (stats == null) {
+ throw new IllegalArgumentException("Stats cannot be null for launch.");
+ }
final StatsHtml emptyStats = StatsHtml.builder()
.worstResult(StageResultHtml.SUPPRESSED)
.build();
return LaunchHtml.builder()
- .stats(statsConverter.convert(source.getStats()))
+ .stats(statsConverter.apply(stats))
.classes(Optional.ofNullable(source.getClasses())
.map(Map::values)
.map(Collection::stream)
- .map(s -> s.map(classConverter::convert).collect(Collectors.toCollection(TreeSet::new)))
+ .map(s -> s.map(classConverter).collect(Collectors.toCollection(TreeSet::new)))
.orElse(new TreeSet<>()))
- .countdownStats(Optional.ofNullable(source.getCountdownStats()).map(statsConverter::convert).orElse(emptyStats))
- .missionStats(Optional.ofNullable(source.getMissionStats()).map(statsConverter::convert).orElse(emptyStats))
+ .countdownStats(Optional.ofNullable(source.getCountdownStats()).map(statsConverter).orElse(emptyStats))
+ .missionStats(Optional.ofNullable(source.getMissionStats()).map(statsConverter).orElse(emptyStats))
.build();
}
+
}
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/StageLaunchStatsJsonToHtmlConverter.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/StageLaunchStatsJsonToHtmlConverter.java
index 829f567f..17407f25 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/StageLaunchStatsJsonToHtmlConverter.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/StageLaunchStatsJsonToHtmlConverter.java
@@ -3,21 +3,17 @@
import com.github.nagyesta.abortmission.reporting.html.LaunchHtml;
import com.github.nagyesta.abortmission.reporting.html.StageLaunchStatsHtml;
import com.github.nagyesta.abortmission.reporting.json.StageLaunchStatsJson;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
+import com.github.nagyesta.abortmission.reporting.json.StatsJson;
+import javax.annotation.Nonnull;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
-@Component
public class StageLaunchStatsJsonToHtmlConverter {
private final StatsJsonToHtmlConverter statsConverter;
- @Autowired
public StageLaunchStatsJsonToHtmlConverter(final StatsJsonToHtmlConverter statsConverter) {
this.statsConverter = statsConverter;
}
@@ -31,17 +27,21 @@ public StageLaunchStatsJsonToHtmlConverter(final StatsJsonToHtmlConverter statsC
* @param source The source object we want to convert.
* @return The converted object
*/
- public StageLaunchStatsHtml convert(@NonNull final Function titleConverter,
- @NonNull final String name,
- @NonNull final StageLaunchStatsJson source) {
- Assert.notNull(source.getStats(), "Stats cannot be null.");
+ public StageLaunchStatsHtml apply(@Nonnull final Function titleConverter,
+ @Nonnull final String name,
+ @Nonnull final StageLaunchStatsJson source) {
+ final StatsJson stats = source.getStats();
+ if (stats == null) {
+ throw new IllegalArgumentException("Stats cannot be null for stage.");
+ }
final Map map = Optional.ofNullable(source.getMatcherNames())
.map(Collection::stream)
.map(s -> s.collect(Collectors.toMap(Function.identity(), LaunchHtml::shortHash)))
.orElse(Collections.emptyMap());
- return StageLaunchStatsHtml.builder(name, statsConverter.convert(source.getStats()))
+ return StageLaunchStatsHtml.builder(name, statsConverter.apply(stats))
.matcherNames(new TreeMap<>(map))
.titleName(titleConverter.apply(name))
.build();
}
+
}
diff --git a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/StatsJsonToHtmlConverter.java b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/StatsJsonToHtmlConverter.java
index 0071d4f9..6f71f613 100644
--- a/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/StatsJsonToHtmlConverter.java
+++ b/mission-report/flight-evaluation-report/src/main/java/com/github/nagyesta/abortmission/reporting/html/converter/StatsJsonToHtmlConverter.java
@@ -4,17 +4,15 @@
import com.github.nagyesta.abortmission.reporting.html.StatsHtml;
import com.github.nagyesta.abortmission.reporting.json.StageResultJson;
import com.github.nagyesta.abortmission.reporting.json.StatsJson;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Component;
+import javax.annotation.Nonnull;
import java.util.Optional;
+import java.util.function.Function;
-@Component
-public class StatsJsonToHtmlConverter implements Converter {
+public class StatsJsonToHtmlConverter implements Function {
@Override
- public StatsHtml convert(@NonNull final StatsJson source) {
+ public StatsHtml apply(@Nonnull final StatsJson source) {
return StatsHtml.builder()
.minStart(source.getMinStart())
.maxEnd(source.getMaxEnd())
diff --git a/mission-report/flight-evaluation-report/src/main/java/org/springframework/boot/loader/JarLauncher.java b/mission-report/flight-evaluation-report/src/main/java/org/springframework/boot/loader/JarLauncher.java
new file mode 100644
index 00000000..216dbfbf
--- /dev/null
+++ b/mission-report/flight-evaluation-report/src/main/java/org/springframework/boot/loader/JarLauncher.java
@@ -0,0 +1,17 @@
+package org.springframework.boot.loader;
+
+import com.github.nagyesta.abortmission.reporting.AbortMissionFlightEvaluationReportApp;
+import lombok.extern.slf4j.Slf4j;
+
+@SuppressWarnings("checkstyle:HideUtilityClassConstructor")
+@Slf4j
+@Deprecated
+public class JarLauncher {
+
+ @Deprecated
+ public static void main(final String[] args) {
+ log.error("This is the legacy launcher. "
+ + "Please use 'com.github.nagyesta.abortmission.reporting.AbortMissionFlightEvaluationReportApp' instead!");
+ AbortMissionFlightEvaluationReportApp.main(args);
+ }
+}
diff --git a/mission-report/flight-evaluation-report/src/main/resources/application.properties b/mission-report/flight-evaluation-report/src/main/resources/application.properties
deleted file mode 100644
index ea7a7147..00000000
--- a/mission-report/flight-evaluation-report/src/main/resources/application.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Spring
-#
-spring.main.banner-mode=off
-#
-# Thymeleaf
-#
-spring.thymeleaf.prefix=classpath:/templates/
-spring.thymeleaf.suffix=.html
-#
-# Logging
-#
-logging.level.root=WARN
-logging.level.org.springframework=WARN
-logging.level.com.networknt.schema=WARN
-# suppress inspection "UnusedMessageFormatParameter"
-logging.exception-conversion-word=%ex{2}
-logging.pattern.level=%5p
-logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(\${logging.pattern.level}) %clr(%-40.40logger{29}){cyan} %clr(:){faint} %m%n\${logging.exception-conversion-word}
-#
-# App
-#
-# suppress inspection "SpringBootApplicationProperties"
-report.relaxed=false
diff --git a/mission-report/flight-evaluation-report/src/main/resources/logback.xml b/mission-report/flight-evaluation-report/src/main/resources/logback.xml
new file mode 100644
index 00000000..2f79e593
--- /dev/null
+++ b/mission-report/flight-evaluation-report/src/main/resources/logback.xml
@@ -0,0 +1,11 @@
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %-50.50logger{29} : %m%n%ex{2}
+
+
+
+
+
+
+
diff --git a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/AbortMissionFlightEvaluationReportAppIntegrationTest.java b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/AbortMissionFlightEvaluationReportAppIntegrationTest.java
index 48076760..5f89b4dd 100644
--- a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/AbortMissionFlightEvaluationReportAppIntegrationTest.java
+++ b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/AbortMissionFlightEvaluationReportAppIntegrationTest.java
@@ -1,23 +1,56 @@
package com.github.nagyesta.abortmission.reporting;
+import com.github.nagyesta.abortmission.reporting.config.ConversionProperties;
+import com.github.nagyesta.abortmission.reporting.exception.RenderException;
import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.*;
-@SpringBootTest
class AbortMissionFlightEvaluationReportAppIntegrationTest {
- @Autowired
- private AbortMissionFlightEvaluationReportApp app;
+ @Test
+ public void testApplicationContextShouldConfigureSuccessfullyWhenCalled() throws IOException {
+ //given
+ final AbortMissionFlightEvaluationReportApp app = new AbortMissionFlightEvaluationReportApp();
+ //noinspection ConstantConditions
+ final String input = getClass().getResource("/abort-mission-report.json").getFile();
+ final File output = File.createTempFile("abort-mission-out", ".html");
+ output.deleteOnExit();
+ final List args = List.of("--report.input=" + input, "--report.output=" + output);
+
+ //when
+ final AbortMissionAppContext actual = app.bootstrap(args);
+
+ //then
+ assertNotNull(actual);
+ }
@Test
- void testApplicationContextShouldConfigureSuccessfullyWhenCalled() {
- //given test instance created
- //when injected
+ public void testApplicationContextShouldExitWithErrorWhenExecutionFails() throws IOException {
+ //given
+ final AbortMissionFlightEvaluationReportApp app = new AbortMissionFlightEvaluationReportApp();
+ //noinspection ConstantConditions
+ final File input = new File(getClass().getResource("/abort-mission-report.json").getFile());
+ final File output = File.createTempFile("abort-mission-out", ".html");
+ output.deleteOnExit();
+ final ConversionProperties properties = ConversionProperties.builder()
+ .input(input)
+ .output(output)
+ .build();
+ final AbortMissionAppContext context = spy(new AbortMissionAppContext(properties));
+ doNothing().when(context).exitWithError();
+ doThrow(new RenderException()).when(context).controller();
+
+ //when
+ app.execute(context);
//then
- assertNotNull(app);
+ verify(context).controller();
+ verify(context).exitWithError();
}
}
diff --git a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/config/ConversionPropertiesTest.java b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/config/ConversionPropertiesTest.java
new file mode 100644
index 00000000..90c73ad5
--- /dev/null
+++ b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/config/ConversionPropertiesTest.java
@@ -0,0 +1,36 @@
+package com.github.nagyesta.abortmission.reporting.config;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+
+class ConversionPropertiesTest {
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ @Test
+ void testConstructorShouldThrowExceptionWhenInputIsnull() {
+ //given
+ final ConversionProperties.ConversionPropertiesBuilder builder = ConversionProperties.builder()
+ .output(new File("out.html"));
+
+ //when
+ //noinspection Convert2MethodRef
+ Assertions.assertThrows(IllegalArgumentException.class, () -> builder.build());
+
+ //then + exception
+ }
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ @Test
+ void testConstructorShouldThrowExceptionWhenOutputIsnull() {
+ //given
+ final ConversionProperties.ConversionPropertiesBuilder builder = ConversionProperties.builder()
+ .input(new File("in.json"));
+
+ //when
+ Assertions.assertThrows(IllegalArgumentException.class, builder::build);
+
+ //then + exception
+ }
+}
diff --git a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/controller/ConversionControllerIntegrationTest.java b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/controller/ConversionControllerIntegrationTest.java
index e594e499..fdfdb7b5 100644
--- a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/controller/ConversionControllerIntegrationTest.java
+++ b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/controller/ConversionControllerIntegrationTest.java
@@ -3,14 +3,15 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.nagyesta.abortmission.reporting.config.ConversionProperties;
import com.github.nagyesta.abortmission.reporting.exception.RenderException;
+import com.github.nagyesta.abortmission.reporting.html.converter.ClassJsonToHtmlConverter;
import com.github.nagyesta.abortmission.reporting.html.converter.LaunchJsonToHtmlConverter;
+import com.github.nagyesta.abortmission.reporting.html.converter.StageLaunchStatsJsonToHtmlConverter;
+import com.github.nagyesta.abortmission.reporting.html.converter.StatsJsonToHtmlConverter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.thymeleaf.spring5.SpringTemplateEngine;
+import org.thymeleaf.TemplateEngine;
import java.io.File;
import java.nio.charset.StandardCharsets;
@@ -21,14 +22,20 @@
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
-@SpringBootTest
class ConversionControllerIntegrationTest {
- @Autowired
- private ObjectMapper objectMapper;
- @Autowired
- private LaunchJsonToHtmlConverter converter;
- @Autowired
- private SpringTemplateEngine templateEngine;
+
+ private final ObjectMapper objectMapper;
+ private final LaunchJsonToHtmlConverter launchConverter;
+ private final TemplateEngine templateEngine;
+
+ ConversionControllerIntegrationTest() {
+ final StatsJsonToHtmlConverter statsConverter = new StatsJsonToHtmlConverter();
+ final StageLaunchStatsJsonToHtmlConverter stageConverter = new StageLaunchStatsJsonToHtmlConverter(statsConverter);
+ final ClassJsonToHtmlConverter classConverter = new ClassJsonToHtmlConverter(statsConverter, stageConverter);
+ templateEngine = new TemplateEngine();
+ launchConverter = new LaunchJsonToHtmlConverter(statsConverter, classConverter);
+ objectMapper = new ObjectMapper();
+ }
private static Stream validInputSource() {
return Stream.builder()
@@ -48,15 +55,16 @@ void testConvertShouldConvertAndRenderDataWhenCalledWithValidJson(final String j
//given
final File inputFile = new File(this.getClass().getResource(jsonResource).getFile());
final File expectedFile = new File(this.getClass().getResource(expectedHtml).getFile());
- final ConversionProperties properties = new ConversionProperties();
- properties.setInput(inputFile);
- properties.setOutput(File.createTempFile("abort-mission-test", ".html"));
- properties.setRelaxed(relaxed);
- properties.setFailOnError(failOnError);
+ final ConversionProperties properties = ConversionProperties.builder()
+ .input(inputFile)
+ .output(File.createTempFile("abort-mission-test", ".html"))
+ .relaxed(relaxed)
+ .failOnError(failOnError)
+ .build();
properties.getOutput().deleteOnExit();
- final ConversionController underTest = new ConversionController(properties, objectMapper, converter, templateEngine);
+ final ConversionController underTest = new ConversionController(properties, objectMapper, launchConverter, templateEngine);
//when
if (failOnError) {
@@ -75,14 +83,15 @@ void testConvertShouldConvertAndRenderDataWhenCalledWithValidJson(final String j
void testConvertShouldThrowExceptionWhenCalledWithInvalidJson() throws Exception {
//given
final File inputFile = new File(this.getClass().getResource("/schema/abort-mission-telemetry-relaxed.json").getFile());
- final ConversionProperties properties = new ConversionProperties();
- properties.setInput(inputFile);
- properties.setOutput(File.createTempFile("abort-mission-test", ".html"));
- properties.setRelaxed(false);
+ final ConversionProperties properties = ConversionProperties.builder()
+ .input(inputFile)
+ .output(File.createTempFile("abort-mission-test", ".html"))
+ .relaxed(false)
+ .build();
properties.getOutput().deleteOnExit();
- final ConversionController underTest = new ConversionController(properties, objectMapper, converter, templateEngine);
+ final ConversionController underTest = new ConversionController(properties, objectMapper, launchConverter, templateEngine);
//when
assertThrows(RuntimeException.class, underTest::convert);
diff --git a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/ClassJsonToHtmlConverterTest.java b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/ClassJsonToHtmlConverterTest.java
index f7bd5f56..7d34ff10 100644
--- a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/ClassJsonToHtmlConverterTest.java
+++ b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/ClassJsonToHtmlConverterTest.java
@@ -69,24 +69,24 @@ private static Stream methodNameProvider() {
void testConvertShouldConvertNonNullValuesWhenCalled(final ClassJson input, final ClassHtml expected) {
//given
final StatsJsonToHtmlConverter statsConverter = mock(StatsJsonToHtmlConverter.class);
- when(statsConverter.convert(notNull())).thenReturn(expected.getStats());
- when(statsConverter.convert(isNull())).thenThrow(new NullPointerException());
+ when(statsConverter.apply(notNull())).thenReturn(expected.getStats());
+ when(statsConverter.apply(isNull())).thenThrow(new NullPointerException());
final StageLaunchStatsJsonToHtmlConverter stageConverter = mock(StageLaunchStatsJsonToHtmlConverter.class);
- when(stageConverter.convert(any(), eq(COUNTDOWN), notNull())).thenReturn(expected.getCountdown());
- when(stageConverter.convert(any(), anyString(), isNull())).thenThrow(new NullPointerException());
+ when(stageConverter.apply(any(), eq(COUNTDOWN), notNull())).thenReturn(expected.getCountdown());
+ when(stageConverter.apply(any(), anyString(), isNull())).thenThrow(new NullPointerException());
final Optional optionalLaunch = Optional.ofNullable(expected.getLaunches())
.map(Map::values)
.map(Collection::stream)
.flatMap(Stream::findFirst);
optionalLaunch.ifPresent(o ->
- when(stageConverter.convert(any(), eq(METHOD_NAME), any(StageLaunchStatsJson.class)))
+ when(stageConverter.apply(any(), eq(METHOD_NAME), any(StageLaunchStatsJson.class)))
.thenReturn(o));
final ClassJsonToHtmlConverter underTest = new ClassJsonToHtmlConverter(statsConverter, stageConverter);
//when
- final ClassHtml actual = underTest.convert(input);
+ final ClassHtml actual = underTest.apply(input);
//then
assertNotNull(actual);
@@ -96,12 +96,12 @@ void testConvertShouldConvertNonNullValuesWhenCalled(final ClassJson input, fina
if (expected.getLaunches() != null) {
expected.getLaunches().forEach((k, v) -> {
assertSame(v, actual.getLaunches().get(k));
- verify(stageConverter).convert(any(), eq(METHOD_NAME), same(input.getLaunches().get(k)));
+ verify(stageConverter).apply(any(), eq(METHOD_NAME), same(input.getLaunches().get(k)));
});
}
- verify(statsConverter).convert(eq(input.getStats()));
+ verify(statsConverter).apply(eq(input.getStats()));
if (input.getCountdown() != null) {
- verify(stageConverter).convert(any(), eq(COUNTDOWN), same(input.getCountdown()));
+ verify(stageConverter).apply(any(), eq(COUNTDOWN), same(input.getCountdown()));
}
}
diff --git a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/LaunchJsonToHtmlConverterTest.java b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/LaunchJsonToHtmlConverterTest.java
index bcbad95a..651e46fb 100644
--- a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/LaunchJsonToHtmlConverterTest.java
+++ b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/LaunchJsonToHtmlConverterTest.java
@@ -7,6 +7,8 @@
import com.github.nagyesta.abortmission.reporting.json.ClassJson;
import com.github.nagyesta.abortmission.reporting.json.LaunchJson;
import com.github.nagyesta.abortmission.reporting.json.StatsJson;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -63,24 +65,24 @@ private static LaunchJson json(final Map classes) {
void testConvertShouldConvertNonNullValuesWhenCalled(final LaunchJson input, final LaunchHtml expected) {
//given
final StatsJsonToHtmlConverter statsConverter = mock(StatsJsonToHtmlConverter.class);
- when(statsConverter.convert(same(input.getStats()))).thenReturn(expected.getStats());
+ when(statsConverter.apply(same(input.getStats()))).thenReturn(expected.getStats());
if (input.getCountdownStats() != null) {
- when(statsConverter.convert(same(input.getCountdownStats()))).thenReturn(expected.getCountdownStats());
+ when(statsConverter.apply(same(input.getCountdownStats()))).thenReturn(expected.getCountdownStats());
}
if (input.getMissionStats() != null) {
- when(statsConverter.convert(same(input.getMissionStats()))).thenReturn(expected.getMissionStats());
+ when(statsConverter.apply(same(input.getMissionStats()))).thenReturn(expected.getMissionStats());
}
- when(statsConverter.convert(isNull())).thenThrow(NullPointerException.class);
+ when(statsConverter.apply(isNull())).thenThrow(NullPointerException.class);
final ClassJsonToHtmlConverter classConverter = mock(ClassJsonToHtmlConverter.class);
if (expected.getClasses() != null && !expected.getClasses().isEmpty()) {
- when(classConverter.convert(notNull())).thenReturn(expected.getClasses().first());
+ when(classConverter.apply(notNull())).thenReturn(expected.getClasses().first());
}
- when(classConverter.convert(isNull())).thenThrow(NullPointerException.class);
+ when(classConverter.apply(isNull())).thenThrow(NullPointerException.class);
final LaunchJsonToHtmlConverter underTest = new LaunchJsonToHtmlConverter(statsConverter, classConverter);
//when
- final LaunchHtml actual = underTest.convert(input);
+ final LaunchHtml actual = underTest.apply(input);
//then
assertNotNull(actual);
@@ -88,18 +90,33 @@ void testConvertShouldConvertNonNullValuesWhenCalled(final LaunchJson input, fin
assertSame(expected.getStats(), actual.getStats());
if (expected.getClasses() != null && !expected.getClasses().isEmpty()) {
assertSame(expected.getClasses().first(), actual.getClasses().first());
- verify(classConverter).convert(same(input.getClasses().get(CLASS_NAME)));
+ verify(classConverter).apply(same(input.getClasses().get(CLASS_NAME)));
}
- verify(statsConverter).convert(same(input.getStats()));
+ verify(statsConverter).apply(same(input.getStats()));
if (input.getCountdownStats() != null) {
assertSame(expected.getCountdownStats(), actual.getCountdownStats());
- verify(statsConverter).convert(same(input.getCountdownStats()));
+ verify(statsConverter).apply(same(input.getCountdownStats()));
}
if (input.getMissionStats() != null) {
assertSame(expected.getMissionStats(), actual.getMissionStats());
- verify(statsConverter).convert(same(input.getMissionStats()));
+ verify(statsConverter).apply(same(input.getMissionStats()));
}
- verify(statsConverter).convert(same(input.getStats()));
+ verify(statsConverter).apply(same(input.getStats()));
+ }
+
+ @Test
+ void testConvertShouldThrowExceptionWhenCalledWithNullStats() {
+ //given
+ final LaunchJson input = new LaunchJson();
+ final StatsJsonToHtmlConverter statsConverter = mock(StatsJsonToHtmlConverter.class);
+ final ClassJsonToHtmlConverter classConverter = mock(ClassJsonToHtmlConverter.class);
+
+ final LaunchJsonToHtmlConverter underTest = new LaunchJsonToHtmlConverter(statsConverter, classConverter);
+
+ //when
+ Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.apply(input));
+ //then + exception
+ verifyNoInteractions(statsConverter, classConverter);
}
}
diff --git a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/StageLaunchStatsJsonToHtmlConverterTest.java b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/StageLaunchStatsJsonToHtmlConverterTest.java
index a1e48c6d..99bfbd61 100644
--- a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/StageLaunchStatsJsonToHtmlConverterTest.java
+++ b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/StageLaunchStatsJsonToHtmlConverterTest.java
@@ -5,6 +5,8 @@
import com.github.nagyesta.abortmission.reporting.html.StatsHtml;
import com.github.nagyesta.abortmission.reporting.json.StageLaunchStatsJson;
import com.github.nagyesta.abortmission.reporting.json.StatsJson;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -12,6 +14,7 @@
import java.util.Collections;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.function.Function;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
@@ -45,19 +48,33 @@ private static Stream validInputProvider() {
void testConvertShouldConvertNonNullValuesWhenCalled(final StageLaunchStatsJson input, final StageLaunchStatsHtml expected) {
//given
final StatsJsonToHtmlConverter statsConverter = mock(StatsJsonToHtmlConverter.class);
- when(statsConverter.convert(notNull())).thenReturn(expected.getStats());
- when(statsConverter.convert(isNull())).thenThrow(new NullPointerException());
+ when(statsConverter.apply(notNull())).thenReturn(expected.getStats());
+ when(statsConverter.apply(isNull())).thenThrow(new NullPointerException());
final StageLaunchStatsJsonToHtmlConverter underTest = new StageLaunchStatsJsonToHtmlConverter(statsConverter);
//when
- final StageLaunchStatsHtml actual = underTest.convert(String::toLowerCase, METHOD_NAME, input);
+ final StageLaunchStatsHtml actual = underTest.apply(String::toLowerCase, METHOD_NAME, input);
//then
assertNotNull(actual);
assertEquals(expected, actual);
assertSame(expected.getStats(), actual.getStats());
- verify(statsConverter).convert(same(input.getStats()));
+ verify(statsConverter).apply(same(input.getStats()));
+ }
+
+ @Test
+ void testConvertShouldThrowExceptionWhenCalledWithNullStats() {
+ //given
+ final StageLaunchStatsJson input = new StageLaunchStatsJson();
+ final StatsJsonToHtmlConverter statsConverter = mock(StatsJsonToHtmlConverter.class);
+
+ final StageLaunchStatsJsonToHtmlConverter underTest = new StageLaunchStatsJsonToHtmlConverter(statsConverter);
+
+ //when
+ Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.apply(Function.identity(), "name", input));
+ //then + exception
+ verifyNoInteractions(statsConverter);
}
}
diff --git a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/StatsJsonToHtmlConverterTest.java b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/StatsJsonToHtmlConverterTest.java
index 1d7e666e..77b2b660 100644
--- a/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/StatsJsonToHtmlConverterTest.java
+++ b/mission-report/flight-evaluation-report/src/test/java/com/github/nagyesta/abortmission/reporting/html/converter/StatsJsonToHtmlConverterTest.java
@@ -81,7 +81,7 @@ void testConvertShouldConvertNonNullValuesWhenCalled(final StatsJson input, fina
final StatsJsonToHtmlConverter underTest = new StatsJsonToHtmlConverter();
//when
- final StatsHtml actual = underTest.convert(input);
+ final StatsHtml actual = underTest.apply(input);
//then
assertNotNull(actual);