From ae3bea917d9df6aa0e76065daf02e814d9d2d37f Mon Sep 17 00:00:00 2001 From: l-1squared <30831153+l-1squared@users.noreply.github.com> Date: Tue, 13 Feb 2024 07:30:27 +0100 Subject: [PATCH] Issue-1527: implement changes from jjohannes these have been detailed https://github.com/jjohannes/JGiven/commit/cc3f67a7b4b39f9f78599c2cea18c42c95870c73 and authority to use these has been explicitly granted https://github.com/TNG/JGiven/issues/1527#issuecomment-1938519442 Signed-off-by: l-1squared <30831153+l-1squared@users.noreply.github.com> --- .../tngtech/jgiven/gradle/JGivenPlugin.java | 67 ++++++++++--------- .../jgiven/gradle/JGivenReportTask.java | 19 ++---- .../jgiven/gradle/JGivenTaskExtension.java | 6 +- .../internal/JGivenReportsContainerImpl.java | 3 + .../JGivenPluginShould.groovy | 2 +- .../jgiven/gradle/JGivenPluginTest.java | 4 +- .../report/html5/Html5ReportGenerator.java | 2 +- 7 files changed, 53 insertions(+), 50 deletions(-) diff --git a/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenPlugin.java b/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenPlugin.java index 2b22d9d9ab4..57b8c893597 100644 --- a/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenPlugin.java +++ b/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenPlugin.java @@ -4,19 +4,24 @@ import com.tngtech.jgiven.impl.Config; import com.tngtech.jgiven.impl.util.WordUtil; import org.gradle.api.*; -import org.gradle.api.internal.ConventionMapping; -import org.gradle.api.internal.IConventionAware; +import org.gradle.api.file.Directory; +import org.gradle.api.model.ObjectFactory; import org.gradle.api.plugins.ReportingBasePlugin; +import org.gradle.api.provider.Provider; import org.gradle.api.reporting.Report; import org.gradle.api.reporting.ReportingExtension; import org.gradle.api.tasks.testing.Test; -import java.io.File; +import javax.inject.Inject; import java.util.Objects; -import java.util.concurrent.Callable; +@SuppressWarnings("unused") @NonNullApi -public class JGivenPlugin implements Plugin { +public abstract class JGivenPlugin implements Plugin { + + @Inject + protected abstract ObjectFactory getObjects(); + @Override public void apply(final Project project) { project.getPluginManager().apply(ReportingBasePlugin.class); @@ -33,13 +38,16 @@ private void addTaskExtension(Project project) { private void applyTo(Test test) { final String testName = test.getName(); final Project project = test.getProject(); - final JGivenTaskExtension extension = project.getObjects().newInstance(JGivenTaskExtension.class); + final JGivenTaskExtension extension = getObjects().newInstance(JGivenTaskExtension.class); + //having this brakes the "test is cacheable" test while not checking whether the extension is configured breaks the "no test no output" test. + //also the groovy tests might be ill-configured, because it is not exactly clear to me, why these get away with not ordering a jgiven report. test.getExtensions().add("jgiven", extension); - ((IConventionAware) extension).getConventionMapping().map("resultsDir", - (Callable) () -> project.file(project.getBuildDir() + "/jgiven-results/" + testName)); - - File resultsDir = extension.getResultsDir().get(); - test.getOutputs().dir(resultsDir).withPropertyName("jgiven.resultsDir"); + var isConfigured = extension.getResultsDir().isPresent(); + extension.getResultsDir().convention(project.getLayout().getBuildDirectory().dir("jgiven-results/" + testName)); + Provider resultsDir = extension.getResultsDir(); + if (isConfigured) { + test.getOutputs().dir(resultsDir).withPropertyName("jgiven.resultsDir"); + } /* Java lambda classes are created at runtime with a non-deterministic classname. * Therefore, the class name does not identify the implementation of the lambda, @@ -47,25 +55,25 @@ private void applyTo(Test test) { * See: https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:how_does_it_work */ //noinspection Convert2Lambda - test.prependParallelSafeAction(new Action<>() { + test.doFirst(new Action<>() { @Override public void execute(Task task) { - ((Test) task).systemProperty(Config.JGIVEN_REPORT_DIR, extension.getResultsDir().get().getAbsolutePath()); + ((Test) task).systemProperty(Config.JGIVEN_REPORT_DIR, extension.getResultsDir().get().getAsFile().getAbsolutePath()); } }); } private void configureJGivenReportDefaults(Project project) { project.getTasks() - .withType(JGivenReportTask.class).forEach(reportTask -> - reportTask.getReports().all((Action) report -> - report.getRequired().convention(report.getName().equals(JGivenHtmlReportImpl.NAME)) - )); + .withType(JGivenReportTask.class).forEach(reportTask -> + reportTask.getReports().all((Action) report -> + report.getRequired().convention(report.getName().equals(JGivenHtmlReportImpl.NAME)) + )); } private void addDefaultReports(final Project project) { final ReportingExtension reportingExtension = Objects.requireNonNull( - project.getExtensions().findByType(ReportingExtension.class)); + project.getExtensions().findByType(ReportingExtension.class)); project.getTasks().withType(Test.class).forEach(test -> project.getTasks() .register("jgiven" + WordUtil.capitalize(test.getName()) + "Report", JGivenReportTask.class) @@ -77,18 +85,15 @@ private void configureDefaultReportTask(final Test test, JGivenReportTask report final ReportingExtension reportingExtension) { reportTask.mustRunAfter(test); - ConventionMapping mapping = ((IConventionAware) reportTask).getConventionMapping(); - Callable getResultsDirectory = () -> test.getExtensions() - .getByType(JGivenTaskExtension.class) - .getResultsDir().get(); - mapping.map("results", getResultsDirectory); - - Objects.requireNonNull(mapping.getConventionValue(reportTask.getReports(), "reports", false)) - .all(report -> { - ConventionMapping reportMapping = ((IConventionAware) report).getConventionMapping(); - String relativeFilePath = "jgiven" + "/" + test.getName() + "/" + report.getName(); - Callable getDestination = () -> reportingExtension.file(relativeFilePath); - reportMapping.map("destination", getDestination); - }); + Provider getResultsDirectory = test.getExtensions() + .getByType(JGivenTaskExtension.class) + .getResultsDir(); + + reportTask.getResults().set(getResultsDirectory); + + reportTask.getReports().configureEach(report -> { + String relativeFilePath = "jgiven" + "/" + test.getName() + "/" + report.getName(); + report.getOutputLocation().set(reportingExtension.getBaseDirectory().dir(relativeFilePath)); + }); } } diff --git a/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenReportTask.java b/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenReportTask.java index e831b9dfb20..c426b176be5 100644 --- a/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenReportTask.java +++ b/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenReportTask.java @@ -8,6 +8,8 @@ import org.gradle.api.Action; import org.gradle.api.DefaultTask; import org.gradle.api.NonNullApi; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.model.ObjectFactory; import org.gradle.api.reporting.Reporting; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.InputDirectory; @@ -20,29 +22,22 @@ @CacheableTask @NonNullApi -public class JGivenReportTask extends DefaultTask implements Reporting { +public abstract class JGivenReportTask extends DefaultTask implements Reporting { private final JGivenReportsContainer reports; - private File results; public JGivenReportTask() { - reports = getInstantiator().newInstance(JGivenReportsContainerImpl.class, this); + reports = getObjects().newInstance(JGivenReportsContainerImpl.class, this); } @Inject - protected Instantiator getInstantiator() { + protected ObjectFactory getObjects() { throw new UnsupportedOperationException(); } @InputDirectory @SkipWhenEmpty @PathSensitive(PathSensitivity.NONE) - public File getResults() { - return results; - } - - public void setResults(File results) { - this.results = results; - } + public abstract DirectoryProperty getResults(); @TaskAction public void generate() { @@ -53,7 +48,7 @@ public void generate() { private void generateReport(JGivenReport report) { AbstractReportGenerator generator = report.createGenerator(); - generator.config.setSourceDir(getResults()); + generator.config.setSourceDir(getResults().get().getAsFile()); generator.loadReportModel(); try { generator.generate(); diff --git a/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenTaskExtension.java b/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenTaskExtension.java index 7d167941f48..11387c8d440 100644 --- a/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenTaskExtension.java +++ b/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/JGivenTaskExtension.java @@ -1,10 +1,8 @@ package com.tngtech.jgiven.gradle; -import org.gradle.api.provider.Property; - -import java.io.File; +import org.gradle.api.file.DirectoryProperty; public interface JGivenTaskExtension { - Property getResultsDir(); + DirectoryProperty getResultsDir(); } diff --git a/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/internal/JGivenReportsContainerImpl.java b/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/internal/JGivenReportsContainerImpl.java index 5e0fd5cc1eb..1c2273c8665 100644 --- a/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/internal/JGivenReportsContainerImpl.java +++ b/jgiven-gradle-plugin/src/main/java/com/tngtech/jgiven/gradle/internal/JGivenReportsContainerImpl.java @@ -5,10 +5,13 @@ import org.gradle.api.Task; import org.gradle.api.reporting.internal.TaskReportContainer; +import javax.inject.Inject; + import static org.gradle.api.internal.CollectionCallbackActionDecorator.NOOP; public class JGivenReportsContainerImpl extends TaskReportContainer implements JGivenReportsContainer { + @Inject public JGivenReportsContainerImpl( Task task ) { super( JGivenReport.class, task, NOOP); add(JGivenHtmlReportImpl.class, task); diff --git a/jgiven-gradle-plugin/src/test/groovy/com/tngtech.jgiven.gradle/JGivenPluginShould.groovy b/jgiven-gradle-plugin/src/test/groovy/com/tngtech.jgiven.gradle/JGivenPluginShould.groovy index 907b99fb2a2..b6472cb8039 100644 --- a/jgiven-gradle-plugin/src/test/groovy/com/tngtech.jgiven.gradle/JGivenPluginShould.groovy +++ b/jgiven-gradle-plugin/src/test/groovy/com/tngtech.jgiven.gradle/JGivenPluginShould.groovy @@ -40,7 +40,7 @@ class JGivenPluginShould extends Specification { when: def result = GradleRunner.create() .withProjectDir(testProjectDir) - .withArguments("--configuration-cache", "test", "jgivenTestReport", "-S", "--info", "-Dorg.gradle.debug=true" ) + .withArguments("--configuration-cache", "test", "jgivenTestReport", "-S", "--info"/*, "-Dorg.gradle.debug=true"*/ ) .withPluginClasspath() .build() diff --git a/jgiven-gradle-plugin/src/test/java/com/tngtech/jgiven/gradle/JGivenPluginTest.java b/jgiven-gradle-plugin/src/test/java/com/tngtech/jgiven/gradle/JGivenPluginTest.java index 2e15ba46e41..a14d3443a2d 100644 --- a/jgiven-gradle-plugin/src/test/java/com/tngtech/jgiven/gradle/JGivenPluginTest.java +++ b/jgiven-gradle-plugin/src/test/java/com/tngtech/jgiven/gradle/JGivenPluginTest.java @@ -230,9 +230,11 @@ When a_build() { } When is_successful() { + var arguments = new ArrayList<>(tasks); + //arguments.add("-Dorg.gradle.debug=true"); result = GradleRunner.create() .withProjectDir(testProjectDir.get()) - .withArguments(tasks) + .withArguments(arguments) .withPluginClasspath() .build(); return self(); diff --git a/jgiven-html5-report/src/main/java/com/tngtech/jgiven/report/html5/Html5ReportGenerator.java b/jgiven-html5-report/src/main/java/com/tngtech/jgiven/report/html5/Html5ReportGenerator.java index c0caf4921b7..5509047cc50 100644 --- a/jgiven-html5-report/src/main/java/com/tngtech/jgiven/report/html5/Html5ReportGenerator.java +++ b/jgiven-html5-report/src/main/java/com/tngtech/jgiven/report/html5/Html5ReportGenerator.java @@ -66,7 +66,7 @@ public void generate() { copyCustomFile( specializedConfig.getCustomCss(), new File( specializedConfig.getTargetDir(), "css" ), "custom.css" ); copyCustomFile( specializedConfig.getCustomJs(), new File( specializedConfig.getTargetDir(), "js" ), "custom.js" ); } catch( IOException e ) { - throw Throwables.propagate( e ); + throw new RuntimeException(e); } }