Skip to content

Commit 4625e92

Browse files
committed
Break dependency between TestCompiler and AOT
This commit improves `TestCompiler` with a `with` function that allows to customize a test compiler instance. Rather than `TestCompiler` knowing about `TestGenerationContext`, the latter implements the function so that it can be passed as is. See spring-projectsgh-29175
1 parent 2f84096 commit 4625e92

17 files changed

+108
-37
lines changed

spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyBeanRegistrationAotProcessorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ private void compile(BiConsumer<DefaultListableBeanFactory, Compiled> result) {
151151
.build());
152152
});
153153
this.generationContext.writeGeneratedContent();
154-
TestCompiler.forSystem().withFiles(this.generationContext.getGeneratedFiles()).compile(compiled -> {
154+
TestCompiler.forSystem().with(this.generationContext).compile(compiled -> {
155155
DefaultListableBeanFactory freshBeanFactory = new DefaultListableBeanFactory();
156156
freshBeanFactory.setBeanClassLoader(compiled.getClassLoader());
157157
compiled.getInstance(Consumer.class).accept(freshBeanFactory);

spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanRegistrationAotContributionTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ private void compile(RegisteredBean registeredBean,
176176

177177
});
178178
this.generationContext.writeGeneratedContent();
179-
TestCompiler.forSystem().withFiles(this.generationContext.getGeneratedFiles()).compile(compiled ->
179+
TestCompiler.forSystem().with(this.generationContext).compile(compiled ->
180180
result.accept(compiled.getInstance(BiFunction.class), compiled));
181181
}
182182

spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ private void compile(MethodReference method,
425425
.addCode("return $L;", methodInvocation).build());
426426
});
427427
this.generationContext.writeGeneratedContent();
428-
TestCompiler.forSystem().withFiles(this.generationContext.getGeneratedFiles()).compile(compiled ->
428+
TestCompiler.forSystem().with(this.generationContext).compile(compiled ->
429429
result.accept((RootBeanDefinition) compiled.getInstance(Supplier.class).get(), compiled));
430430
}
431431

spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertiesCodeGeneratorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ private void compile(
429429
.addStatement("return beanDefinition").build());
430430
});
431431
this.generationContext.writeGeneratedContent();
432-
TestCompiler.forSystem().withFiles(this.generationContext.getGeneratedFiles()).compile(compiled -> {
432+
TestCompiler.forSystem().with(this.generationContext).compile(compiled -> {
433433
RootBeanDefinition suppliedBeanDefinition = (RootBeanDefinition) compiled
434434
.getInstance(Supplier.class).get();
435435
result.accept(suppliedBeanDefinition, compiled);

spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ private void compile(Object value, BiConsumer<Object, Compiled> result) {
7676
.returns(Object.class).addStatement("return $L", generatedCode).build());
7777
});
7878
generationContext.writeGeneratedContent();
79-
TestCompiler.forSystem().withFiles(generationContext.getGeneratedFiles()).compile(compiled ->
79+
TestCompiler.forSystem().with(generationContext).compile(compiled ->
8080
result.accept(compiled.getInstance(Supplier.class).get(), compiled));
8181
}
8282

spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContributionTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ private void compile(
167167
.build());
168168
});
169169
this.generationContext.writeGeneratedContent();
170-
TestCompiler.forSystem().withFiles(this.generationContext.getGeneratedFiles()).compile(compiled ->
170+
TestCompiler.forSystem().with(this.generationContext).compile(compiled ->
171171
result.accept(compiled.getInstance(Consumer.class), compiled));
172172
}
173173

spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ private void compile(DefaultListableBeanFactory beanFactory,
317317
.addStatement("return $L", generatedCode).build());
318318
});
319319
this.generationContext.writeGeneratedContent();
320-
TestCompiler.forSystem().withFiles(this.generationContext.getGeneratedFiles()).compile(compiled ->
320+
TestCompiler.forSystem().with(this.generationContext).compile(compiled ->
321321
result.accept((InstanceSupplier<?>) compiled.getInstance(Supplier.class).get(), compiled));
322322
}
323323

spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorAotContributionTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ private void compile(BiConsumer<Consumer<DefaultListableBeanFactory>, Compiled>
165165
.build());
166166
});
167167
generationContext.writeGeneratedContent();
168-
TestCompiler.forSystem().withFiles(generationContext.getGeneratedFiles()).compile(compiled ->
168+
TestCompiler.forSystem().with(generationContext).compile(compiled ->
169169
result.accept(compiled.getInstance(Consumer.class), compiled));
170170
}
171171

@@ -297,7 +297,7 @@ private void compile(BiConsumer<Consumer<GenericApplicationContext>, Compiled> r
297297
.build());
298298
});
299299
generationContext.writeGeneratedContent();
300-
TestCompiler.forSystem().withFiles(generationContext.getGeneratedFiles()).compile(compiled ->
300+
TestCompiler.forSystem().with(generationContext).compile(compiled ->
301301
result.accept(compiled.getInstance(Consumer.class), compiled));
302302
}
303303

spring-context/src/test/java/org/springframework/context/aot/ApplicationContextAotGeneratorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ private void testCompiledResult(GenericApplicationContext applicationContext,
315315
@SuppressWarnings({ "rawtypes", "unchecked" })
316316
private void testCompiledResult(TestGenerationContext generationContext,
317317
BiConsumer<ApplicationContextInitializer<GenericApplicationContext>, Compiled> result) {
318-
TestCompiler.forSystem().withFiles(generationContext.getGeneratedFiles()).compile(compiled ->
318+
TestCompiler.forSystem().with(generationContext).compile(compiled ->
319319
result.accept(compiled.getInstance(ApplicationContextInitializer.class), compiled));
320320
}
321321

spring-context/src/test/java/org/springframework/context/generator/ApplicationContextAotGeneratorRuntimeHintsTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ private void compile(GenericApplicationContext applicationContext, BiConsumer<Ru
8686
TestGenerationContext generationContext = new TestGenerationContext();
8787
generator.processAheadOfTime(applicationContext, generationContext);
8888
generationContext.writeGeneratedContent();
89-
TestCompiler.forSystem().withFiles(generationContext.getGeneratedFiles()).compile(compiled -> {
89+
TestCompiler.forSystem().with(generationContext).compile(compiled -> {
9090
ApplicationContextInitializer instance = compiled.getInstance(ApplicationContextInitializer.class);
9191
GenericApplicationContext freshContext = new GenericApplicationContext();
9292
RuntimeHintsInvocations recordedInvocations = RuntimeHintsRecorder.record(() -> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2002-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.aot.test.generate;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import org.springframework.aot.generate.GeneratedFiles.Kind;
23+
import org.springframework.aot.generate.InMemoryGeneratedFiles;
24+
import org.springframework.core.test.tools.ClassFile;
25+
import org.springframework.core.test.tools.ResourceFile;
26+
import org.springframework.core.test.tools.SourceFile;
27+
import org.springframework.core.test.tools.TestCompiler;
28+
29+
/**
30+
* {@link TestCompiler} utilities for generated files.
31+
*
32+
* @author Stephane Nicoll
33+
* @since 6.0
34+
*/
35+
public abstract class GeneratedFilesTestCompilerUtils {
36+
37+
/**
38+
* Apply the specified {@link InMemoryGeneratedFiles} to the specified {@link TestCompiler}.
39+
* @param testCompiler the compiler to configure
40+
* @param generatedFiles the generated files to apply
41+
* @return a new {@link TestCompiler} instance configured with the generated files
42+
*/
43+
public static TestCompiler configure(TestCompiler testCompiler, InMemoryGeneratedFiles generatedFiles) {
44+
List<SourceFile> sourceFiles = new ArrayList<>();
45+
generatedFiles.getGeneratedFiles(Kind.SOURCE).forEach(
46+
(path, inputStreamSource) -> sourceFiles.add(SourceFile.of(inputStreamSource)));
47+
List<ResourceFile> resourceFiles = new ArrayList<>();
48+
generatedFiles.getGeneratedFiles(Kind.RESOURCE).forEach(
49+
(path, inputStreamSource) -> resourceFiles.add(ResourceFile.of(path, inputStreamSource)));
50+
List<ClassFile> classFiles = new ArrayList<>();
51+
generatedFiles.getGeneratedFiles(Kind.CLASS).forEach(
52+
(path, inputStreamSource) -> classFiles.add(ClassFile.of(
53+
ClassFile.toClassName(path), inputStreamSource)));
54+
return testCompiler.withSources(sourceFiles).withResources(resourceFiles).withClasses(classFiles);
55+
}
56+
}

spring-core-test/src/main/java/org/springframework/aot/test/generate/TestGenerationContext.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,24 @@
1616

1717
package org.springframework.aot.test.generate;
1818

19+
import java.util.function.Function;
20+
1921
import org.springframework.aot.generate.ClassNameGenerator;
2022
import org.springframework.aot.generate.DefaultGenerationContext;
2123
import org.springframework.aot.generate.GenerationContext;
2224
import org.springframework.aot.generate.InMemoryGeneratedFiles;
25+
import org.springframework.core.test.tools.TestCompiler;
2326

2427
/**
2528
* {@link GenerationContext} test implementation that uses
26-
* {@link InMemoryGeneratedFiles}.
29+
* {@link InMemoryGeneratedFiles} and can configure a {@link TestCompiler}
30+
* instance.
2731
*
2832
* @author Stephane Nicoll
2933
* @author Sam Brannen
3034
* @since 6.0
3135
*/
32-
public class TestGenerationContext extends DefaultGenerationContext {
36+
public class TestGenerationContext extends DefaultGenerationContext implements Function<TestCompiler, TestCompiler> {
3337

3438
/**
3539
* Create an instance using the specified {@link ClassNameGenerator}.
@@ -60,4 +64,15 @@ public InMemoryGeneratedFiles getGeneratedFiles() {
6064
return (InMemoryGeneratedFiles) super.getGeneratedFiles();
6165
}
6266

67+
/**
68+
* Configure the specified {@link TestCompiler} with the state of this context.
69+
* @param testCompiler the compiler to configure
70+
* @return a new {@link TestCompiler} instance configured with the generated files
71+
* @see TestCompiler#with(Function)
72+
*/
73+
@Override
74+
public TestCompiler apply(TestCompiler testCompiler) {
75+
return GeneratedFilesTestCompilerUtils.configure(testCompiler, getGeneratedFiles());
76+
}
77+
6378
}

spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.List;
2424
import java.util.Locale;
2525
import java.util.function.Consumer;
26+
import java.util.function.Function;
2627

2728
import javax.annotation.processing.Processor;
2829
import javax.tools.Diagnostic;
@@ -33,8 +34,6 @@
3334
import javax.tools.StandardJavaFileManager;
3435
import javax.tools.ToolProvider;
3536

36-
import org.springframework.aot.generate.GeneratedFiles.Kind;
37-
import org.springframework.aot.generate.InMemoryGeneratedFiles;
3837
import org.springframework.lang.Nullable;
3938

4039
/**
@@ -93,23 +92,12 @@ public static TestCompiler forCompiler(JavaCompiler javaCompiler) {
9392
}
9493

9594
/**
96-
* Create a new {@code TestCompiler} instance with additional generated
97-
* source, resource, and class files.
98-
* @param generatedFiles the generated files to add
99-
* @return a new {@code TestCompiler} instance
95+
* Apply customization to this compiler.
96+
* @param customizer the customizer to call
97+
* @return a new {@code TestCompiler} instance with the customizations applied
10098
*/
101-
public TestCompiler withFiles(InMemoryGeneratedFiles generatedFiles) {
102-
List<SourceFile> sourceFiles = new ArrayList<>();
103-
generatedFiles.getGeneratedFiles(Kind.SOURCE).forEach(
104-
(path, inputStreamSource) -> sourceFiles.add(SourceFile.of(inputStreamSource)));
105-
List<ResourceFile> resourceFiles = new ArrayList<>();
106-
generatedFiles.getGeneratedFiles(Kind.RESOURCE).forEach(
107-
(path, inputStreamSource) -> resourceFiles.add(ResourceFile.of(path, inputStreamSource)));
108-
List<ClassFile> classFiles = new ArrayList<>();
109-
generatedFiles.getGeneratedFiles(Kind.CLASS).forEach(
110-
(path, inputStreamSource) -> classFiles.add(ClassFile.of(
111-
ClassFile.toClassName(path), inputStreamSource)));
112-
return withSources(sourceFiles).withResources(resourceFiles).withClasses(classFiles);
99+
public TestCompiler with(Function<TestCompiler, TestCompiler> customizer) {
100+
return customizer.apply(this);
113101
}
114102

115103
/**

spring-orm/src/test/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ private void compile(GenericApplicationContext applicationContext,
109109
TestGenerationContext generationContext = new TestGenerationContext();
110110
generator.processAheadOfTime(applicationContext, generationContext);
111111
generationContext.writeGeneratedContent();
112-
TestCompiler.forSystem().withFiles(generationContext.getGeneratedFiles()).compile(compiled ->
112+
TestCompiler.forSystem().with(generationContext).compile(compiled ->
113113
result.accept(compiled.getInstance(ApplicationContextInitializer.class), compiled));
114114
}
115115

spring-orm/src/test/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessorAotContributionTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ private void testCompile(RegisteredBean registeredBean,
175175
BeanRegistrationCode beanRegistrationCode = mock(BeanRegistrationCode.class);
176176
contribution.applyTo(generationContext, beanRegistrationCode);
177177
generationContext.writeGeneratedContent();
178-
TestCompiler.forSystem().withFiles(generationContext.getGeneratedFiles())
178+
TestCompiler.forSystem().with(generationContext)
179179
.compile(compiled -> result.accept(new Invoker(compiled), compiled));
180180
}
181181

spring-test/src/test/java/org/springframework/test/context/aot/AotIntegrationTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.nio.file.Paths;
2222
import java.util.List;
2323
import java.util.Set;
24+
import java.util.function.Function;
2425
import java.util.stream.Stream;
2526

2627
import org.junit.jupiter.api.Disabled;
@@ -37,6 +38,7 @@
3738
import org.springframework.aot.AotDetector;
3839
import org.springframework.aot.generate.GeneratedFiles.Kind;
3940
import org.springframework.aot.generate.InMemoryGeneratedFiles;
41+
import org.springframework.aot.test.generate.GeneratedFilesTestCompilerUtils;
4042
import org.springframework.core.test.tools.CompileWithForkedClassLoader;
4143
import org.springframework.core.test.tools.TestCompiler;
4244
import org.springframework.test.context.aot.samples.basic.BasicSpringJupiterSharedConfigTests;
@@ -92,7 +94,7 @@ void endToEndTests() {
9294
assertThat(sourceFiles).containsExactlyInAnyOrder(expectedSourceFilesForBasicSpringTests);
9395

9496
// AOT BUILD-TIME: COMPILATION
95-
TestCompiler.forSystem().withFiles(generatedFiles)
97+
TestCompiler.forSystem().with(setupGeneratedFiles(generatedFiles))
9698
// .printFiles(System.out)
9799
.compile(compiled ->
98100
// AOT RUN-TIME: EXECUTION
@@ -123,13 +125,17 @@ void endToEndTestsForEntireSpringTestModule() {
123125
generator.processAheadOfTime(testClasses.stream());
124126

125127
// AOT BUILD-TIME: COMPILATION
126-
TestCompiler.forSystem().withFiles(generatedFiles)
128+
TestCompiler.forSystem().with(setupGeneratedFiles(generatedFiles))
127129
// .printFiles(System.out)
128130
.compile(compiled ->
129131
// AOT RUN-TIME: EXECUTION
130132
runTestsInAotMode(testClasses));
131133
}
132134

135+
private static Function<TestCompiler, TestCompiler> setupGeneratedFiles(InMemoryGeneratedFiles generatedFiles) {
136+
return testCompiler -> GeneratedFilesTestCompilerUtils.configure(testCompiler, generatedFiles);
137+
}
138+
133139
private static void runTestsInAotMode(List<Class<?>> testClasses) {
134140
runTestsInAotMode(-1, testClasses);
135141
}

spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.ArrayList;
2121
import java.util.List;
2222
import java.util.Set;
23+
import java.util.function.Function;
2324
import java.util.stream.Stream;
2425

2526
import javax.sql.DataSource;
@@ -33,6 +34,7 @@
3334
import org.springframework.aot.hint.MemberCategory;
3435
import org.springframework.aot.hint.RuntimeHints;
3536
import org.springframework.aot.hint.TypeReference;
37+
import org.springframework.aot.test.generate.GeneratedFilesTestCompilerUtils;
3638
import org.springframework.context.ApplicationContext;
3739
import org.springframework.context.ApplicationContextInitializer;
3840
import org.springframework.context.ConfigurableApplicationContext;
@@ -83,6 +85,10 @@
8385
@CompileWithForkedClassLoader
8486
class TestContextAotGeneratorTests extends AbstractAotTests {
8587

88+
private static Function<TestCompiler, TestCompiler> setupGeneratedFiles(InMemoryGeneratedFiles generatedFiles) {
89+
return testCompiler -> GeneratedFilesTestCompilerUtils.configure(testCompiler, generatedFiles);
90+
}
91+
8692
/**
8793
* End-to-end tests within the scope of the {@link TestContextAotGenerator}.
8894
*
@@ -110,7 +116,7 @@ void endToEndTests() {
110116
List<String> sourceFiles = generatedFiles.getGeneratedFiles(Kind.SOURCE).keySet().stream().toList();
111117
assertThat(sourceFiles).containsExactlyInAnyOrder(expectedSourceFiles);
112118

113-
TestCompiler.forSystem().withFiles(generatedFiles).compile(ThrowingConsumer.of(compiled -> {
119+
TestCompiler.forSystem().with(setupGeneratedFiles(generatedFiles)).compile(ThrowingConsumer.of(compiled -> {
114120
try {
115121
System.setProperty(AotDetector.AOT_ENABLED, "true");
116122
AotTestAttributesFactory.reset();
@@ -321,7 +327,7 @@ private void processAheadOfTime(Set<Class<?>> testClasses, ThrowingConsumer<Appl
321327
InMemoryGeneratedFiles generatedFiles = new InMemoryGeneratedFiles();
322328
TestContextAotGenerator generator = new TestContextAotGenerator(generatedFiles);
323329
List<Mapping> mappings = processAheadOfTime(generator, testClasses);
324-
TestCompiler.forSystem().withFiles(generatedFiles).compile(ThrowingConsumer.of(compiled -> {
330+
TestCompiler.forSystem().with(setupGeneratedFiles(generatedFiles)).compile(ThrowingConsumer.of(compiled -> {
325331
for (Mapping mapping : mappings) {
326332
MergedContextConfiguration mergedConfig = mapping.mergedConfig();
327333
ApplicationContextInitializer<ConfigurableApplicationContext> contextInitializer =

0 commit comments

Comments
 (0)