From 83f15bf1f10f11b798889af9a8e82e0375c34190 Mon Sep 17 00:00:00 2001 From: Tomasz Linkowski Date: Sun, 17 Mar 2019 13:14:23 +0100 Subject: [PATCH] #72: initial refactorings/improvements necessary for further commits MAIN: 1) renamed TestModuleOptions.isRunOnClasspath() to getRunOnClasspath() (otherwise won't work with Kotlin DSL) + added a Kotlin DSL example for "runOnClasspath = true" to README.md 2) introduced JavaProjectHelper and applied it to CompileTask 3) added comments for all anonymous classes that should not be removed 4) minor improvements in ModuleSystemPlugin 5) minor fixes in test-project-kotlin/README.md TEST: 1) bumped smoke-test Gradle version to 5.0 (for improved Kotlin DSL) 2) introduced a no-op "moduleOptions" access in greeter.api (for testing DSL) 3) introduced SmokeTestHelper for ModulePluginSmokeTest 4) disabled stackTraceFilters in all tests 5) updated Kotlin to 1.3.20 --- README.md | 23 +++++- build.gradle | 1 + .../moduleplugin/JavaProjectHelper.java | 63 +++++++++++++++ .../moduleplugin/ModuleSystemPlugin.java | 29 +++---- .../tasks/CompileJavaTaskMutator.java | 5 +- .../moduleplugin/tasks/CompileTask.java | 36 +++++---- .../moduleplugin/tasks/CompileTestTask.java | 29 ++----- .../moduleplugin/tasks/JavadocTask.java | 6 +- .../moduleplugin/tasks/RunTaskMutator.java | 22 +++--- .../moduleplugin/tasks/TestModuleOptions.java | 2 +- .../moduleplugin/tasks/TestTask.java | 69 ++++++----------- .../moduleplugin/ModulePluginSmokeTest.java | 76 +++++++------------ .../moduleplugin/SmokeTestHelper.java | 56 ++++++++++++++ .../tasks/CompileJavaTaskMutatorTest.java | 4 +- test-project-kotlin/README.md | 6 +- test-project-kotlin/build.gradle.kts | 3 +- .../greeter.api/build.gradle.kts | 21 ++++- .../local_maven_build.gradle.kts | 2 +- .../smoke_test_build.gradle.kts | 2 +- test-project/build.gradle | 1 + test-project/greeter.api/build.gradle | 17 ++++- 21 files changed, 298 insertions(+), 175 deletions(-) create mode 100644 src/main/java/org/javamodularity/moduleplugin/JavaProjectHelper.java create mode 100644 src/test/java/org/javamodularity/moduleplugin/SmokeTestHelper.java diff --git a/README.md b/README.md index 8077515..256b513 100644 --- a/README.md +++ b/README.md @@ -265,7 +265,10 @@ See `src/test/java/module-info.test` and `src/test/java/greeter/ScriptingTest.ja Fall-back to classpath mode ---- -If for whatever reason this is unwanted or introduces problems, you can enable classpath mode, which essentially turns of the plugin while running tests. +If for whatever reason this is unwanted or introduces problems, you can enable classpath mode, which essentially turns off the plugin while running tests. + +
+Groovy DSL ```groovy test { @@ -275,6 +278,22 @@ test { } ``` +
+
+Kotlin DSL + +```kotlin +tasks { + test { + extensions.configure(TestModuleOptions::class) { + runOnClasspath = true + } + } +} +``` + +
+ Blackbox testing === @@ -286,7 +305,7 @@ This module `requires` and/or `uses` the module under test, and tests it's exter In the following example we test a module `greeter.provider`, which provides a service implementation of type `Greeter`. The `Greeter` type is provided by yet another module `greeter.api`. -The test module would typically be named something similar to the the module it's testing, e.g. `greeter.provider.test`. +The test module would typically be named something similar to the module it's testing, e.g. `greeter.provider.test`. In `src/main/java` it has some code that looks like code that you would normally write to use the module that's being tested. For example, we do a service lookup. diff --git a/build.gradle b/build.gradle index 1619d50..beb54fc 100644 --- a/build.gradle +++ b/build.gradle @@ -58,6 +58,7 @@ test { testLogging { events 'PASSED', 'FAILED', 'SKIPPED' + stackTraceFilters = [] } } diff --git a/src/main/java/org/javamodularity/moduleplugin/JavaProjectHelper.java b/src/main/java/org/javamodularity/moduleplugin/JavaProjectHelper.java new file mode 100644 index 0000000..0e2150f --- /dev/null +++ b/src/main/java/org/javamodularity/moduleplugin/JavaProjectHelper.java @@ -0,0 +1,63 @@ +package org.javamodularity.moduleplugin; + +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.SourceSetContainer; +import org.gradle.api.tasks.compile.JavaCompile; + +import java.util.Optional; + +/** + * Generic helper for Gradle {@link Project} API that has {@link JavaPlugin} applied. + */ +public final class JavaProjectHelper { + + private final Project project; + + public JavaProjectHelper(Project project) { + this.project = project; + } + + public Project project() { + return project; + } + + //region SOURCE SETS + public SourceSetContainer sourceSets() { + return project.getExtensions().getByType(SourceSetContainer.class); + } + + public SourceSet sourceSet(String sourceSetName) { + return sourceSets().getByName(sourceSetName); + } + + public SourceSet mainSourceSet() { + return sourceSet(SourceSet.MAIN_SOURCE_SET_NAME); + } + + public SourceSet testSourceSet(String sourceSetName) { + return sourceSet(SourceSet.TEST_SOURCE_SET_NAME); + } + //endregion + + //region TASKS + public Task task(String taskName) { + return project.getTasks().getByName(taskName); + } + + public JavaCompile compileJavaTask(String taskName) { + return (JavaCompile) task(taskName); + } + + public Optional findTask(String taskName) { + return Optional.ofNullable(project.getTasks().findByName(taskName)); + } + + public Optional findCompileJavaTask(String taskName) { + return findTask(taskName).map(JavaCompile.class::cast); + } + //endregion + +} diff --git a/src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java b/src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java index 47d51a6..0509498 100644 --- a/src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java +++ b/src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java @@ -2,28 +2,29 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; +import org.gradle.api.plugins.ExtensionContainer; import org.gradle.api.plugins.JavaPlugin; import org.javamodularity.moduleplugin.tasks.*; -import java.util.Optional; - public class ModuleSystemPlugin implements Plugin { @Override public void apply(Project project) { project.getPlugins().apply(JavaPlugin.class); - Optional foundModuleName = new ModuleName().findModuleName(project); - foundModuleName.ifPresent(moduleName -> { - project.getExtensions().add("moduleName", moduleName); - project.getExtensions().create("patchModules", PatchModuleExtension.class); + new ModuleName().findModuleName(project).ifPresent(moduleName -> configureModularity(project, moduleName)); + } + + private void configureModularity(Project project, String moduleName) { + ExtensionContainer extensions = project.getExtensions(); + extensions.add("moduleName", moduleName); + extensions.create("patchModules", PatchModuleExtension.class); - new CompileTask().configureCompileJava(project); - new CompileTestTask().configureCompileTestJava(project, moduleName); - new TestTask().configureTestJava(project, moduleName); - new RunTask().configureRun(project, moduleName); - new JavadocTask().configureJavaDoc(project); - ModularJavaExec.configure(project, moduleName); - ModularCreateStartScripts.configure(project, moduleName); - }); + new CompileTask(project).configureCompileJava(); + new CompileTestTask().configureCompileTestJava(project, moduleName); + new TestTask().configureTestJava(project, moduleName); + new RunTask().configureRun(project, moduleName); + new JavadocTask().configureJavaDoc(project); + ModularJavaExec.configure(project, moduleName); + ModularCreateStartScripts.configure(project, moduleName); } } diff --git a/src/main/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutator.java b/src/main/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutator.java index 73e2ed0..75ccd2a 100644 --- a/src/main/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutator.java +++ b/src/main/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutator.java @@ -9,6 +9,8 @@ class CompileJavaTaskMutator { + private static final String COMPILE_KOTLIN_TASK_NAME = "compileKotlin"; + static void mutateJavaCompileTask(Project project, JavaCompile compileJava) { ModuleOptions moduleOptions = compileJava.getExtensions().getByType(ModuleOptions.class); PatchModuleExtension patchModuleExtension = project.getExtensions().getByType(PatchModuleExtension.class); @@ -26,7 +28,8 @@ static void mutateJavaCompileTask(Project project, JavaCompile compileJava) { compileJava.getOptions().setCompilerArgs(compilerArgs); compileJava.setClasspath(project.files()); - AbstractCompile compileKotlin = (AbstractCompile) project.getTasks().findByName("compileKotlin"); + // https://github.com/java9-modularity/gradle-modules-plugin/issues/45 + AbstractCompile compileKotlin = (AbstractCompile) project.getTasks().findByName(COMPILE_KOTLIN_TASK_NAME); if (compileKotlin != null) { compileJava.setDestinationDir(compileKotlin.getDestinationDir()); } diff --git a/src/main/java/org/javamodularity/moduleplugin/tasks/CompileTask.java b/src/main/java/org/javamodularity/moduleplugin/tasks/CompileTask.java index 755d1b8..75039a5 100644 --- a/src/main/java/org/javamodularity/moduleplugin/tasks/CompileTask.java +++ b/src/main/java/org/javamodularity/moduleplugin/tasks/CompileTask.java @@ -5,26 +5,34 @@ import org.gradle.api.Task; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.tasks.compile.JavaCompile; +import org.javamodularity.moduleplugin.JavaProjectHelper; public class CompileTask { - public void configureCompileJava(Project project) { - JavaCompile compileJava = (JavaCompile) project.getTasks().findByName(JavaPlugin.COMPILE_JAVA_TASK_NAME); - if (compileJava != null) { - compileJava.getExtensions().create("moduleOptions", ModuleOptions.class, project); + private final Project project; - compileJava.doFirst(new Action() { + public CompileTask(Project project) { + this.project = project; + } + + public void configureCompileJava() { + helper().findCompileJavaTask(JavaPlugin.COMPILE_JAVA_TASK_NAME) + .ifPresent(this::configureCompileJava); + } - /* (non-Javadoc) - * @see org.gradle.api.Action#execute(java.lang.Object) - */ - @Override - public void execute(Task task) { - CompileJavaTaskMutator.mutateJavaCompileTask(project, compileJava); - } + private void configureCompileJava(JavaCompile compileJava) { + compileJava.getExtensions().create("moduleOptions", ModuleOptions.class, project); - }); - } + // don't convert to lambda: https://github.com/java9-modularity/gradle-modules-plugin/issues/54 + compileJava.doFirst(new Action() { + @Override + public void execute(Task task) { + CompileJavaTaskMutator.mutateJavaCompileTask(project, compileJava); + } + }); } + private JavaProjectHelper helper() { + return new JavaProjectHelper(project); + } } diff --git a/src/main/java/org/javamodularity/moduleplugin/tasks/CompileTestTask.java b/src/main/java/org/javamodularity/moduleplugin/tasks/CompileTestTask.java index 4137650..334d53b 100644 --- a/src/main/java/org/javamodularity/moduleplugin/tasks/CompileTestTask.java +++ b/src/main/java/org/javamodularity/moduleplugin/tasks/CompileTestTask.java @@ -1,9 +1,5 @@ package org.javamodularity.moduleplugin.tasks; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - import org.gradle.api.Action; import org.gradle.api.Project; import org.gradle.api.Task; @@ -13,6 +9,9 @@ import org.gradle.api.tasks.compile.JavaCompile; import org.javamodularity.moduleplugin.TestEngine; +import java.util.ArrayList; +import java.util.List; + public class CompileTestTask { public void configureCompileTestJava(Project project, String moduleName) { @@ -23,11 +22,8 @@ public void configureCompileTestJava(Project project, String moduleName) { compileTestJava.getExtensions().create("moduleOptions", ModuleOptions.class, project); SourceSet testSourceSet = javaConvention.getSourceSets().getByName(SourceSet.TEST_SOURCE_SET_NAME); + // don't convert to lambda: https://github.com/java9-modularity/gradle-modules-plugin/issues/54 compileTestJava.doFirst(new Action() { - - /* (non-Javadoc) - * @see org.gradle.api.Action#execute(java.lang.Object) - */ @Override public void execute(Task task) { var args = new ArrayList<>(compileTestJava.getOptions().getCompilerArgs()); @@ -38,19 +34,10 @@ public void execute(Task task) { "--patch-module", moduleName + "=" + testSourceSet.getJava().getSourceDirectories().getAsPath() )); - TestEngine.select(project).ifPresent(new Consumer() { - - /* (non-Javadoc) - * @see java.util.function.Consumer#accept(java.lang.Object) - */ - @Override - public void accept(TestEngine testEngine) { - args.addAll(List.of( - "--add-modules", testEngine.moduleName, - "--add-reads", moduleName + "=" + testEngine.moduleName)); - } - - }); + TestEngine.select(project).ifPresent(testEngine -> args.addAll(List.of( + "--add-modules", testEngine.moduleName, + "--add-reads", moduleName + "=" + testEngine.moduleName + ))); ModuleOptions moduleOptions = compileTestJava.getExtensions().getByType(ModuleOptions.class); moduleOptions.mutateArgs(moduleName, args); diff --git a/src/main/java/org/javamodularity/moduleplugin/tasks/JavadocTask.java b/src/main/java/org/javamodularity/moduleplugin/tasks/JavadocTask.java index 3238f3a..816b4fd 100644 --- a/src/main/java/org/javamodularity/moduleplugin/tasks/JavadocTask.java +++ b/src/main/java/org/javamodularity/moduleplugin/tasks/JavadocTask.java @@ -4,7 +4,6 @@ import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.plugins.JavaPlugin; -import org.gradle.api.tasks.compile.JavaCompile; import org.gradle.api.tasks.javadoc.Javadoc; import org.gradle.external.javadoc.CoreJavadocOptions; @@ -16,11 +15,8 @@ public void configureJavaDoc(Project project) { javadoc.getExtensions().create("moduleOptions", ModuleOptions.class, project); PatchModuleExtension patchModuleExtension = project.getExtensions().getByType(PatchModuleExtension.class); + // don't convert to lambda: https://github.com/java9-modularity/gradle-modules-plugin/issues/54 javadoc.doFirst(new Action() { - - /* (non-Javadoc) - * @see org.gradle.api.Action#execute(java.lang.Object) - */ @Override public void execute(Task task) { ModuleOptions moduleOptions = javadoc.getExtensions().getByType(ModuleOptions.class); diff --git a/src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java b/src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java index 266e41b..5cadbc3 100644 --- a/src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java +++ b/src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java @@ -6,8 +6,7 @@ import org.gradle.api.Task; import org.gradle.api.distribution.Distribution; import org.gradle.api.distribution.DistributionContainer; -import org.gradle.api.file.CopySpec; -import org.gradle.api.file.FileCollection; +import org.gradle.api.file.RelativePath; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; import org.gradle.api.plugins.JavaPluginConvention; @@ -21,7 +20,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class RunTaskMutator { @@ -54,6 +52,7 @@ public void updateStartScriptsTask(String taskStartScriptsName) { public void updateStartScriptsTask(CreateStartScripts startScriptsTask) { PatchModuleExtension patchModuleExtension = project.getExtensions().getByType(PatchModuleExtension.class); + // don't convert to lambda: https://github.com/java9-modularity/gradle-modules-plugin/issues/54 startScriptsTask.doFirst(new Action() { @Override public void execute(final Task task) { @@ -86,6 +85,7 @@ public void execute(final Task task) { } }); + // don't convert to lambda: https://github.com/java9-modularity/gradle-modules-plugin/issues/54 startScriptsTask.doLast(new Action() { @Override public void execute(final Task task) { @@ -100,20 +100,18 @@ public void execute(final Task task) { public void movePatchedLibs() { PatchModuleExtension patchModuleExtension = project.getExtensions().getByType(PatchModuleExtension.class); - if(!patchModuleExtension.getConfig().isEmpty()) { + if (!patchModuleExtension.getConfig().isEmpty()) { Distribution distribution = ((DistributionContainer) project.getExtensions().getByName("distributions")).getByName("main"); - distribution.contents(new Action() { - @Override - public void execute(CopySpec copySpec) { - copySpec.filesMatching(patchModuleExtension.getJars(), (action) -> { - action.setRelativePath(action.getRelativePath().getParent().getParent().append(true, "patchlibs", action.getName())); - }); - } - }); + distribution.contents(copySpec -> copySpec.filesMatching(patchModuleExtension.getJars(), action -> { + RelativePath relativePath = action.getRelativePath().getParent().getParent() + .append(true, "patchlibs", action.getName()); + action.setRelativePath(relativePath); + })); } } private void updateJavaExecTask() { + // don't convert to lambda: https://github.com/java9-modularity/gradle-modules-plugin/issues/54 execTask.doFirst(new Action() { @Override public void execute(final Task task) { diff --git a/src/main/java/org/javamodularity/moduleplugin/tasks/TestModuleOptions.java b/src/main/java/org/javamodularity/moduleplugin/tasks/TestModuleOptions.java index 0e2682b..15fd3b2 100644 --- a/src/main/java/org/javamodularity/moduleplugin/tasks/TestModuleOptions.java +++ b/src/main/java/org/javamodularity/moduleplugin/tasks/TestModuleOptions.java @@ -10,7 +10,7 @@ public TestModuleOptions(Project project) { super(project); } - public boolean isRunOnClasspath() { + public boolean getRunOnClasspath() { return runOnClasspath; } diff --git a/src/main/java/org/javamodularity/moduleplugin/tasks/TestTask.java b/src/main/java/org/javamodularity/moduleplugin/tasks/TestTask.java index d56ecce..05dfeff 100644 --- a/src/main/java/org/javamodularity/moduleplugin/tasks/TestTask.java +++ b/src/main/java/org/javamodularity/moduleplugin/tasks/TestTask.java @@ -1,21 +1,5 @@ package org.javamodularity.moduleplugin.tasks; -import static java.io.File.pathSeparator; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; -import java.util.function.Consumer; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - import org.codehaus.groovy.tools.Utilities; import org.gradle.api.Action; import org.gradle.api.GradleException; @@ -29,6 +13,17 @@ import org.gradle.api.tasks.testing.Test; import org.javamodularity.moduleplugin.TestEngine; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.io.File.pathSeparator; + public class TestTask { private static final Logger LOGGER = Logging.getLogger(TestTask.class); private static Pattern CLASS_FILE_SPLITTER = Pattern.compile("[./\\\\]"); @@ -42,23 +37,21 @@ public void configureTestJava(Project project, String moduleName) { SourceSet mainSourceSet = javaConvention.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); testJava.getExtensions().create("moduleOptions", TestModuleOptions.class, project); + // don't convert to lambda: https://github.com/java9-modularity/gradle-modules-plugin/issues/54 testJava.doFirst(new Action() { - - /* (non-Javadoc) - * @see org.gradle.api.Action#execute(java.lang.Object) - */ @Override public void execute(Task task) { TestModuleOptions testModuleOptions = testJava.getExtensions().getByType(TestModuleOptions.class); - if (testModuleOptions.isRunOnClasspath()) { + if (testModuleOptions.getRunOnClasspath()) { LOGGER.lifecycle("Running tests on classpath"); return; } var args = new ArrayList<>(testJava.getJvmArgs()); - String testClassesDirs = testSourceSet.getOutput().getClassesDirs().getFiles() - .stream().map(File::getPath).collect(Collectors.joining(pathSeparator)); + String testClassesDirs = testSourceSet.getOutput().getClassesDirs().getFiles().stream() + .map(File::getPath) + .collect(Collectors.joining(pathSeparator)); args.addAll(List.of( "--module-path", testJava.getClasspath() @@ -74,30 +67,14 @@ public void execute(Task task) { args.addAll(patchModuleExtension.configure(testJava.getClasspath())); - TestEngine.select(project).ifPresent(new Consumer() { - - /* (non-Javadoc) - * @see java.util.function.Consumer#accept(java.lang.Object) - */ - @Override - public void accept(TestEngine testEngine) { - args.addAll(List.of("--add-reads", moduleName + "=" + testEngine.moduleName)); - - Set testDirs = testSourceSet.getOutput().getClassesDirs().getFiles(); - getPackages(testDirs).forEach(new Consumer() { - - /* (non-Javadoc) - * @see java.util.function.Consumer#accept(java.lang.Object) - */ - @Override - public void accept(String p) { - args.add("--add-opens"); - args.add(String.format("%s/%s=%s", moduleName, p, testEngine.addOpens)); - } - - }); - } + TestEngine.select(project).ifPresent(testEngine -> { + args.addAll(List.of("--add-reads", moduleName + "=" + testEngine.moduleName)); + Set testDirs = testSourceSet.getOutput().getClassesDirs().getFiles(); + getPackages(testDirs).forEach(p -> { + args.add("--add-opens"); + args.add(String.format("%s/%s=%s", moduleName, p, testEngine.addOpens)); + }); }); ModuleInfoTestHelper.mutateArgs(project, moduleName, args::add); diff --git a/src/test/java/org/javamodularity/moduleplugin/ModulePluginSmokeTest.java b/src/test/java/org/javamodularity/moduleplugin/ModulePluginSmokeTest.java index 8b9f2e4..adb1284 100644 --- a/src/test/java/org/javamodularity/moduleplugin/ModulePluginSmokeTest.java +++ b/src/test/java/org/javamodularity/moduleplugin/ModulePluginSmokeTest.java @@ -2,16 +2,16 @@ import com.google.common.base.Charsets; import com.google.common.io.Resources; +import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; -import org.gradle.testkit.runner.TaskOutcome; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.nio.file.Path; import java.util.List; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -20,47 +20,48 @@ @SuppressWarnings("ConstantConditions") class ModulePluginSmokeTest { + private static final String GRADLE_VERSION = "5.0"; + private List pluginClasspath; @BeforeEach void before() throws IOException { pluginClasspath = Resources.readLines(Resources.getResource("plugin-classpath.txt"), Charsets.UTF_8) .stream() - .map(fname -> new File(fname)) + .map(File::new) .collect(Collectors.toList()); } @ParameterizedTest - @ValueSource(strings = { "test-project", "test-project-kotlin" }) + @ValueSource(strings = {"test-project", "test-project-kotlin"}) void smokeTest(String projectName) { var result = GradleRunner.create() .withProjectDir(new File(projectName + "/")) .withPluginClasspath(pluginClasspath) - .withGradleVersion("4.10.2") + .withGradleVersion(GRADLE_VERSION) .withArguments("-c", "smoke_test_settings.gradle", "clean", "build", "run", "--stacktrace") .forwardOutput() .build(); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.api:build").getOutcome(), "Failed Build!"); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.provider:build").getOutcome(), "Failed Build!"); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.provider.test:build").getOutcome(), "Failed Build!"); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.runner:build").getOutcome(), "Failed Build!"); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.runner:run").getOutcome(), "Failed Build!"); + assertTasksSuccessful(result, "greeter.api", "build"); + assertTasksSuccessful(result, "greeter.provider", "build"); + assertTasksSuccessful(result, "greeter.provider.test", "build"); + assertTasksSuccessful(result, "greeter.runner", "build", "run"); } @ParameterizedTest - @ValueSource(strings = "test-project") + @ValueSource(strings = "test-project") void smokeTestDist(String projectName) { var result = GradleRunner.create() .withProjectDir(new File(projectName + "/")) .withPluginClasspath(pluginClasspath) - .withGradleVersion("4.10.2") + .withGradleVersion(GRADLE_VERSION) .withArguments("-c", "smoke_test_settings.gradle", "clean", "build", ":greeter.runner:installDist", "--stacktrace") .forwardOutput() .build(); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.runner:installDist").getOutcome(), "Failed Build!"); - Path installDir = Path.of(projectName + "/greeter.runner/build/install/greeter.runner"); + assertTasksSuccessful(result, "greeter.runner", "installDist"); + Path installDir = Path.of(projectName + "/greeter.runner/build/install/greeter.runner"); assertTrue(installDir.toFile().exists(), "Install dir was not created"); Path libDir = installDir.resolve("lib"); @@ -73,26 +74,25 @@ void smokeTestDist(String projectName) { assertTrue(patchedLib.toFile().exists(), "Patched lib should be in patchlibs dir"); assertEquals(0, libDir.toFile().listFiles(f -> f.getName().equals("jsr305-3.0.2.jar")).length, "Patched libs should not be in lib dir"); - assertEquals(4, libDir.toFile().listFiles().length, "Unexepcted number of jars in lib dir"); + assertEquals(4, libDir.toFile().listFiles().length, "Unexpected number of jars in lib dir"); Path binDir = installDir.resolve("bin"); assertTrue(getAppOutput(binDir.toString(), "greeter.runner").contains("welcome")); } @ParameterizedTest - @ValueSource(strings = { "test-project", "test-project-kotlin" }) + @ValueSource(strings = {"test-project", "test-project-kotlin"}) void smokeTestRunDemo(String projectName) { var result = GradleRunner.create() .withProjectDir(new File(projectName + "/")) .withPluginClasspath(pluginClasspath) - .withGradleVersion("4.10.2") + .withGradleVersion(GRADLE_VERSION) .withArguments("-c", "smoke_test_settings.gradle", "clean", "build", ":greeter.javaexec:runDemo1", ":greeter.javaexec:runDemo2", "--info", "--stacktrace") .forwardOutput() .build(); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.javaexec:runDemo1").getOutcome(), "Failed Build!"); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.javaexec:runDemo2").getOutcome(), "Failed Build!"); + assertTasksSuccessful(result, "greeter.javaexec", "runDemo1", "runDemo2"); } @ParameterizedTest @@ -101,12 +101,12 @@ void smokeTestRunStartScripts(String projectName) { var result = GradleRunner.create() .withProjectDir(new File(projectName + "/")) .withPluginClasspath(pluginClasspath) - .withGradleVersion("4.10.2") + .withGradleVersion(GRADLE_VERSION) .withArguments("-c", "smoke_test_settings.gradle", "clean", ":greeter.startscripts:installDist", "--info", "--stacktrace") .forwardOutput() .build(); - assertEquals(TaskOutcome.SUCCESS, result.task(":greeter.startscripts:installDist").getOutcome(), "Failed Build!"); + assertTasksSuccessful(result, "greeter.startscripts", "installDist"); String binDir = projectName + "/greeter.startscripts/build/install/demo/bin"; assertEquals("MainDemo: welcome", getAppOutput(binDir, "demo")); @@ -115,35 +115,13 @@ void smokeTestRunStartScripts(String projectName) { } private static String getAppOutput(String binDirPath, String appName) { - boolean windows = System.getProperty("os.name").toLowerCase().contains("windows"); - String scriptName = windows ? (appName + ".bat") : appName ; - - File binDir = new File(binDirPath).getAbsoluteFile(); - Process process; - try { - process = new ProcessBuilder() - .directory(binDir) - .command(new File(binDir, scriptName).getPath()) - .start(); - process.waitFor(30, TimeUnit.SECONDS); - } catch (Exception e) { - e.printStackTrace(); - return e.toString(); - } - if(process.exitValue() != 0) { - String errText = getText(process.getErrorStream()); - System.err.println("Process terminated with exit code " + process.exitValue() + ": " + errText); - return errText; - } - return getText(process.getInputStream()); + return SmokeTestHelper.getAppOutput(binDirPath, appName); } - public static String getText(InputStream inputStream){ - try (BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream))) { - return buffer.lines().collect(Collectors.joining("\n")); - } catch(IOException e) { - e.printStackTrace(); - return e.getMessage(); + private static void assertTasksSuccessful(BuildResult result, String subprojectName, String... taskNames) { + for (String taskName : taskNames) { + SmokeTestHelper.assertTaskSuccessful(result, subprojectName, taskName); } } + } diff --git a/src/test/java/org/javamodularity/moduleplugin/SmokeTestHelper.java b/src/test/java/org/javamodularity/moduleplugin/SmokeTestHelper.java new file mode 100644 index 0000000..77ab344 --- /dev/null +++ b/src/test/java/org/javamodularity/moduleplugin/SmokeTestHelper.java @@ -0,0 +1,56 @@ +package org.javamodularity.moduleplugin; + +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.BuildTask; +import org.gradle.testkit.runner.TaskOutcome; + +import java.io.*; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class SmokeTestHelper { + + static void assertTaskSuccessful(BuildResult result, String subprojectName, String taskName) { + String fullTaskName = String.format(":%s:%s", subprojectName, taskName); + BuildTask task = Objects.requireNonNull(result.task(fullTaskName), fullTaskName); + assertEquals(TaskOutcome.SUCCESS, task.getOutcome(), () -> fullTaskName + " failed!"); + } + + //region APP OUTPUT + static String getAppOutput(String binDirPath, String appName) { + boolean windows = System.getProperty("os.name").toLowerCase().contains("windows"); + String scriptName = windows ? (appName + ".bat") : appName; + + File binDir = new File(binDirPath).getAbsoluteFile(); + Process process; + try { + process = new ProcessBuilder() + .directory(binDir) + .command(new File(binDir, scriptName).getPath()) + .start(); + process.waitFor(30, TimeUnit.SECONDS); + } catch (Exception e) { + e.printStackTrace(); + return e.toString(); + } + if (process.exitValue() != 0) { + String errText = getText(process.getErrorStream()); + System.err.println("Process terminated with exit code " + process.exitValue() + ": " + errText); + return errText; + } + return getText(process.getInputStream()); + } + + private static String getText(InputStream inputStream) { + try (BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream))) { + return buffer.lines().collect(Collectors.joining("\n")); + } catch (IOException e) { + e.printStackTrace(); + return e.getMessage(); + } + } + //endregion +} diff --git a/src/test/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutatorTest.java b/src/test/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutatorTest.java index b6064fd..54a6177 100644 --- a/src/test/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutatorTest.java +++ b/src/test/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutatorTest.java @@ -37,7 +37,7 @@ void mutateJavaCompileTask() { private List twoLastCompilerArgs(JavaCompile compileJava) { List allCompilerArgs = compileJava.getOptions().getAllCompilerArgs(); int size = allCompilerArgs.size(); - return allCompilerArgs.subList(size-2, size); + return allCompilerArgs.subList(size - 2, size); } -} \ No newline at end of file +} diff --git a/test-project-kotlin/README.md b/test-project-kotlin/README.md index 77f95dc..401316c 100644 --- a/test-project-kotlin/README.md +++ b/test-project-kotlin/README.md @@ -33,8 +33,8 @@ Internal test project === This mode is enabled in `ModulePluginSmokeTest` by passing an extra parameter (`-c smoke_test_settings.gradle`) -that points to `smoke_test_build.gradle` instead of `build.gradle`. It doesn't resolve a plugin jar. -Instead, it relies on the smoke test to makes the plugin under development available +that points to `smoke_test_build.gradle.kts` instead of `build.gradle.kts`. It doesn't resolve a plugin jar. +Instead, it relies on the smoke test to make the plugin under development available to the test project by sharing a classpath (using Gradle TestKit). -__CAUTION:__ This approach won't work outside of the smoke test, it will break the build because the plugin jar won't be resolved. \ No newline at end of file +__CAUTION:__ This approach won't work outside of the smoke test, it will break the build because the plugin jar won't be resolved. diff --git a/test-project-kotlin/build.gradle.kts b/test-project-kotlin/build.gradle.kts index 2d628c5..3c915ae 100644 --- a/test-project-kotlin/build.gradle.kts +++ b/test-project-kotlin/build.gradle.kts @@ -10,7 +10,7 @@ buildscript { } plugins { - val kotlinVersion = "1.3.10" + val kotlinVersion = "1.3.20" kotlin("jvm") version kotlinVersion } @@ -40,6 +40,7 @@ subprojects { testLogging { events("PASSED", "FAILED", "SKIPPED") + stackTraceFilters = listOf() } } diff --git a/test-project-kotlin/greeter.api/build.gradle.kts b/test-project-kotlin/greeter.api/build.gradle.kts index 2b02113..011320c 100644 --- a/test-project-kotlin/greeter.api/build.gradle.kts +++ b/test-project-kotlin/greeter.api/build.gradle.kts @@ -1,5 +1,24 @@ +import org.javamodularity.moduleplugin.tasks.ModuleOptions +import org.javamodularity.moduleplugin.tasks.TestModuleOptions import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +//region NO-OP (DSL testing) +tasks { + compileJava { + extensions.configure(ModuleOptions::class) { + addModules = listOf() + } + } + + test { + extensions.configure(TestModuleOptions::class) { + addModules = listOf() + runOnClasspath = false + } + } +} +//endregion + val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions { jvmTarget = "1.8" @@ -7,4 +26,4 @@ compileKotlin.kotlinOptions { val compileTestKotlin: KotlinCompile by tasks compileTestKotlin.kotlinOptions { jvmTarget = "1.8" -} \ No newline at end of file +} diff --git a/test-project-kotlin/local_maven_build.gradle.kts b/test-project-kotlin/local_maven_build.gradle.kts index 9df463f..60893c7 100644 --- a/test-project-kotlin/local_maven_build.gradle.kts +++ b/test-project-kotlin/local_maven_build.gradle.kts @@ -9,7 +9,7 @@ buildscript { } plugins { - val kotlinVersion = "1.3.10" + val kotlinVersion = "1.3.20" kotlin("jvm") version kotlinVersion } diff --git a/test-project-kotlin/smoke_test_build.gradle.kts b/test-project-kotlin/smoke_test_build.gradle.kts index aa79bb0..2a3d888 100644 --- a/test-project-kotlin/smoke_test_build.gradle.kts +++ b/test-project-kotlin/smoke_test_build.gradle.kts @@ -6,7 +6,7 @@ buildscript { } } plugins { - val kotlinVersion = "1.3.10" + val kotlinVersion = "1.3.20" kotlin("jvm") version kotlinVersion id("org.javamodularity.moduleplugin") } diff --git a/test-project/build.gradle b/test-project/build.gradle index bd41f07..186d39a 100644 --- a/test-project/build.gradle +++ b/test-project/build.gradle @@ -26,6 +26,7 @@ subprojects { testLogging { events 'PASSED', 'FAILED', 'SKIPPED' + stackTraceFilters = [] } } diff --git a/test-project/greeter.api/build.gradle b/test-project/greeter.api/build.gradle index 15cc768..46380ea 100644 --- a/test-project/greeter.api/build.gradle +++ b/test-project/greeter.api/build.gradle @@ -1,3 +1,18 @@ plugins { id 'org.javamodularity.moduleplugin' -} \ No newline at end of file +} + +//region NO-OP (DSL testing) +compileJava { + moduleOptions { + addModules = [] + } +} + +test { + moduleOptions { + addModules = [] + runOnClasspath = false + } +} +//endregion