Skip to content

Commit 93e9fd2

Browse files
committed
Base plugin on 'test suite' API
1 parent 23e6c4d commit 93e9fd2

File tree

9 files changed

+151
-170
lines changed

9 files changed

+151
-170
lines changed
Lines changed: 51 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package de.jjohannes.gradle.moduletesting;
22

3+
import de.jjohannes.gradle.moduletesting.internal.ModuleInfoParser;
4+
import de.jjohannes.gradle.moduletesting.internal.bridges.JavaModuleDependenciesBridge;
5+
import de.jjohannes.gradle.moduletesting.internal.provider.WhiteboxTestCompileArgumentProvider;
6+
import de.jjohannes.gradle.moduletesting.internal.provider.WhiteboxTestRuntimeArgumentProvider;
37
import org.gradle.api.Action;
48
import org.gradle.api.Project;
59
import org.gradle.api.artifacts.Configuration;
610
import org.gradle.api.artifacts.ConfigurationContainer;
711
import org.gradle.api.artifacts.dsl.DependencyHandler;
12+
import org.gradle.api.plugins.jvm.JvmTestSuite;
13+
import org.gradle.api.provider.Provider;
814
import org.gradle.api.tasks.SourceSet;
915
import org.gradle.api.tasks.SourceSetContainer;
1016
import org.gradle.api.tasks.TaskContainer;
@@ -13,14 +19,13 @@
1319
import org.gradle.api.tasks.testing.Test;
1420
import org.gradle.internal.jvm.JavaModuleDetector;
1521
import org.gradle.jvm.tasks.Jar;
16-
import org.gradle.language.base.plugins.LifecycleBasePlugin;
22+
import org.gradle.testing.base.TestSuite;
1723

1824
import javax.inject.Inject;
19-
import java.util.List;
20-
import java.util.Map;
2125

26+
@SuppressWarnings("UnstableApiUsage")
2227
public abstract class JavaModuleTestingExtension {
23-
private static final Action<WhiteboxTestSet> NO_OP_ACTION = c -> {};
28+
private static final Action<WhiteboxJvmTestSuite> NO_OP_ACTION = c -> {};
2429

2530
private final Project project;
2631
private final JavaModuleDetector moduleDetector;
@@ -31,63 +36,32 @@ public JavaModuleTestingExtension(Project project, JavaModuleDetector moduleDete
3136
this.moduleDetector = moduleDetector;
3237
}
3338

34-
public void blackboxTests(String testSourceSetName) {
35-
SourceSet sourceSet = configureSourceSetForTesting(testSourceSetName);
36-
configureSourceSetForBlackbox(sourceSet);
37-
}
38-
39-
public void junit5WhiteboxTests(String testSourceSetName, String junit5Version) {
40-
junit5WhiteboxTests(testSourceSetName, junit5Version, NO_OP_ACTION);
41-
}
42-
43-
public void junit5WhiteboxTests(String testSourceSetName, String junit5Version, Action<WhiteboxTestSet> conf) {
44-
whiteboxTests(testSourceSetName, "org.junit.jupiter.api", "org.junit.jupiter:junit-jupiter-api:" + junit5Version, conf);
45-
project.getTasks().named(testSourceSetName, Test.class).configure(Test::useJUnitPlatform);
46-
}
47-
48-
public void junit4WhiteboxTests(String testSourceSetName, String junit4Version) {
49-
junit4WhiteboxTests(testSourceSetName, junit4Version, NO_OP_ACTION);
39+
public void blackbox(TestSuite jvmTestSuite) {
40+
if (jvmTestSuite instanceof JvmTestSuite) {
41+
configureJvmTestSuiteForBlackbox((JvmTestSuite) jvmTestSuite);
42+
}
5043
}
5144

52-
public void junit4WhiteboxTests(String testSourceSetName, String junit4Version, Action<WhiteboxTestSet> conf) {
53-
whiteboxTests(testSourceSetName, "junit", "junit:junit:" + junit4Version, conf);
54-
project.getTasks().named(testSourceSetName, Test.class).configure(Test::useJUnit);
55-
}
45+
public void whitebox(TestSuite jvmTestSuite) {
46+
whitebox(jvmTestSuite, NO_OP_ACTION);
5647

57-
private void whiteboxTests(String testSourceSetName, String testFrameworkModuleName, String testFrameworkGAV, Action<WhiteboxTestSet> conf) {
58-
WhiteboxTestSet whiteboxTestSet = new WhiteboxTestSet();
59-
conf.execute(whiteboxTestSet);
60-
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
61-
SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
62-
SourceSet testSourceSet = configureSourceSetForTesting(testSourceSetName);
63-
configureSourceSetForWhitebox(mainSourceSet, testSourceSet, testFrameworkModuleName, testFrameworkGAV, whiteboxTestSet.getTestRequires());
6448
}
6549

66-
private SourceSet configureSourceSetForTesting(String name) {
67-
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
68-
TaskContainer tasks = project.getTasks();
69-
SourceSet sourceSet = sourceSets.maybeCreate(name);
70-
71-
TaskProvider<Test> testTask;
72-
if (!tasks.getNames().contains(name)) {
73-
testTask = tasks.register(name, Test.class, t -> {
74-
t.setDescription("Runs " + name + " tests.");
75-
t.setGroup("verification");
76-
});
77-
tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME, t-> {
78-
t.dependsOn(testTask);
79-
});
50+
public void whitebox(TestSuite jvmTestSuite, Action<WhiteboxJvmTestSuite> conf) {
51+
if (jvmTestSuite instanceof JvmTestSuite) {
52+
WhiteboxJvmTestSuite whiteboxJvmTestSuite = project.getObjects().newInstance(WhiteboxJvmTestSuite.class);
53+
whiteboxJvmTestSuite.getSourcesUnderTest().convention(project.getExtensions().getByType(SourceSetContainer.class).getByName(SourceSet.MAIN_SOURCE_SET_NAME));
54+
conf.execute(whiteboxJvmTestSuite);
55+
configureJvmTestSuiteForWhitebox((JvmTestSuite) jvmTestSuite, whiteboxJvmTestSuite);
8056
}
81-
82-
return sourceSet;
8357
}
8458

85-
private void configureSourceSetForBlackbox(SourceSet sourceSet) {
59+
private void configureJvmTestSuiteForBlackbox(JvmTestSuite jvmTestSuite) {
8660
ConfigurationContainer configurations = project.getConfigurations();
87-
DependencyHandler dependencies = project.getDependencies();
8861
TaskContainer tasks = project.getTasks();
8962

9063
TaskProvider<Jar> jarTask;
64+
SourceSet sourceSet = jvmTestSuite.getSources();
9165
if (!tasks.getNames().contains(sourceSet.getJarTaskName())) {
9266
jarTask = tasks.register(sourceSet.getJarTaskName(), Jar.class, t -> {
9367
t.getArchiveClassifier().set(sourceSet.getName());
@@ -98,61 +72,58 @@ private void configureSourceSetForBlackbox(SourceSet sourceSet) {
9872
}
9973

10074
tasks.named(sourceSet.getName(), Test.class, t -> {
75+
// Classpath consists only of Jars to include classes+resources in one place
10176
t.setClasspath(configurations.getByName(sourceSet.getRuntimeClasspathConfigurationName()).plus(project.files(jarTask)));
77+
// Rest test classes dir to allow switching back from 'whitebox' to 'blackbox'
10278
t.setTestClassesDirs(sourceSet.getOutput().getClassesDirs());
10379
});
104-
dependencies.add(sourceSet.getImplementationConfigurationName(), project);
10580
}
10681

107-
private void configureSourceSetForWhitebox(SourceSet mainSourceSet, SourceSet testSourceSet, String testFrameworkModuleName, String testFrameworkGAV, List<String> testRequires) {
82+
private void configureJvmTestSuiteForWhitebox(JvmTestSuite jvmTestSuite, WhiteboxJvmTestSuite whiteboxJvmTestSuite) {
10883
ConfigurationContainer configurations = project.getConfigurations();
10984
DependencyHandler dependencies = project.getDependencies();
11085
TaskContainer tasks = project.getTasks();
11186
ModuleInfoParser moduleInfoParser = new ModuleInfoParser(project.getLayout(), project.getProviders());
11287

113-
tasks.named(testSourceSet.getCompileJavaTaskName(), JavaCompile.class, t -> {
114-
t.setClasspath(mainSourceSet.getOutput().plus(configurations.getByName(testSourceSet.getCompileClasspathConfigurationName())));
115-
t.getOptions().getCompilerArgumentProviders().add(new WhiteboxTestCompileArgumentProvider(
116-
mainSourceSet.getJava().getSrcDirs(),
117-
testSourceSet.getJava().getSrcDirs(),
118-
t,
119-
testFrameworkModuleName,
120-
testRequires,
88+
SourceSet testSources = jvmTestSuite.getSources();
89+
tasks.named(testSources.getCompileJavaTaskName(), JavaCompile.class, compileJava -> {
90+
SourceSet sourcesUnderTest = whiteboxJvmTestSuite.getSourcesUnderTest().get();
91+
compileJava.setClasspath(sourcesUnderTest.getOutput().plus(configurations.getByName(testSources.getCompileClasspathConfigurationName())));
92+
compileJava.getOptions().getCompilerArgumentProviders().add(new WhiteboxTestCompileArgumentProvider(
93+
sourcesUnderTest.getJava().getSrcDirs(),
94+
testSources.getJava().getSrcDirs(),
95+
compileJava,
96+
whiteboxJvmTestSuite.getRequires(),
12197
moduleDetector,
12298
moduleInfoParser));
12399
});
124100

125-
tasks.named(testSourceSet.getName(), Test.class, t -> {
126-
t.setClasspath(configurations.getByName(testSourceSet.getRuntimeClasspathConfigurationName()).plus(mainSourceSet.getOutput()).plus(testSourceSet.getOutput()));
101+
tasks.named(testSources.getName(), Test.class, test -> {
102+
SourceSet sourcesUnderTest = whiteboxJvmTestSuite.getSourcesUnderTest().get();
103+
test.setClasspath(configurations.getByName(testSources.getRuntimeClasspathConfigurationName()).plus(sourcesUnderTest.getOutput()).plus(testSources.getOutput()));
127104

128105
// Add main classes here so that Gradle finds module-info.class and treats this as a test with module path
129-
t.setTestClassesDirs(mainSourceSet.getOutput().getClassesDirs().plus(testSourceSet.getOutput().getClassesDirs()));
130-
131-
t.getJvmArgumentProviders().add(new WhiteboxTestRuntimeArgumentProvider(
132-
mainSourceSet.getJava().getSrcDirs(),
133-
testSourceSet.getJava().getClassesDirectory(),
134-
testFrameworkModuleName,
135-
testRequires,
106+
test.setTestClassesDirs(sourcesUnderTest.getOutput().getClassesDirs().plus(testSources.getOutput().getClassesDirs()));
107+
108+
test.getJvmArgumentProviders().add(new WhiteboxTestRuntimeArgumentProvider(
109+
sourcesUnderTest.getJava().getSrcDirs(),
110+
testSources.getJava().getClassesDirectory(),
111+
sourcesUnderTest.getOutput().getResourcesDir(),
112+
testSources.getOutput().getResourcesDir(),
113+
whiteboxJvmTestSuite.getRequires(),
114+
whiteboxJvmTestSuite.getOpensTo(),
136115
moduleInfoParser
137116
));
138117
});
139118

140-
Configuration implementation = configurations.getByName(testSourceSet.getImplementationConfigurationName());
141-
Configuration runtimeOnly = configurations.getByName(testSourceSet.getRuntimeOnlyConfigurationName());
142-
143-
implementation.extendsFrom(configurations.getByName(mainSourceSet.getImplementationConfigurationName()));
144-
runtimeOnly.extendsFrom(configurations.getByName(mainSourceSet.getRuntimeOnlyConfigurationName()));
145-
146-
dependencies.add(implementation.getName(), testFrameworkGAV);
147-
119+
Configuration implementation = configurations.getByName(testSources.getImplementationConfigurationName());
148120
implementation.withDependencies(d -> {
149-
for (String requiresModuleName : testRequires) {
150-
Map<?, ?> gav = JavaModuleDependenciesBridge.gav(project, requiresModuleName);
121+
for (String requiresModuleName : whiteboxJvmTestSuite.getRequires().get()) {
122+
Provider<?> gav = JavaModuleDependenciesBridge.gav(project, requiresModuleName);
151123
if (gav != null) {
152-
dependencies.add(implementation.getName(), gav);
124+
dependencies.addProvider(implementation.getName(), gav);
153125
}
154126
}
155127
});
156128
}
157-
158129
}

src/main/java/de/jjohannes/gradle/moduletesting/JavaModuleTestingPlugin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ public abstract class JavaModuleTestingPlugin implements Plugin<Project> {
1111

1212
@Override
1313
public void apply(Project project) {
14-
if (GradleVersion.current().compareTo(GradleVersion.version("7.0")) < 0) {
15-
throw new RuntimeException("This plugin requires Gradle 7.0+");
14+
if (GradleVersion.current().compareTo(GradleVersion.version("7.4")) < 0) {
15+
throw new RuntimeException("This plugin requires Gradle 7.4+");
1616
}
1717

1818
project.getExtensions().create("javaModuleTesting", JavaModuleTestingExtension.class);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package de.jjohannes.gradle.moduletesting;
2+
3+
import org.gradle.api.provider.ListProperty;
4+
import org.gradle.api.provider.Property;
5+
import org.gradle.api.tasks.SourceSet;
6+
7+
public interface WhiteboxJvmTestSuite {
8+
9+
Property<SourceSet> getSourcesUnderTest();
10+
11+
ListProperty<String> getRequires();
12+
13+
ListProperty<String> getOpensTo();
14+
}

src/main/java/de/jjohannes/gradle/moduletesting/WhiteboxTestRuntimeArgumentProvider.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/main/java/de/jjohannes/gradle/moduletesting/WhiteboxTestSet.java

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/main/java/de/jjohannes/gradle/moduletesting/ModuleInfoParser.java renamed to src/main/java/de/jjohannes/gradle/moduletesting/internal/ModuleInfoParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package de.jjohannes.gradle.moduletesting;
1+
package de.jjohannes.gradle.moduletesting.internal;
22

33
import org.gradle.api.file.ProjectLayout;
44
import org.gradle.api.file.RegularFile;
@@ -23,7 +23,7 @@ public ModuleInfoParser(ProjectLayout layout, ProviderFactory providers) {
2323
public String moduleName(Set<File> sourceFolders) {
2424
for (File folder : sourceFolders) {
2525
Provider<RegularFile> moduleInfoFile = layout.file(providers.provider(() -> new File(folder, "module-info.java")));
26-
Provider<String> moduleInfoContent = providers.fileContents(moduleInfoFile).getAsText().forUseAtConfigurationTime();
26+
Provider<String> moduleInfoContent = providers.fileContents(moduleInfoFile).getAsText();
2727
if (moduleInfoContent.isPresent()) {
2828
return moduleName(moduleInfoContent.get());
2929
}

src/main/java/de/jjohannes/gradle/moduletesting/JavaModuleDependenciesBridge.java renamed to src/main/java/de/jjohannes/gradle/moduletesting/internal/bridges/JavaModuleDependenciesBridge.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
package de.jjohannes.gradle.moduletesting;
1+
package de.jjohannes.gradle.moduletesting.internal.bridges;
22

33
import org.gradle.api.Project;
4+
import org.gradle.api.provider.Provider;
45

56
import java.lang.reflect.Method;
6-
import java.util.Map;
77

88
public class JavaModuleDependenciesBridge {
99

10-
public static Map<?, ?> gav(Project project, String moduleName) {
10+
public static Provider<?> gav(Project project, String moduleName) {
1111
Object javaModuleDependencies = project.getExtensions().findByName("javaModuleDependencies");
1212
if (javaModuleDependencies == null) {
1313
return null;
1414
}
1515
try {
1616
Method gav = javaModuleDependencies.getClass().getMethod("gav", String.class);
17-
return (Map<?, ?>) gav.invoke(javaModuleDependencies, moduleName);
17+
return (Provider<?>) gav.invoke(javaModuleDependencies, moduleName);
1818
} catch (Exception e) {
1919
throw new RuntimeException(e);
2020
}

src/main/java/de/jjohannes/gradle/moduletesting/WhiteboxTestCompileArgumentProvider.java renamed to src/main/java/de/jjohannes/gradle/moduletesting/internal/provider/WhiteboxTestCompileArgumentProvider.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
package de.jjohannes.gradle.moduletesting;
1+
package de.jjohannes.gradle.moduletesting.internal.provider;
22

33

4+
import de.jjohannes.gradle.moduletesting.internal.ModuleInfoParser;
5+
import org.gradle.api.provider.Provider;
46
import org.gradle.api.tasks.compile.JavaCompile;
57
import org.gradle.internal.jvm.JavaModuleDetector;
68
import org.gradle.process.CommandLineArgumentProvider;
@@ -15,16 +17,14 @@ public class WhiteboxTestCompileArgumentProvider implements CommandLineArgumentP
1517
private final Set<File> mainSourceFolders;
1618
private final Set<File> testSourceFolders;
1719
private final JavaCompile task;
18-
private final String testFrameworkAPI;
19-
private final List<String> testRequires;
20+
private final Provider<List<String>> testRequires;
2021
private final JavaModuleDetector moduleDetector;
2122
private final ModuleInfoParser moduleInfoParser;
2223

23-
public WhiteboxTestCompileArgumentProvider(Set<File> mainSourceFolders, Set<File> testSourceFolders, JavaCompile task, String testFrameworkAPI, List<String> testRequires, JavaModuleDetector moduleDetector, ModuleInfoParser moduleInfoParser) {
24+
public WhiteboxTestCompileArgumentProvider(Set<File> mainSourceFolders, Set<File> testSourceFolders, JavaCompile task, Provider<List<String>> testRequires, JavaModuleDetector moduleDetector, ModuleInfoParser moduleInfoParser) {
2425
this.mainSourceFolders = mainSourceFolders;
2526
this.testSourceFolders = testSourceFolders;
2627
this.task = task;
27-
this.testFrameworkAPI = testFrameworkAPI;
2828
this.testRequires = testRequires;
2929
this.moduleDetector = moduleDetector;
3030
this.moduleInfoParser = moduleInfoParser;
@@ -42,13 +42,7 @@ public Iterable<String> asArguments() {
4242
args.add("--module-path");
4343
args.add(moduleDetector.inferModulePath(true, task.getClasspath()).getFiles().stream().map(File::getPath).collect(Collectors.joining(cpSeparator)));
4444

45-
// Add module dependency to test framework
46-
args.add("--add-modules");
47-
args.add(testFrameworkAPI);
48-
args.add("--add-reads");
49-
args.add(moduleName + "=" + testFrameworkAPI);
50-
51-
for (String testRequires : testRequires) {
45+
for (String testRequires : testRequires.get()) {
5246
args.add("--add-modules");
5347
args.add(testRequires);
5448
args.add("--add-reads");

0 commit comments

Comments
 (0)