mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
Replace Spring Boot TestCompiler with Spring Framework's version
See gh-31266
This commit is contained in:
parent
8b2fd6a05a
commit
d25a99692f
@ -12,5 +12,6 @@ dependencies {
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
testImplementation("org.assertj:assertj-core")
|
||||
testImplementation("org.springframework:spring-core")
|
||||
testImplementation("org.springframework:spring-core-test")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
}
|
||||
|
@ -16,145 +16,171 @@
|
||||
|
||||
package org.springframework.boot.autoconfigureprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.core.test.tools.SourceFile;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutoConfigureAnnotationProcessor}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Moritz Halbritter
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class AutoConfigureAnnotationProcessorTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
private TestCompiler compiler;
|
||||
|
||||
@BeforeEach
|
||||
void createCompiler() throws IOException {
|
||||
this.compiler = new TestCompiler(this.tempDir);
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotatedClass() throws Exception {
|
||||
Properties properties = compile(TestClassConfiguration.class);
|
||||
assertThat(properties).hasSize(7);
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestClassConfiguration.ConditionalOnClass",
|
||||
"java.io.InputStream,org.springframework.boot.autoconfigureprocessor."
|
||||
+ "TestClassConfiguration$Nested,org.springframework.foo");
|
||||
assertThat(properties).containsKey("org.springframework.boot.autoconfigureprocessor.TestClassConfiguration");
|
||||
assertThat(properties)
|
||||
.containsKey("org.springframework.boot.autoconfigureprocessor.TestClassConfiguration$Nested");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestClassConfiguration.ConditionalOnBean",
|
||||
"java.io.OutputStream");
|
||||
assertThat(properties).containsEntry("org.springframework.boot.autoconfigureprocessor."
|
||||
+ "TestClassConfiguration.ConditionalOnSingleCandidate", "java.io.OutputStream");
|
||||
assertThat(properties).containsEntry("org.springframework.boot.autoconfigureprocessor."
|
||||
+ "TestClassConfiguration.ConditionalOnWebApplication", "SERVLET");
|
||||
compile(TestClassConfiguration.class, (properties) -> {
|
||||
assertThat(properties).hasSize(7);
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestClassConfiguration.ConditionalOnClass",
|
||||
"java.io.InputStream,org.springframework.boot.autoconfigureprocessor."
|
||||
+ "TestClassConfiguration$Nested,org.springframework.foo");
|
||||
assertThat(properties)
|
||||
.containsKey("org.springframework.boot.autoconfigureprocessor.TestClassConfiguration");
|
||||
assertThat(properties)
|
||||
.containsKey("org.springframework.boot.autoconfigureprocessor.TestClassConfiguration$Nested");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestClassConfiguration.ConditionalOnBean",
|
||||
"java.io.OutputStream");
|
||||
assertThat(properties).containsEntry("org.springframework.boot.autoconfigureprocessor."
|
||||
+ "TestClassConfiguration.ConditionalOnSingleCandidate", "java.io.OutputStream");
|
||||
assertThat(properties).containsEntry("org.springframework.boot.autoconfigureprocessor."
|
||||
+ "TestClassConfiguration.ConditionalOnWebApplication", "SERVLET");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotatedClassWithOnlyAutoConfiguration() throws Exception {
|
||||
Properties properties = compile(TestAutoConfigurationOnlyConfiguration.class);
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationOnlyConfiguration", "");
|
||||
assertThat(properties).doesNotContainEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationOnlyConfiguration.AutoConfigureAfter",
|
||||
"");
|
||||
assertThat(properties).doesNotContainEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationOnlyConfiguration.AutoConfigureBefore",
|
||||
"");
|
||||
void annotatedClassWithOnlyAutoConfiguration() {
|
||||
compile(TestAutoConfigurationOnlyConfiguration.class, (properties) -> {
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationOnlyConfiguration", "");
|
||||
assertThat(properties).doesNotContainEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationOnlyConfiguration.AutoConfigureAfter",
|
||||
"");
|
||||
assertThat(properties).doesNotContainEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationOnlyConfiguration.AutoConfigureBefore",
|
||||
"");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotatedClassWithOnBeanThatHasName() throws Exception {
|
||||
Properties properties = compile(TestOnBeanWithNameClassConfiguration.class);
|
||||
assertThat(properties).hasSize(2);
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestOnBeanWithNameClassConfiguration.ConditionalOnBean",
|
||||
"");
|
||||
void annotatedClassWithOnBeanThatHasName() {
|
||||
compile(TestOnBeanWithNameClassConfiguration.class, (properties) -> {
|
||||
assertThat(properties).hasSize(2);
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestOnBeanWithNameClassConfiguration.ConditionalOnBean",
|
||||
"");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotatedMethod() throws Exception {
|
||||
Properties properties = compile(TestMethodConfiguration.class);
|
||||
assertThat(properties).isNull();
|
||||
void annotatedMethod() {
|
||||
process(TestMethodConfiguration.class, (properties) -> assertThat(properties).isNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotatedClassWithOrder() throws Exception {
|
||||
Properties properties = compile(TestOrderedClassConfiguration.class);
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestOrderedClassConfiguration.ConditionalOnClass",
|
||||
"java.io.InputStream,java.io.OutputStream");
|
||||
assertThat(properties).containsEntry("org.springframework.boot.autoconfigureprocessor."
|
||||
+ "TestOrderedClassConfiguration.AutoConfigureBefore", "test.before1,test.before2");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestOrderedClassConfiguration.AutoConfigureAfter",
|
||||
"java.io.ObjectInputStream");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestOrderedClassConfiguration.AutoConfigureOrder",
|
||||
"123");
|
||||
void annotatedClassWithOrder() {
|
||||
compile(TestOrderedClassConfiguration.class, (properties) -> {
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestOrderedClassConfiguration.ConditionalOnClass",
|
||||
"java.io.InputStream,java.io.OutputStream");
|
||||
assertThat(properties).containsEntry("org.springframework.boot.autoconfigureprocessor."
|
||||
+ "TestOrderedClassConfiguration.AutoConfigureBefore", "test.before1,test.before2");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestOrderedClassConfiguration.AutoConfigureAfter",
|
||||
"java.io.ObjectInputStream");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestOrderedClassConfiguration.AutoConfigureOrder",
|
||||
"123");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotatedClassWithAutoConfiguration() throws Exception {
|
||||
Properties properties = compile(TestAutoConfigurationConfiguration.class);
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationConfiguration", "");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationConfiguration.AutoConfigureBefore",
|
||||
"java.io.InputStream,test.before1,test.before2");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationConfiguration.AutoConfigureAfter",
|
||||
"java.io.OutputStream,test.after1,test.after2");
|
||||
compile(TestAutoConfigurationConfiguration.class, (properties) -> {
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationConfiguration", "");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationConfiguration.AutoConfigureBefore",
|
||||
"java.io.InputStream,test.before1,test.before2");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfigurationConfiguration.AutoConfigureAfter",
|
||||
"java.io.OutputStream,test.after1,test.after2");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void annotatedClassWithAutoConfigurationMerged() throws Exception {
|
||||
Properties properties = compile(TestMergedAutoConfigurationConfiguration.class);
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestMergedAutoConfigurationConfiguration", "");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestMergedAutoConfigurationConfiguration.AutoConfigureBefore",
|
||||
"java.io.InputStream,test.before1,test.before2,java.io.ObjectInputStream,test.before3,test.before4");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestMergedAutoConfigurationConfiguration.AutoConfigureAfter",
|
||||
"java.io.OutputStream,test.after1,test.after2,java.io.ObjectOutputStream,test.after3,test.after4");
|
||||
compile(TestMergedAutoConfigurationConfiguration.class, (properties) -> {
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestMergedAutoConfigurationConfiguration", "");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestMergedAutoConfigurationConfiguration.AutoConfigureBefore",
|
||||
"java.io.InputStream,test.before1,test.before2,java.io.ObjectInputStream,test.before3,test.before4");
|
||||
assertThat(properties).containsEntry(
|
||||
"org.springframework.boot.autoconfigureprocessor.TestMergedAutoConfigurationConfiguration.AutoConfigureAfter",
|
||||
"java.io.OutputStream,test.after1,test.after2,java.io.ObjectOutputStream,test.after3,test.after4");
|
||||
});
|
||||
}
|
||||
|
||||
@Test // gh-19370
|
||||
void propertiesAreFullRepeatable() throws Exception {
|
||||
String first = new String(
|
||||
FileCopyUtils.copyToByteArray(process(TestOrderedClassConfiguration.class).getWrittenFile()));
|
||||
String second = new String(
|
||||
FileCopyUtils.copyToByteArray(process(TestOrderedClassConfiguration.class).getWrittenFile()));
|
||||
assertThat(first).isEqualTo(second).doesNotContain("#");
|
||||
process(TestOrderedClassConfiguration.class, (firstFile) -> {
|
||||
String first = getFileContents(firstFile);
|
||||
process(TestOrderedClassConfiguration.class, (secondFile) -> {
|
||||
String second = getFileContents(secondFile);
|
||||
assertThat(first).isEqualTo(second).doesNotContain("#");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private Properties compile(Class<?>... types) throws IOException {
|
||||
return process(types).getWrittenProperties();
|
||||
private void compile(Class<?> type, Consumer<Properties> consumer) {
|
||||
process(type, (writtenFile) -> consumer.accept(getWrittenProperties(writtenFile)));
|
||||
}
|
||||
|
||||
private TestAutoConfigureAnnotationProcessor process(Class<?>... types) {
|
||||
TestAutoConfigureAnnotationProcessor processor = new TestAutoConfigureAnnotationProcessor(
|
||||
this.compiler.getOutputLocation());
|
||||
this.compiler.getTask(types).call(processor);
|
||||
return processor;
|
||||
private void process(Class<?> type, Consumer<InputStream> consumer) {
|
||||
TestAutoConfigureAnnotationProcessor processor = new TestAutoConfigureAnnotationProcessor();
|
||||
SourceFile sourceFile = SourceFile.forTestClass(type);
|
||||
TestCompiler compiler = TestCompiler.forSystem().withProcessors(processor).withSources(sourceFile);
|
||||
compiler.compile((compiled) -> {
|
||||
InputStream propertiesFile = compiled.getClassLoader()
|
||||
.getResourceAsStream(AutoConfigureAnnotationProcessor.PROPERTIES_PATH);
|
||||
consumer.accept(propertiesFile);
|
||||
});
|
||||
}
|
||||
|
||||
private Properties getWrittenProperties(InputStream inputStream) {
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
properties.load(inputStream);
|
||||
return properties;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
fail("Error reading properties", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getFileContents(InputStream inputStream) {
|
||||
try {
|
||||
return new String(inputStream.readAllBytes());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
fail("Error reading contents of properties file", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,12 +16,8 @@
|
||||
|
||||
package org.springframework.boot.autoconfigureprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
|
||||
@ -29,6 +25,7 @@ import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
* Version of {@link AutoConfigureAnnotationProcessor} used for testing.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@SupportedAnnotationTypes({ "org.springframework.boot.autoconfigureprocessor.TestConditionalOnClass",
|
||||
"org.springframework.boot.autoconfigureprocessor.TestConditionalOnBean",
|
||||
@ -40,10 +37,7 @@ import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
"org.springframework.boot.autoconfigureprocessor.TestAutoConfiguration" })
|
||||
public class TestAutoConfigureAnnotationProcessor extends AutoConfigureAnnotationProcessor {
|
||||
|
||||
private final File outputLocation;
|
||||
|
||||
public TestAutoConfigureAnnotationProcessor(File outputLocation) {
|
||||
this.outputLocation = outputLocation;
|
||||
public TestAutoConfigureAnnotationProcessor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -69,20 +63,4 @@ public class TestAutoConfigureAnnotationProcessor extends AutoConfigureAnnotatio
|
||||
return generators;
|
||||
}
|
||||
|
||||
public Properties getWrittenProperties() throws IOException {
|
||||
File file = getWrittenFile();
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
try (FileInputStream inputStream = new FileInputStream(file)) {
|
||||
Properties properties = new Properties();
|
||||
properties.load(inputStream);
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
public File getWrittenFile() {
|
||||
return new File(this.outputLocation, PROPERTIES_PATH);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ dependencies {
|
||||
testCompileOnly("com.google.code.findbugs:jsr305:3.0.2")
|
||||
testImplementation(enforcedPlatform(project(":spring-boot-project:spring-boot-dependencies")))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
testImplementation("org.springframework:spring-core-test")
|
||||
testImplementation("jakarta.validation:jakarta.validation-api")
|
||||
testImplementation("org.assertj:assertj-core")
|
||||
testImplementation("org.hamcrest:hamcrest-library")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -36,6 +36,7 @@ import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller;
|
||||
* A {@code MetadataStore} is responsible for the storage of metadata on the filesystem.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Scott Frederick
|
||||
* @since 1.2.2
|
||||
*/
|
||||
public class MetadataStore {
|
||||
@ -76,7 +77,7 @@ public class MetadataStore {
|
||||
}
|
||||
|
||||
private ConfigurationMetadata readMetadata(InputStream in) throws IOException {
|
||||
try {
|
||||
try (in) {
|
||||
return new JsonMarshaller().read(in);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
@ -87,9 +88,6 @@ public class MetadataStore {
|
||||
"Invalid additional meta-data in '" + METADATA_PATH + "': " + ex.getMessage(),
|
||||
Diagnostic.Kind.ERROR);
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
private FileObject getMetadataResource() throws IOException {
|
||||
@ -104,8 +102,26 @@ public class MetadataStore {
|
||||
// Most build systems will have copied the file to the class output location
|
||||
FileObject fileObject = this.environment.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "",
|
||||
ADDITIONAL_METADATA_PATH);
|
||||
File file = locateAdditionalMetadataFile(new File(fileObject.toUri()));
|
||||
return (file.exists() ? new FileInputStream(file) : fileObject.toUri().toURL().openStream());
|
||||
InputStream inputStream = getMetadataStream(fileObject);
|
||||
if (inputStream != null) {
|
||||
return inputStream;
|
||||
}
|
||||
try {
|
||||
File file = locateAdditionalMetadataFile(new File(fileObject.toUri()));
|
||||
return (file.exists() ? new FileInputStream(file) : fileObject.toUri().toURL().openStream());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getMetadataStream(FileObject fileObject) {
|
||||
try {
|
||||
return fileObject.openInputStream();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
File locateAdditionalMetadataFile(File standardLocation) throws IOException {
|
||||
|
@ -16,50 +16,58 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.test.CompiledMetadataReader;
|
||||
import org.springframework.boot.configurationprocessor.test.TestConfigurationMetadataAnnotationProcessor;
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler;
|
||||
import org.springframework.core.test.tools.ResourceFile;
|
||||
import org.springframework.core.test.tools.SourceFile;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
|
||||
/**
|
||||
* Base test infrastructure for metadata generation tests.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
public abstract class AbstractMetadataGenerationTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
private TestCompiler compiler;
|
||||
|
||||
@BeforeEach
|
||||
void createCompiler() throws IOException {
|
||||
this.compiler = new TestCompiler(this.tempDir);
|
||||
}
|
||||
|
||||
protected TestCompiler getCompiler() {
|
||||
return this.compiler;
|
||||
}
|
||||
private static final String ADDITIONAL_METADATA_FILE = "META-INF/additional-spring-configuration-metadata.json";
|
||||
|
||||
protected ConfigurationMetadata compile(Class<?>... types) {
|
||||
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(
|
||||
this.compiler.getOutputLocation());
|
||||
this.compiler.getTask(types).call(processor);
|
||||
return processor.getMetadata();
|
||||
TestCompiler compiler = TestCompiler.forSystem().withSources(sourceFilesOf(types));
|
||||
return compile(compiler);
|
||||
}
|
||||
|
||||
protected ConfigurationMetadata compile(File... sources) {
|
||||
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(
|
||||
this.compiler.getOutputLocation());
|
||||
this.compiler.getTask(Arrays.asList(sources)).call(processor);
|
||||
return processor.getMetadata();
|
||||
protected ConfigurationMetadata compile(String additionalMetadata, Class<?> type, Class<?>... types) {
|
||||
TestCompiler compiler = TestCompiler.forSystem().withSources(sourceFilesOf(type))
|
||||
.withSources(sourceFilesOf(types))
|
||||
.withResources(ResourceFile.of(ADDITIONAL_METADATA_FILE, additionalMetadata));
|
||||
return compile(compiler);
|
||||
}
|
||||
|
||||
protected ConfigurationMetadata compile(String... source) {
|
||||
TestCompiler compiler = TestCompiler.forSystem().withSources(sourceFilesOf(source));
|
||||
return compile(compiler);
|
||||
}
|
||||
|
||||
private ConfigurationMetadata compile(TestCompiler compiler) {
|
||||
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor();
|
||||
compiler = compiler.withProcessors(processor);
|
||||
AtomicReference<ConfigurationMetadata> configurationMetadata = new AtomicReference<>();
|
||||
compiler.compile((compiled) -> configurationMetadata.set(CompiledMetadataReader.getMetadata(compiled)));
|
||||
return configurationMetadata.get();
|
||||
}
|
||||
|
||||
private List<SourceFile> sourceFilesOf(Class<?>... types) {
|
||||
return Arrays.stream(types).map(SourceFile::forTestClass).toList();
|
||||
}
|
||||
|
||||
private List<SourceFile> sourceFilesOf(String... content) {
|
||||
return Arrays.stream(content).map(SourceFile::of).toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,13 +16,9 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
|
||||
@ -60,9 +56,10 @@ import org.springframework.boot.configurationsample.specific.InvalidDefaultValue
|
||||
import org.springframework.boot.configurationsample.specific.InvalidDoubleRegistrationProperties;
|
||||
import org.springframework.boot.configurationsample.specific.SimplePojo;
|
||||
import org.springframework.boot.configurationsample.specific.StaticAccessor;
|
||||
import org.springframework.core.test.tools.CompilationException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConfigurationMetadataAnnotationProcessor}.
|
||||
@ -73,6 +70,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
* @author Kris De Volder
|
||||
* @author Jonas Keßler
|
||||
* @author Pavel Anisimov
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@ -374,26 +372,30 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene
|
||||
|
||||
@Test
|
||||
void invalidDoubleRegistration() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> compile(InvalidDoubleRegistrationProperties.class))
|
||||
.withMessageContaining("Compilation failed");
|
||||
assertThatExceptionOfType(CompilationException.class)
|
||||
.isThrownBy(() -> compile(InvalidDoubleRegistrationProperties.class))
|
||||
.withMessageContaining("Unable to compile source");
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructorParameterPropertyWithInvalidDefaultValueOnNumber() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> compile(InvalidDefaultValueNumberProperties.class))
|
||||
.withMessageContaining("Compilation failed");
|
||||
assertThatExceptionOfType(CompilationException.class)
|
||||
.isThrownBy(() -> compile(InvalidDefaultValueNumberProperties.class))
|
||||
.withMessageContaining("Unable to compile source");
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructorParameterPropertyWithInvalidDefaultValueOnFloatingPoint() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> compile(InvalidDefaultValueFloatingPointProperties.class))
|
||||
.withMessageContaining("Compilation failed");
|
||||
assertThatExceptionOfType(CompilationException.class)
|
||||
.isThrownBy(() -> compile(InvalidDefaultValueFloatingPointProperties.class))
|
||||
.withMessageContaining("Unable to compile source");
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructorParameterPropertyWithInvalidDefaultValueOnCharacter() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> compile(InvalidDefaultValueCharacterProperties.class))
|
||||
.withMessageContaining("Compilation failed");
|
||||
assertThatExceptionOfType(CompilationException.class)
|
||||
.isThrownBy(() -> compile(InvalidDefaultValueCharacterProperties.class))
|
||||
.withMessageContaining("Unable to compile source");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -411,31 +413,27 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordProperties(@TempDir File temp) throws IOException {
|
||||
File exampleRecord = new File(temp, "ExampleRecord.java");
|
||||
try (PrintWriter writer = new PrintWriter(new FileWriter(exampleRecord))) {
|
||||
writer.println("@org.springframework.boot.configurationsample.ConfigurationProperties(\"implicit\")");
|
||||
writer.println("public record ExampleRecord(String someString, Integer someInteger) {");
|
||||
writer.println("}");
|
||||
}
|
||||
ConfigurationMetadata metadata = compile(exampleRecord);
|
||||
void recordProperties() throws IOException {
|
||||
String source = """
|
||||
@org.springframework.boot.configurationsample.ConfigurationProperties("implicit")
|
||||
public record ExampleRecord(String someString, Integer someInteger) {
|
||||
}
|
||||
""";
|
||||
ConfigurationMetadata metadata = compile(source);
|
||||
assertThat(metadata).has(Metadata.withProperty("implicit.some-string"));
|
||||
assertThat(metadata).has(Metadata.withProperty("implicit.some-integer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void recordPropertiesWithDefaultValues(@TempDir File temp) throws IOException {
|
||||
File exampleRecord = new File(temp, "ExampleRecord.java");
|
||||
try (PrintWriter writer = new PrintWriter(new FileWriter(exampleRecord))) {
|
||||
writer.println(
|
||||
"@org.springframework.boot.configurationsample.ConfigurationProperties(\"record.defaults\")");
|
||||
writer.println("public record ExampleRecord(");
|
||||
writer.println("@org.springframework.boot.configurationsample.DefaultValue(\"An1s9n\") String someString,");
|
||||
writer.println("@org.springframework.boot.configurationsample.DefaultValue(\"594\") Integer someInteger");
|
||||
writer.println(") {");
|
||||
writer.println("}");
|
||||
}
|
||||
ConfigurationMetadata metadata = compile(exampleRecord);
|
||||
void recordPropertiesWithDefaultValues() throws IOException {
|
||||
String source = """
|
||||
@org.springframework.boot.configurationsample.ConfigurationProperties("record.defaults")
|
||||
public record ExampleRecord(
|
||||
@org.springframework.boot.configurationsample.DefaultValue("An1s9n") String someString,
|
||||
@org.springframework.boot.configurationsample.DefaultValue("594") Integer someInteger) {
|
||||
}
|
||||
""";
|
||||
ConfigurationMetadata metadata = compile(source);
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withProperty("record.defaults.some-string", String.class).withDefaultValue("An1s9n"));
|
||||
assertThat(metadata)
|
||||
@ -443,21 +441,20 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene
|
||||
}
|
||||
|
||||
@Test
|
||||
void multiConstructorRecordProperties(@TempDir File temp) throws IOException {
|
||||
File exampleRecord = new File(temp, "ExampleRecord.java");
|
||||
try (PrintWriter writer = new PrintWriter(new FileWriter(exampleRecord))) {
|
||||
writer.println("@org.springframework.boot.configurationsample.ConfigurationProperties(\"multi\")");
|
||||
writer.println("public record ExampleRecord(String someString, Integer someInteger) {");
|
||||
writer.println(" @org.springframework.boot.configurationsample.ConstructorBinding");
|
||||
writer.println(" public ExampleRecord(String someString) {");
|
||||
writer.println(" this(someString, 42);");
|
||||
writer.println(" }");
|
||||
writer.println(" public ExampleRecord(Integer someInteger) {");
|
||||
writer.println(" this(\"someString\", someInteger);");
|
||||
writer.println(" }");
|
||||
writer.println("}");
|
||||
}
|
||||
ConfigurationMetadata metadata = compile(exampleRecord);
|
||||
void multiConstructorRecordProperties() throws IOException {
|
||||
String source = """
|
||||
@org.springframework.boot.configurationsample.ConfigurationProperties("multi")
|
||||
public record ExampleRecord(String someString, Integer someInteger) {
|
||||
@org.springframework.boot.configurationsample.ConstructorBinding
|
||||
public ExampleRecord(String someString) {
|
||||
this(someString, 42);
|
||||
}
|
||||
public ExampleRecord(Integer someInteger) {
|
||||
this("someString", someInteger);
|
||||
}
|
||||
}
|
||||
""";
|
||||
ConfigurationMetadata metadata = compile(source);
|
||||
assertThat(metadata).has(Metadata.withProperty("multi.some-string"));
|
||||
assertThat(metadata).doesNotHave(Metadata.withProperty("multi.some-integer"));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Metadata generation tests for Actuator endpoints.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class EndpointMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@ -96,8 +97,8 @@ class EndpointMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@Test
|
||||
void incrementalEndpointBuildChangeGeneralEnabledFlag() throws Exception {
|
||||
TestProject project = new TestProject(this.tempDir, IncrementalEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
TestProject project = new TestProject(IncrementalEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.compile();
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withGroup("management.endpoint.incremental").fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", true));
|
||||
@ -105,7 +106,7 @@ class EndpointMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
project.replaceText(IncrementalEndpoint.class, "id = \"incremental\"",
|
||||
"id = \"incremental\", enableByDefault = false");
|
||||
metadata = project.incrementalBuild(IncrementalEndpoint.class);
|
||||
metadata = project.compile();
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withGroup("management.endpoint.incremental").fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", false));
|
||||
@ -115,15 +116,15 @@ class EndpointMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@Test
|
||||
void incrementalEndpointBuildChangeCacheFlag() throws Exception {
|
||||
TestProject project = new TestProject(this.tempDir, IncrementalEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
TestProject project = new TestProject(IncrementalEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.compile();
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withGroup("management.endpoint.incremental").fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", true));
|
||||
assertThat(metadata).has(cacheTtl("incremental"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
project.replaceText(IncrementalEndpoint.class, "@Nullable String param", "String param");
|
||||
metadata = project.incrementalBuild(IncrementalEndpoint.class);
|
||||
metadata = project.compile();
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withGroup("management.endpoint.incremental").fromSource(IncrementalEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("incremental", true));
|
||||
@ -132,14 +133,14 @@ class EndpointMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@Test
|
||||
void incrementalEndpointBuildEnableSpecificEndpoint() throws Exception {
|
||||
TestProject project = new TestProject(this.tempDir, SpecificEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
TestProject project = new TestProject(SpecificEndpoint.class);
|
||||
ConfigurationMetadata metadata = project.compile();
|
||||
assertThat(metadata).has(Metadata.withGroup("management.endpoint.specific").fromSource(SpecificEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("specific", true));
|
||||
assertThat(metadata).has(cacheTtl("specific"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
project.replaceText(SpecificEndpoint.class, "enableByDefault = true", "enableByDefault = false");
|
||||
metadata = project.incrementalBuild(SpecificEndpoint.class);
|
||||
metadata = project.compile();
|
||||
assertThat(metadata).has(Metadata.withGroup("management.endpoint.specific").fromSource(SpecificEndpoint.class));
|
||||
assertThat(metadata).has(enabledFlag("specific", false));
|
||||
assertThat(metadata).has(cacheTtl("specific"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -32,31 +32,30 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Metadata generation tests for incremental builds.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class IncrementalBuildMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@Test
|
||||
void incrementalBuild() throws Exception {
|
||||
TestProject project = new TestProject(this.tempDir, FooProperties.class, BarProperties.class);
|
||||
assertThat(project.getOutputFile(MetadataStore.METADATA_PATH).exists()).isFalse();
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
assertThat(project.getOutputFile(MetadataStore.METADATA_PATH).exists()).isTrue();
|
||||
TestProject project = new TestProject(FooProperties.class, BarProperties.class);
|
||||
ConfigurationMetadata metadata = project.compile();
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withProperty("foo.counter").fromSource(FooProperties.class).withDefaultValue(0));
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withProperty("bar.counter").fromSource(BarProperties.class).withDefaultValue(0));
|
||||
metadata = project.incrementalBuild(BarProperties.class);
|
||||
metadata = project.compile();
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withProperty("foo.counter").fromSource(FooProperties.class).withDefaultValue(0));
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withProperty("bar.counter").fromSource(BarProperties.class).withDefaultValue(0));
|
||||
project.addSourceCode(BarProperties.class, BarProperties.class.getResourceAsStream("BarProperties.snippet"));
|
||||
metadata = project.incrementalBuild(BarProperties.class);
|
||||
metadata = project.compile();
|
||||
assertThat(metadata).has(Metadata.withProperty("bar.extra"));
|
||||
assertThat(metadata).has(Metadata.withProperty("foo.counter").withDefaultValue(0));
|
||||
assertThat(metadata).has(Metadata.withProperty("bar.counter").withDefaultValue(0));
|
||||
project.revert(BarProperties.class);
|
||||
metadata = project.incrementalBuild(BarProperties.class);
|
||||
metadata = project.compile();
|
||||
assertThat(metadata).isNotEqualTo(Metadata.withProperty("bar.extra"));
|
||||
assertThat(metadata).has(Metadata.withProperty("foo.counter").withDefaultValue(0));
|
||||
assertThat(metadata).has(Metadata.withProperty("bar.counter").withDefaultValue(0));
|
||||
@ -64,20 +63,21 @@ class IncrementalBuildMetadataGenerationTests extends AbstractMetadataGeneration
|
||||
|
||||
@Test
|
||||
void incrementalBuildAnnotationRemoved() throws Exception {
|
||||
TestProject project = new TestProject(this.tempDir, FooProperties.class, BarProperties.class);
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
TestProject project = new TestProject(FooProperties.class, BarProperties.class);
|
||||
ConfigurationMetadata metadata = project.compile();
|
||||
assertThat(metadata).has(Metadata.withProperty("foo.counter").withDefaultValue(0));
|
||||
assertThat(metadata).has(Metadata.withProperty("bar.counter").withDefaultValue(0));
|
||||
project.replaceText(BarProperties.class, "@ConfigurationProperties", "//@ConfigurationProperties");
|
||||
metadata = project.incrementalBuild(BarProperties.class);
|
||||
project.replaceText(FooProperties.class, "@ConfigurationProperties", "//@ConfigurationProperties");
|
||||
metadata = project.compile();
|
||||
assertThat(metadata).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("gh-26271")
|
||||
void incrementalBuildTypeRenamed() throws Exception {
|
||||
TestProject project = new TestProject(this.tempDir, FooProperties.class, BarProperties.class);
|
||||
ConfigurationMetadata metadata = project.fullBuild();
|
||||
TestProject project = new TestProject(FooProperties.class, BarProperties.class);
|
||||
ConfigurationMetadata metadata = project.compile();
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withProperty("foo.counter").fromSource(FooProperties.class).withDefaultValue(0));
|
||||
assertThat(metadata)
|
||||
@ -85,7 +85,7 @@ class IncrementalBuildMetadataGenerationTests extends AbstractMetadataGeneration
|
||||
assertThat(metadata).doesNotHave(Metadata.withProperty("bar.counter").fromSource(RenamedBarProperties.class));
|
||||
project.delete(BarProperties.class);
|
||||
project.add(RenamedBarProperties.class);
|
||||
metadata = project.incrementalBuild(RenamedBarProperties.class);
|
||||
metadata = project.compile();
|
||||
assertThat(metadata)
|
||||
.has(Metadata.withProperty("foo.counter").fromSource(FooProperties.class).withDefaultValue(0));
|
||||
assertThat(metadata)
|
||||
@ -96,9 +96,9 @@ class IncrementalBuildMetadataGenerationTests extends AbstractMetadataGeneration
|
||||
|
||||
@Test
|
||||
void incrementalBuildDoesNotDeleteItems() throws Exception {
|
||||
TestProject project = new TestProject(this.tempDir, ClassWithNestedProperties.class, FooProperties.class);
|
||||
ConfigurationMetadata initialMetadata = project.fullBuild();
|
||||
ConfigurationMetadata updatedMetadata = project.incrementalBuild(FooProperties.class);
|
||||
TestProject project = new TestProject(ClassWithNestedProperties.class, FooProperties.class);
|
||||
ConfigurationMetadata initialMetadata = project.compile();
|
||||
ConfigurationMetadata updatedMetadata = project.compile();
|
||||
assertThat(initialMetadata.getItems()).isEqualTo(updatedMetadata.getItems());
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -37,15 +35,16 @@ import org.springframework.boot.configurationprocessor.metadata.TestJsonConverte
|
||||
import org.springframework.boot.configurationsample.simple.DeprecatedSingleProperty;
|
||||
import org.springframework.boot.configurationsample.simple.SimpleProperties;
|
||||
import org.springframework.boot.configurationsample.specific.SimpleConflictingProperties;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.core.test.tools.CompilationException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Metadata generation tests for merging additional metadata.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@ -53,8 +52,8 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
void mergingOfAdditionalProperty() throws Exception {
|
||||
ItemMetadata property = ItemMetadata.newProperty(null, "foo", "java.lang.String",
|
||||
AdditionalMetadata.class.getName(), null, null, null, null);
|
||||
writeAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
String additionalMetadata = buildAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("simple.comparator"));
|
||||
assertThat(metadata).has(Metadata.withProperty("foo", String.class).fromSource(AdditionalMetadata.class));
|
||||
}
|
||||
@ -63,8 +62,8 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
void mergingOfAdditionalPropertyMatchingGroup() throws Exception {
|
||||
ItemMetadata property = ItemMetadata.newProperty(null, "simple", "java.lang.String", null, null, null, null,
|
||||
null);
|
||||
writeAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
String additionalMetadata = buildAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withGroup("simple").fromSource(SimpleProperties.class));
|
||||
assertThat(metadata).has(Metadata.withProperty("simple", String.class));
|
||||
}
|
||||
@ -72,8 +71,8 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
@Test
|
||||
void mergeExistingPropertyDefaultValue() throws Exception {
|
||||
ItemMetadata property = ItemMetadata.newProperty("simple", "flag", null, null, null, null, true, null);
|
||||
writeAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
String additionalMetadata = buildAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("simple.flag", Boolean.class).fromSource(SimpleProperties.class)
|
||||
.withDescription("A simple flag.").withDeprecation(null, null).withDefaultValue(true));
|
||||
assertThat(metadata.getItems()).hasSize(4);
|
||||
@ -83,8 +82,9 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
void mergeExistingPropertyWithSeveralCandidates() throws Exception {
|
||||
ItemMetadata property = ItemMetadata.newProperty("simple", "flag", Boolean.class.getName(), null, null, null,
|
||||
true, null);
|
||||
writeAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class, SimpleConflictingProperties.class);
|
||||
String additionalMetadata = buildAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, SimpleProperties.class,
|
||||
SimpleConflictingProperties.class);
|
||||
assertThat(metadata.getItems()).hasSize(6);
|
||||
List<ItemMetadata> items = metadata.getItems().stream().filter((item) -> item.getName().equals("simple.flag"))
|
||||
.collect(Collectors.toList());
|
||||
@ -107,8 +107,8 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
void mergeExistingPropertyDescription() throws Exception {
|
||||
ItemMetadata property = ItemMetadata.newProperty("simple", "comparator", null, null, null, "A nice comparator.",
|
||||
null, null);
|
||||
writeAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
String additionalMetadata = buildAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("simple.comparator", "java.util.Comparator<?>")
|
||||
.fromSource(SimpleProperties.class).withDescription("A nice comparator."));
|
||||
assertThat(metadata.getItems()).hasSize(4);
|
||||
@ -118,8 +118,8 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
void mergeExistingPropertyDeprecation() throws Exception {
|
||||
ItemMetadata property = ItemMetadata.newProperty("simple", "comparator", null, null, null, null, null,
|
||||
new ItemDeprecation("Don't use this.", "simple.complex-comparator", "error"));
|
||||
writeAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
String additionalMetadata = buildAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, SimpleProperties.class);
|
||||
assertThat(metadata).has(
|
||||
Metadata.withProperty("simple.comparator", "java.util.Comparator<?>").fromSource(SimpleProperties.class)
|
||||
.withDeprecation("Don't use this.", "simple.complex-comparator", "error"));
|
||||
@ -130,8 +130,8 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
void mergeExistingPropertyDeprecationOverride() throws Exception {
|
||||
ItemMetadata property = ItemMetadata.newProperty("singledeprecated", "name", null, null, null, null, null,
|
||||
new ItemDeprecation("Don't use this.", "single.name"));
|
||||
writeAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(DeprecatedSingleProperty.class);
|
||||
String additionalMetadata = buildAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, DeprecatedSingleProperty.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("singledeprecated.name", String.class.getName())
|
||||
.fromSource(DeprecatedSingleProperty.class).withDeprecation("Don't use this.", "single.name"));
|
||||
assertThat(metadata.getItems()).hasSize(3);
|
||||
@ -141,8 +141,8 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
void mergeExistingPropertyDeprecationOverrideLevel() throws Exception {
|
||||
ItemMetadata property = ItemMetadata.newProperty("singledeprecated", "name", null, null, null, null, null,
|
||||
new ItemDeprecation(null, null, "error"));
|
||||
writeAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(DeprecatedSingleProperty.class);
|
||||
String additionalMetadata = buildAdditionalMetadata(property);
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, DeprecatedSingleProperty.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("singledeprecated.name", String.class.getName())
|
||||
.fromSource(DeprecatedSingleProperty.class)
|
||||
.withDeprecation("renamed", "singledeprecated.new-name", "error"));
|
||||
@ -151,17 +151,17 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@Test
|
||||
void mergeOfInvalidAdditionalMetadata() throws IOException {
|
||||
File additionalMetadataFile = createAdditionalMetadataFile();
|
||||
FileCopyUtils.copy("Hello World", new FileWriter(additionalMetadataFile));
|
||||
assertThatIllegalStateException().isThrownBy(() -> compile(SimpleProperties.class))
|
||||
.withMessage("Compilation failed");
|
||||
String metadata = "Hello World";
|
||||
assertThatExceptionOfType(CompilationException.class)
|
||||
.isThrownBy(() -> compile(metadata, SimpleProperties.class))
|
||||
.withMessageContaining("Invalid additional meta-data");
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergingOfSimpleHint() throws Exception {
|
||||
writeAdditionalHints(ItemHint.newHint("simple.the-name", new ItemHint.ValueHint("boot", "Bla bla"),
|
||||
new ItemHint.ValueHint("spring", null)));
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
String hints = buildAdditionalHints(ItemHint.newHint("simple.the-name",
|
||||
new ItemHint.ValueHint("boot", "Bla bla"), new ItemHint.ValueHint("spring", null)));
|
||||
ConfigurationMetadata metadata = compile(hints, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("simple.the-name", String.class)
|
||||
.fromSource(SimpleProperties.class).withDescription("The name of this simple properties.")
|
||||
.withDefaultValue("boot").withDeprecation(null, null));
|
||||
@ -171,8 +171,9 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@Test
|
||||
void mergingOfHintWithNonCanonicalName() throws Exception {
|
||||
writeAdditionalHints(ItemHint.newHint("simple.theName", new ItemHint.ValueHint("boot", "Bla bla")));
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
String hints = buildAdditionalHints(
|
||||
ItemHint.newHint("simple.theName", new ItemHint.ValueHint("boot", "Bla bla")));
|
||||
ConfigurationMetadata metadata = compile(hints, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("simple.the-name", String.class)
|
||||
.fromSource(SimpleProperties.class).withDescription("The name of this simple properties.")
|
||||
.withDefaultValue("boot").withDeprecation(null, null));
|
||||
@ -181,10 +182,10 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@Test
|
||||
void mergingOfHintWithProvider() throws Exception {
|
||||
writeAdditionalHints(new ItemHint("simple.theName", Collections.emptyList(),
|
||||
String hints = buildAdditionalHints(new ItemHint("simple.theName", Collections.emptyList(),
|
||||
Arrays.asList(new ItemHint.ValueProvider("first", Collections.singletonMap("target", "org.foo")),
|
||||
new ItemHint.ValueProvider("second", null))));
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
ConfigurationMetadata metadata = compile(hints, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("simple.the-name", String.class)
|
||||
.fromSource(SimpleProperties.class).withDescription("The name of this simple properties.")
|
||||
.withDefaultValue("boot").withDeprecation(null, null));
|
||||
@ -194,58 +195,48 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@Test
|
||||
void mergingOfAdditionalDeprecation() throws Exception {
|
||||
writePropertyDeprecation(ItemMetadata.newProperty("simple", "wrongName", "java.lang.String", null, null, null,
|
||||
null, new ItemDeprecation("Lame name.", "simple.the-name")));
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
String deprecations = buildPropertyDeprecations(ItemMetadata.newProperty("simple", "wrongName",
|
||||
"java.lang.String", null, null, null, null, new ItemDeprecation("Lame name.", "simple.the-name")));
|
||||
ConfigurationMetadata metadata = compile(deprecations, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("simple.wrong-name", String.class).withDeprecation("Lame name.",
|
||||
"simple.the-name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void mergingOfAdditionalMetadata() throws Exception {
|
||||
File metaInfDirectory = new File(getCompiler().getOutputLocation(), "META-INF");
|
||||
metaInfDirectory.mkdirs();
|
||||
File additionalMetadataFile = new File(metaInfDirectory, "additional-spring-configuration-metadata.json");
|
||||
additionalMetadataFile.createNewFile();
|
||||
JSONObject property = new JSONObject();
|
||||
property.put("name", "foo");
|
||||
property.put("type", "java.lang.String");
|
||||
property.put("sourceType", AdditionalMetadata.class.getName());
|
||||
JSONArray properties = new JSONArray();
|
||||
properties.put(property);
|
||||
JSONObject additionalMetadata = new JSONObject();
|
||||
additionalMetadata.put("properties", properties);
|
||||
FileWriter writer = new FileWriter(additionalMetadataFile);
|
||||
writer.append(additionalMetadata.toString(2));
|
||||
writer.flush();
|
||||
writer.close();
|
||||
ConfigurationMetadata metadata = compile(SimpleProperties.class);
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("properties", properties);
|
||||
String additionalMetadata = json.toString();
|
||||
ConfigurationMetadata metadata = compile(additionalMetadata, SimpleProperties.class);
|
||||
assertThat(metadata).has(Metadata.withProperty("simple.comparator"));
|
||||
assertThat(metadata).has(Metadata.withProperty("foo", String.class).fromSource(AdditionalMetadata.class));
|
||||
}
|
||||
|
||||
private void writeAdditionalMetadata(ItemMetadata... metadata) throws Exception {
|
||||
private String buildAdditionalMetadata(ItemMetadata... metadata) throws Exception {
|
||||
TestJsonConverter converter = new TestJsonConverter();
|
||||
File additionalMetadataFile = createAdditionalMetadataFile();
|
||||
JSONObject additionalMetadata = new JSONObject();
|
||||
JSONArray properties = new JSONArray();
|
||||
for (ItemMetadata itemMetadata : metadata) {
|
||||
properties.put(converter.toJsonObject(itemMetadata));
|
||||
}
|
||||
additionalMetadata.put("properties", properties);
|
||||
writeMetadata(additionalMetadataFile, additionalMetadata);
|
||||
return additionalMetadata.toString();
|
||||
}
|
||||
|
||||
private void writeAdditionalHints(ItemHint... hints) throws Exception {
|
||||
private String buildAdditionalHints(ItemHint... hints) throws Exception {
|
||||
TestJsonConverter converter = new TestJsonConverter();
|
||||
File additionalMetadataFile = createAdditionalMetadataFile();
|
||||
JSONObject additionalMetadata = new JSONObject();
|
||||
additionalMetadata.put("hints", converter.toJsonArray(Arrays.asList(hints)));
|
||||
writeMetadata(additionalMetadataFile, additionalMetadata);
|
||||
return additionalMetadata.toString();
|
||||
}
|
||||
|
||||
private void writePropertyDeprecation(ItemMetadata... items) throws Exception {
|
||||
File additionalMetadataFile = createAdditionalMetadataFile();
|
||||
private String buildPropertyDeprecations(ItemMetadata... items) throws Exception {
|
||||
JSONArray propertiesArray = new JSONArray();
|
||||
for (ItemMetadata item : items) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
@ -269,21 +260,7 @@ class MergeMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
}
|
||||
JSONObject additionalMetadata = new JSONObject();
|
||||
additionalMetadata.put("properties", propertiesArray);
|
||||
writeMetadata(additionalMetadataFile, additionalMetadata);
|
||||
}
|
||||
|
||||
private File createAdditionalMetadataFile() throws IOException {
|
||||
File metaInfDirectory = new File(getCompiler().getOutputLocation(), "META-INF");
|
||||
metaInfDirectory.mkdirs();
|
||||
File additionalMetadataFile = new File(metaInfDirectory, "additional-spring-configuration-metadata.json");
|
||||
additionalMetadataFile.createNewFile();
|
||||
return additionalMetadataFile;
|
||||
}
|
||||
|
||||
private void writeMetadata(File metadataFile, JSONObject metadata) throws Exception {
|
||||
try (FileWriter writer = new FileWriter(metadataFile)) {
|
||||
writer.append(metadata.toString(2));
|
||||
}
|
||||
return additionalMetadata.toString();
|
||||
}
|
||||
|
||||
static class AdditionalMetadata {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Metadata generation tests for types defined by {@code @Bean} methods.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class MethodBasedMetadataGenerationTests extends AbstractMetadataGenerationTests {
|
||||
|
||||
@ -65,7 +66,7 @@ class MethodBasedMetadataGenerationTests extends AbstractMetadataGenerationTests
|
||||
@Test
|
||||
void privateMethodConfig() {
|
||||
ConfigurationMetadata metadata = compile(PrivateMethodConfig.class);
|
||||
assertThat(metadata).doesNotHave(Metadata.withGroup("foo"));
|
||||
assertThat(metadata).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -16,12 +16,11 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
@ -29,7 +28,6 @@ import java.util.stream.Stream;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
|
||||
import org.springframework.boot.configurationprocessor.test.RoundEnvironmentTester;
|
||||
@ -49,7 +47,8 @@ import org.springframework.boot.configurationsample.simple.HierarchicalPropertie
|
||||
import org.springframework.boot.configurationsample.simple.HierarchicalPropertiesParent;
|
||||
import org.springframework.boot.configurationsample.simple.SimpleProperties;
|
||||
import org.springframework.boot.configurationsample.specific.TwoConstructorsExample;
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler;
|
||||
import org.springframework.core.test.tools.SourceFile;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -57,12 +56,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Tests for {@link PropertyDescriptorResolver}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class PropertyDescriptorResolverTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
void propertiesWithJavaBeanProperties() throws IOException {
|
||||
process(SimpleProperties.class,
|
||||
@ -181,7 +178,7 @@ class PropertyDescriptorResolverTests {
|
||||
}
|
||||
|
||||
private void process(Class<?> target, Collection<Class<?>> additionalClasses,
|
||||
BiConsumer<TypeElement, MetadataGenerationEnvironment> consumer) throws IOException {
|
||||
BiConsumer<TypeElement, MetadataGenerationEnvironment> consumer) {
|
||||
BiConsumer<RoundEnvironmentTester, MetadataGenerationEnvironment> internalConsumer = (roundEnv,
|
||||
metadataEnv) -> {
|
||||
TypeElement element = roundEnv.getRootElement(target);
|
||||
@ -189,11 +186,12 @@ class PropertyDescriptorResolverTests {
|
||||
};
|
||||
TestableAnnotationProcessor<MetadataGenerationEnvironment> processor = new TestableAnnotationProcessor<>(
|
||||
internalConsumer, new MetadataGenerationEnvironmentFactory());
|
||||
TestCompiler compiler = new TestCompiler(this.tempDir);
|
||||
ArrayList<Class<?>> allClasses = new ArrayList<>();
|
||||
allClasses.add(target);
|
||||
allClasses.addAll(additionalClasses);
|
||||
compiler.getTask(allClasses.toArray(new Class<?>[0])).call(processor);
|
||||
SourceFile targetSource = SourceFile.forTestClass(target);
|
||||
List<SourceFile> additionalSource = additionalClasses.stream().map(SourceFile::forTestClass).toList();
|
||||
TestCompiler compiler = TestCompiler.forSystem().withProcessors(processor).withSources(targetSource)
|
||||
.withSources(additionalSource);
|
||||
compiler.compile((compiled) -> {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
@ -26,23 +24,20 @@ import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.test.ItemMetadataAssert;
|
||||
import org.springframework.boot.configurationprocessor.test.RoundEnvironmentTester;
|
||||
import org.springframework.boot.configurationprocessor.test.TestableAnnotationProcessor;
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler;
|
||||
import org.springframework.core.test.tools.SourceFile;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
|
||||
/**
|
||||
* Base test infrastructure to test {@link PropertyDescriptor} implementations.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
public abstract class PropertyDescriptorTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
protected String createAccessorMethodName(String prefix, String name) {
|
||||
char[] chars = name.toCharArray();
|
||||
chars[0] = Character.toUpperCase(chars[0]);
|
||||
@ -66,12 +61,14 @@ public abstract class PropertyDescriptorTests {
|
||||
return new ItemMetadataAssert(property.resolveItemMetadata("test", metadataEnv));
|
||||
}
|
||||
|
||||
protected void process(Class<?> target, BiConsumer<RoundEnvironmentTester, MetadataGenerationEnvironment> consumer)
|
||||
throws IOException {
|
||||
protected void process(Class<?> target,
|
||||
BiConsumer<RoundEnvironmentTester, MetadataGenerationEnvironment> consumer) {
|
||||
TestableAnnotationProcessor<MetadataGenerationEnvironment> processor = new TestableAnnotationProcessor<>(
|
||||
consumer, new MetadataGenerationEnvironmentFactory());
|
||||
TestCompiler compiler = new TestCompiler(this.tempDir);
|
||||
compiler.getTask(target).call(processor);
|
||||
TestCompiler compiler = TestCompiler.forSystem().withProcessors(processor)
|
||||
.withSources(SourceFile.forTestClass(target));
|
||||
compiler.compile((compiled) -> {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,27 +16,22 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.test.CompiledMetadataReader;
|
||||
import org.springframework.boot.configurationprocessor.test.TestConfigurationMetadataAnnotationProcessor;
|
||||
import org.springframework.boot.configurationsample.ConfigurationProperties;
|
||||
import org.springframework.boot.configurationsample.NestedConfigurationProperty;
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler;
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler.TestCompilationTask;
|
||||
import org.springframework.core.test.tools.SourceFile;
|
||||
import org.springframework.core.test.tools.SourceFiles;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
|
||||
/**
|
||||
* A TestProject contains a copy of a subset of test sample code.
|
||||
@ -46,85 +41,26 @@ import org.springframework.util.FileSystemUtils;
|
||||
* original content itself.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
public class TestProject {
|
||||
|
||||
private static final Class<?>[] ALWAYS_INCLUDE = { ConfigurationProperties.class,
|
||||
NestedConfigurationProperty.class };
|
||||
|
||||
/**
|
||||
* Contains copies of the original source so we can modify it safely to test
|
||||
* incremental builds.
|
||||
*/
|
||||
private File sourceDirectory;
|
||||
private SourceFiles sources;
|
||||
|
||||
private TestCompiler compiler;
|
||||
|
||||
private Set<File> sourceFiles = new LinkedHashSet<>();
|
||||
|
||||
public TestProject(File tempDirectory, Class<?>... classes) throws IOException {
|
||||
this.sourceDirectory = new File(tempDirectory, "src");
|
||||
this.compiler = new TestCompiler(new File(tempDirectory, "build")) {
|
||||
|
||||
@Override
|
||||
protected File getSourceDirectory() {
|
||||
return TestProject.this.sourceDirectory;
|
||||
}
|
||||
|
||||
};
|
||||
Set<Class<?>> contents = new HashSet<>(Arrays.asList(classes));
|
||||
contents.addAll(Arrays.asList(ALWAYS_INCLUDE));
|
||||
copySources(contents);
|
||||
public TestProject(Class<?>... classes) {
|
||||
this.sources = SourceFiles.none().and(sourceFilesOf(ALWAYS_INCLUDE)).and(sourceFilesOf(classes));
|
||||
}
|
||||
|
||||
private void copySources(Set<Class<?>> contents) throws IOException {
|
||||
for (Class<?> type : contents) {
|
||||
copySources(type);
|
||||
}
|
||||
}
|
||||
|
||||
private void copySources(Class<?> type) throws IOException {
|
||||
File original = getOriginalSourceFile(type);
|
||||
File target = getSourceFile(type);
|
||||
target.getParentFile().mkdirs();
|
||||
FileCopyUtils.copy(original, target);
|
||||
this.sourceFiles.add(target);
|
||||
}
|
||||
|
||||
public File getSourceFile(Class<?> type) {
|
||||
return new File(this.sourceDirectory, TestCompiler.sourcePathFor(type));
|
||||
}
|
||||
|
||||
public ConfigurationMetadata fullBuild() {
|
||||
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(
|
||||
this.compiler.getOutputLocation());
|
||||
TestCompilationTask task = this.compiler.getTask(this.sourceFiles);
|
||||
deleteDirectoryContents(this.compiler.getOutputLocation());
|
||||
task.call(processor);
|
||||
return processor.getMetadata();
|
||||
}
|
||||
|
||||
public ConfigurationMetadata incrementalBuild(Class<?>... toRecompile) {
|
||||
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(
|
||||
this.compiler.getOutputLocation());
|
||||
TestCompilationTask task = this.compiler.getTask(toRecompile);
|
||||
task.call(processor);
|
||||
return processor.getMetadata();
|
||||
}
|
||||
|
||||
private void deleteDirectoryContents(File outputDirectory) {
|
||||
FileSystemUtils.deleteRecursively(outputDirectory);
|
||||
outputDirectory.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve File relative to project's output directory.
|
||||
* @param relativePath the relative path
|
||||
* @return the output file
|
||||
*/
|
||||
public File getOutputFile(String relativePath) {
|
||||
Assert.isTrue(!new File(relativePath).isAbsolute(), "'" + relativePath + "' was absolute");
|
||||
return new File(this.compiler.getOutputLocation(), relativePath);
|
||||
public ConfigurationMetadata compile() {
|
||||
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor();
|
||||
TestCompiler compiler = TestCompiler.forSystem().withProcessors(processor);
|
||||
AtomicReference<ConfigurationMetadata> configurationMetadata = new AtomicReference<>();
|
||||
compiler.compile(this.sources,
|
||||
(compiled) -> configurationMetadata.set(CompiledMetadataReader.getMetadata(compiled)));
|
||||
return configurationMetadata.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,12 +70,12 @@ public class TestProject {
|
||||
* @throws Exception if the source cannot be added
|
||||
*/
|
||||
public void addSourceCode(Class<?> target, InputStream snippetStream) throws Exception {
|
||||
File targetFile = getSourceFile(target);
|
||||
String contents = getContents(targetFile);
|
||||
SourceFile sourceFile = SourceFile.forTestClass(target);
|
||||
String contents = sourceFile.getContent();
|
||||
int insertAt = contents.lastIndexOf('}');
|
||||
String additionalSource = FileCopyUtils.copyToString(new InputStreamReader(snippetStream));
|
||||
contents = contents.substring(0, insertAt) + additionalSource + contents.substring(insertAt);
|
||||
putContents(targetFile, contents);
|
||||
this.sources = this.sources.and(SourceFile.of(contents));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,53 +83,40 @@ public class TestProject {
|
||||
* @param type the class to delete
|
||||
*/
|
||||
public void delete(Class<?> type) {
|
||||
File target = getSourceFile(type);
|
||||
target.delete();
|
||||
this.sourceFiles.remove(target);
|
||||
SourceFile[] newSources = this.sources.stream()
|
||||
.filter((sourceFile) -> !sourceFile.getPath().equals(SourceFile.forTestClass(type).getPath()))
|
||||
.toArray(SourceFile[]::new);
|
||||
this.sources = SourceFiles.of(newSources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore source code of given class to its original contents.
|
||||
* @param type the class to revert
|
||||
* @throws IOException on IO error
|
||||
*/
|
||||
public void revert(Class<?> type) throws IOException {
|
||||
Assert.isTrue(getSourceFile(type).exists(), "Source file for type '" + type + "' does not exist");
|
||||
copySources(type);
|
||||
public void revert(Class<?> type) {
|
||||
Assert.isTrue(this.sources.stream().anyMatch((sourceFile) -> sourceFile.getClassName().equals(type.getName())),
|
||||
"Source file for type '" + type + "' does not exist");
|
||||
this.sources = this.sources.and(SourceFile.forTestClass(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add source code of given class to this project.
|
||||
* @param type the class to add
|
||||
* @throws IOException on IO error
|
||||
*/
|
||||
public void add(Class<?> type) throws IOException {
|
||||
Assert.isTrue(!getSourceFile(type).exists(), "Source file for type '" + type + "' already exists");
|
||||
copySources(type);
|
||||
public void add(Class<?> type) {
|
||||
Assert.isTrue(this.sources.stream().noneMatch((sourceFile) -> sourceFile.getClassName().equals(type.getName())),
|
||||
"Source file for type '" + type + "' already exists");
|
||||
this.sources = this.sources.and(SourceFile.forTestClass(type));
|
||||
}
|
||||
|
||||
public void replaceText(Class<?> type, String find, String replace) throws Exception {
|
||||
File target = getSourceFile(type);
|
||||
String contents = getContents(target);
|
||||
contents = contents.replace(find, replace);
|
||||
putContents(target, contents);
|
||||
public void replaceText(Class<?> type, String find, String replace) {
|
||||
SourceFile sourceFile = SourceFile.forTestClass(type);
|
||||
String contents = sourceFile.getContent().replace(find, replace);
|
||||
this.sources = this.sources.and(SourceFile.of(contents));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the 'original' source code for given test class. Clients or subclasses should
|
||||
* have no need to know about these. They should work only with the copied source
|
||||
* code.
|
||||
*/
|
||||
private File getOriginalSourceFile(Class<?> type) {
|
||||
return new File(TestCompiler.SOURCE_DIRECTORY, TestCompiler.sourcePathFor(type));
|
||||
}
|
||||
|
||||
private static void putContents(File targetFile, String contents) throws IOException {
|
||||
FileCopyUtils.copy(new StringReader(contents), new FileWriter(targetFile));
|
||||
}
|
||||
|
||||
private static String getContents(File file) throws Exception {
|
||||
return FileCopyUtils.copyToString(new FileReader(file));
|
||||
private List<SourceFile> sourceFilesOf(Class<?>... types) {
|
||||
return Arrays.stream(types).map(SourceFile::forTestClass).toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,13 +16,11 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.TypeUtils.TypeDescriptor;
|
||||
import org.springframework.boot.configurationprocessor.test.RoundEnvironmentTester;
|
||||
@ -30,7 +28,8 @@ import org.springframework.boot.configurationprocessor.test.TestableAnnotationPr
|
||||
import org.springframework.boot.configurationsample.generic.AbstractGenericProperties;
|
||||
import org.springframework.boot.configurationsample.generic.AbstractIntermediateGenericProperties;
|
||||
import org.springframework.boot.configurationsample.generic.SimpleGenericProperties;
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler;
|
||||
import org.springframework.core.test.tools.SourceFile;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -38,12 +37,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Tests for {@link TypeUtils}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class TypeUtilsTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
void resolveTypeDescriptorOnConcreteClass() throws IOException {
|
||||
process(SimpleGenericProperties.class, (roundEnv, typeUtils) -> {
|
||||
@ -82,10 +79,12 @@ class TypeUtilsTests {
|
||||
});
|
||||
}
|
||||
|
||||
private void process(Class<?> target, BiConsumer<RoundEnvironmentTester, TypeUtils> consumer) throws IOException {
|
||||
private void process(Class<?> target, BiConsumer<RoundEnvironmentTester, TypeUtils> consumer) {
|
||||
TestableAnnotationProcessor<TypeUtils> processor = new TestableAnnotationProcessor<>(consumer, TypeUtils::new);
|
||||
TestCompiler compiler = new TestCompiler(this.tempDir);
|
||||
compiler.getTask(target).call(processor);
|
||||
TestCompiler compiler = TestCompiler.forSystem().withProcessors(processor)
|
||||
.withSources(SourceFile.forTestClass(target));
|
||||
compiler.compile((compiled) -> {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor.fieldvalues;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -31,10 +30,10 @@ import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.configurationsample.fieldvalues.FieldValues;
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler;
|
||||
import org.springframework.core.test.tools.SourceFile;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -46,16 +45,15 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
public abstract class AbstractFieldValuesProcessorTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
protected abstract FieldValuesParser createProcessor(ProcessingEnvironment env);
|
||||
|
||||
@Test
|
||||
void getFieldValues() throws Exception {
|
||||
TestProcessor processor = new TestProcessor();
|
||||
TestCompiler compiler = new TestCompiler(this.tempDir);
|
||||
compiler.getTask(FieldValues.class).call(processor);
|
||||
TestCompiler compiler = TestCompiler.forSystem().withProcessors(processor)
|
||||
.withSources(SourceFile.forTestClass(FieldValues.class));
|
||||
compiler.compile((compiled) -> {
|
||||
});
|
||||
Map<String, Object> values = processor.getValues();
|
||||
assertThat(values.get("string")).isEqualTo("1");
|
||||
assertThat(values.get("stringNone")).isNull();
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.configurationprocessor.test;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller;
|
||||
import org.springframework.core.test.tools.Compiled;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
|
||||
/**
|
||||
* Read the contents of metadata generated from the {@link TestCompiler}.
|
||||
*
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
public final class CompiledMetadataReader {
|
||||
|
||||
private static final String METADATA_FILE = "META-INF/spring-configuration-metadata.json";
|
||||
|
||||
private CompiledMetadataReader() {
|
||||
}
|
||||
|
||||
public static ConfigurationMetadata getMetadata(Compiled compiled) {
|
||||
InputStream inputStream = compiled.getClassLoader().getResourceAsStream(METADATA_FILE);
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
return new JsonMarshaller().read(inputStream);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException("Failed to read metadata", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,10 +16,6 @@
|
||||
|
||||
package org.springframework.boot.configurationprocessor.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@ -29,8 +25,6 @@ import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.ConfigurationMetadataAnnotationProcessor;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller;
|
||||
|
||||
/**
|
||||
* Test {@link ConfigurationMetadataAnnotationProcessor}.
|
||||
@ -39,6 +33,7 @@ import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller;
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Kris De Volder
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@SupportedAnnotationTypes({ TestConfigurationMetadataAnnotationProcessor.CONFIGURATION_PROPERTIES_ANNOTATION,
|
||||
TestConfigurationMetadataAnnotationProcessor.CONTROLLER_ENDPOINT_ANNOTATION,
|
||||
@ -79,12 +74,7 @@ public class TestConfigurationMetadataAnnotationProcessor extends ConfigurationM
|
||||
|
||||
public static final String NAME_ANNOTATION = "org.springframework.boot.configurationsample.Name";
|
||||
|
||||
private ConfigurationMetadata metadata;
|
||||
|
||||
private final File outputLocation;
|
||||
|
||||
public TestConfigurationMetadataAnnotationProcessor(File outputLocation) {
|
||||
this.outputLocation = outputLocation;
|
||||
public TestConfigurationMetadataAnnotationProcessor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -133,28 +123,4 @@ public class TestConfigurationMetadataAnnotationProcessor extends ConfigurationM
|
||||
return NAME_ANNOTATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigurationMetadata writeMetadata() throws Exception {
|
||||
super.writeMetadata();
|
||||
try {
|
||||
File metadataFile = new File(this.outputLocation, "META-INF/spring-configuration-metadata.json");
|
||||
if (metadataFile.isFile()) {
|
||||
try (InputStream input = new FileInputStream(metadataFile)) {
|
||||
this.metadata = new JsonMarshaller().read(input);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.metadata = new ConfigurationMetadata();
|
||||
}
|
||||
return this.metadata;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new RuntimeException("Failed to read metadata from disk", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigurationMetadata getMetadata() {
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ dependencies {
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
testImplementation("org.mockito:mockito-core")
|
||||
testImplementation("org.springframework:spring-test")
|
||||
testImplementation("org.springframework:spring-core-test")
|
||||
|
||||
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||
testRuntimeOnly("org.bouncycastle:bcprov-jdk18on:1.71")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -101,6 +101,7 @@ class JarLauncherTests extends AbstractExecutableArchiveLauncherTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("removal")
|
||||
void explodedJarDefinedPackagesIncludeManifestAttributes() throws Exception {
|
||||
Manifest manifest = new Manifest();
|
||||
Attributes attributes = manifest.getMainAttributes();
|
||||
|
@ -36,6 +36,7 @@ dependencies {
|
||||
implementation("org.hamcrest:hamcrest-library")
|
||||
implementation("org.springframework:spring-core")
|
||||
implementation("org.springframework:spring-test")
|
||||
implementation("org.springframework:spring-core-test")
|
||||
|
||||
testImplementation("jakarta.servlet:jakarta.servlet-api")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -37,7 +37,10 @@ import javax.tools.ToolProvider;
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.5.0
|
||||
* @deprecated since 3.0.0 in favor of
|
||||
* {@link org.springframework.core.test.tools.TestCompiler}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public class TestCompiler {
|
||||
|
||||
/**
|
||||
|
@ -102,6 +102,7 @@ dependencies {
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib")
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
testImplementation("org.springframework:spring-core-test")
|
||||
testImplementation("com.ibm.db2:jcc")
|
||||
testImplementation("com.jayway.jsonpath:json-path")
|
||||
testImplementation("com.microsoft.sqlserver:mssql-jdbc")
|
||||
|
@ -16,36 +16,31 @@
|
||||
|
||||
package org.springframework.boot.context.properties.bind;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
||||
import org.springframework.boot.context.properties.source.MockConfigurationPropertySource;
|
||||
import org.springframework.boot.testsupport.compiler.TestCompiler;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.test.tools.SourceFile;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for {@link ValueObjectBinder}.
|
||||
@ -368,26 +363,27 @@ class ValueObjectBinderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindToRecordWithDefaultValue(@TempDir File tempDir) throws IOException, ClassNotFoundException {
|
||||
void bindToRecordWithDefaultValue() throws IOException {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
source.put("test.record.property1", "value-from-config-1");
|
||||
this.sources.add(source);
|
||||
File recordProperties = new File(tempDir, "RecordProperties.java");
|
||||
try (PrintWriter writer = new PrintWriter(new FileWriter(recordProperties))) {
|
||||
writer.println("public record RecordProperties(");
|
||||
writer.println(
|
||||
"@org.springframework.boot.context.properties.bind.DefaultValue(\"default-value-1\") String property1,");
|
||||
writer.println(
|
||||
"@org.springframework.boot.context.properties.bind.DefaultValue(\"default-value-2\") String property2");
|
||||
writer.println(") {");
|
||||
writer.println("}");
|
||||
}
|
||||
TestCompiler compiler = new TestCompiler(tempDir);
|
||||
compiler.getTask(Arrays.asList(recordProperties)).call();
|
||||
ClassLoader ucl = new URLClassLoader(new URL[] { tempDir.toURI().toURL() });
|
||||
Object bean = this.binder.bind("test.record", Class.forName("RecordProperties", true, ucl)).get();
|
||||
assertThat(bean).hasFieldOrPropertyWithValue("property1", "value-from-config-1")
|
||||
.hasFieldOrPropertyWithValue("property2", "default-value-2");
|
||||
String recordProperties = """
|
||||
public record RecordProperties(
|
||||
@org.springframework.boot.context.properties.bind.DefaultValue("default-value-1") String property1,
|
||||
@org.springframework.boot.context.properties.bind.DefaultValue("default-value-2") String property2) {
|
||||
}
|
||||
""";
|
||||
TestCompiler.forSystem().withSources(SourceFile.of(recordProperties)).compile((compiled) -> {
|
||||
try {
|
||||
ClassLoader cl = compiled.getClassLoader();
|
||||
Object bean = this.binder.bind("test.record", Class.forName("RecordProperties", true, cl)).get();
|
||||
assertThat(bean).hasFieldOrPropertyWithValue("property1", "value-from-config-1")
|
||||
.hasFieldOrPropertyWithValue("property2", "default-value-2");
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
fail("Expected generated class 'RecordProperties' not found", ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void noConfigurationProperty(BindException ex) {
|
||||
|
Loading…
Reference in New Issue
Block a user