mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-10-10 11:29:20 +00:00
Add nullability annotations to tests in core/spring-boot
See gh-47263
This commit is contained in:
@@ -50,6 +50,8 @@ dependencies {
|
||||
optional("org.yaml:snakeyaml")
|
||||
optional("tools.jackson.core:jackson-databind")
|
||||
|
||||
testCompileOnly("com.google.code.findbugs:jsr305")
|
||||
|
||||
testFixturesCompileOnly(project(":test-support:spring-boot-test-support"))
|
||||
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
@@ -106,3 +108,7 @@ sourceSets {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("compileTestJava") {
|
||||
options.nullability.checking = "tests"
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.boot;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -49,7 +50,7 @@ import static org.mockito.Mockito.reset;
|
||||
@ExtendWith({ MockitoExtension.class, OutputCaptureExtension.class })
|
||||
class BannerTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
private @Nullable ConfigurableApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
@@ -59,6 +60,7 @@ class BannerTests {
|
||||
}
|
||||
|
||||
@Captor
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ArgumentCaptor<Class<?>> sourceClassCaptor;
|
||||
|
||||
@Test
|
||||
@@ -123,7 +125,7 @@ class BannerTests {
|
||||
static class DummyBanner implements Banner {
|
||||
|
||||
@Override
|
||||
public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
|
||||
public void printBanner(Environment environment, @Nullable Class<?> sourceClass, PrintStream out) {
|
||||
out.println("My Banner");
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ class DefaultApplicationArgumentsTests {
|
||||
private static final String[] ARGS = new String[] { "--foo=bar", "--foo=baz", "--debug", "spring", "boot" };
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void argumentsMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DefaultApplicationArguments((String[]) null))
|
||||
.withMessageContaining("'args' must not be null");
|
||||
|
||||
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.withSettings;
|
||||
class ExitCodeGeneratorsTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void addAllWhenGeneratorsIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> {
|
||||
List<ExitCodeGenerator> generators = null;
|
||||
@@ -45,6 +46,7 @@ class ExitCodeGeneratorsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void addWhenGeneratorIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ExitCodeGenerators().add(null))
|
||||
.withMessageContaining("'generator' must not be null");
|
||||
|
||||
+4
-2
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
/**
|
||||
@@ -27,12 +29,12 @@ import org.springframework.mock.env.MockEnvironment;
|
||||
public class MockApplicationEnvironment extends MockEnvironment {
|
||||
|
||||
@Override
|
||||
protected String doGetActiveProfilesProperty() {
|
||||
protected @Nullable String doGetActiveProfilesProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doGetDefaultProfilesProperty() {
|
||||
protected @Nullable String doGetDefaultProfilesProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -35,7 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class OverrideSourcesTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
private @Nullable ConfigurableApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -170,12 +171,12 @@ class ResourceBannerTests {
|
||||
assertThat(banner).startsWith("banner bar");
|
||||
}
|
||||
|
||||
private String printBanner(Resource resource, String bootVersion, String applicationVersion,
|
||||
String applicationTitle) {
|
||||
private String printBanner(Resource resource, @Nullable String bootVersion, @Nullable String applicationVersion,
|
||||
@Nullable String applicationTitle) {
|
||||
return printBanner(new MockResourceBanner(resource, bootVersion, applicationTitle), applicationVersion);
|
||||
}
|
||||
|
||||
private String printBanner(ResourceBanner banner, String applicationVersion) {
|
||||
private String printBanner(ResourceBanner banner, @Nullable String applicationVersion) {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
if (applicationVersion != null) {
|
||||
environment.setProperty("spring.application.version", applicationVersion);
|
||||
@@ -189,23 +190,23 @@ class ResourceBannerTests {
|
||||
|
||||
static class MockResourceBanner extends ResourceBanner {
|
||||
|
||||
private final String bootVersion;
|
||||
private final @Nullable String bootVersion;
|
||||
|
||||
private final String applicationTitle;
|
||||
private final @Nullable String applicationTitle;
|
||||
|
||||
MockResourceBanner(Resource resource, String bootVersion, String applicationTitle) {
|
||||
MockResourceBanner(Resource resource, @Nullable String bootVersion, @Nullable String applicationTitle) {
|
||||
super(resource);
|
||||
this.bootVersion = bootVersion;
|
||||
this.applicationTitle = applicationTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBootVersion() {
|
||||
protected @Nullable String getBootVersion() {
|
||||
return this.bootVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApplicationTitle(Class<?> sourceClass) {
|
||||
protected @Nullable String getApplicationTitle(@Nullable Class<?> sourceClass) {
|
||||
return this.applicationTitle;
|
||||
}
|
||||
|
||||
@@ -213,23 +214,23 @@ class ResourceBannerTests {
|
||||
|
||||
static class MutatingResourceBanner extends MockResourceBanner {
|
||||
|
||||
MutatingResourceBanner(Resource resource, String bootVersion, String applicationTitle) {
|
||||
MutatingResourceBanner(Resource resource, String bootVersion, @Nullable String applicationTitle) {
|
||||
super(resource, bootVersion, applicationTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PropertyResolver> getPropertyResolvers(Environment environment, Class<?> sourceClass) {
|
||||
protected List<PropertyResolver> getPropertyResolvers(Environment environment, @Nullable Class<?> sourceClass) {
|
||||
List<PropertyResolver> resolvers = super.getPropertyResolvers(environment, sourceClass);
|
||||
PropertyResolver resolver = new AbstractPropertyResolver() {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getProperty(String key, Class<T> targetType) {
|
||||
public <T> @Nullable T getProperty(String key, Class<T> targetType) {
|
||||
return String.class.equals(targetType) ? (T) getPropertyAsRawString(key) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPropertyAsRawString(String key) {
|
||||
protected @Nullable String getPropertyAsRawString(String key) {
|
||||
return ("foo".equals(key)) ? "bar" : null;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package org.springframework.boot;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -101,7 +102,7 @@ class SpringApplicationAotProcessorTests {
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public static class SampleApplication {
|
||||
|
||||
public static String[] argsHolder;
|
||||
public static String @Nullable [] argsHolder;
|
||||
|
||||
public static boolean postRunInvoked;
|
||||
|
||||
|
||||
+7
-3
@@ -25,6 +25,7 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@@ -152,6 +153,7 @@ class SpringApplicationShutdownHookTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void addHandlerActionWhenNullThrowsException() {
|
||||
TestSpringApplicationShutdownHook shutdownHook = new TestSpringApplicationShutdownHook();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> shutdownHook.getHandlers().add(null))
|
||||
@@ -168,6 +170,7 @@ class SpringApplicationShutdownHookTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void removeHandlerActionWhenNullThrowsException() {
|
||||
TestSpringApplicationShutdownHook shutdownHook = new TestSpringApplicationShutdownHook();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> shutdownHook.getHandlers().remove(null))
|
||||
@@ -244,15 +247,16 @@ class SpringApplicationShutdownHookTests {
|
||||
|
||||
private final List<Object> finished;
|
||||
|
||||
private final CountDownLatch closing;
|
||||
private final @Nullable CountDownLatch closing;
|
||||
|
||||
private final CountDownLatch proceedWithClose;
|
||||
private final @Nullable CountDownLatch proceedWithClose;
|
||||
|
||||
TestApplicationContext(List<Object> finished) {
|
||||
this(finished, null, null);
|
||||
}
|
||||
|
||||
TestApplicationContext(List<Object> finished, CountDownLatch closing, CountDownLatch proceedWithClose) {
|
||||
TestApplicationContext(List<Object> finished, @Nullable CountDownLatch closing,
|
||||
@Nullable CountDownLatch proceedWithClose) {
|
||||
this.finished = finished;
|
||||
this.closing = closing;
|
||||
this.proceedWithClose = proceedWithClose;
|
||||
|
||||
+45
-21
@@ -23,6 +23,7 @@ import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -32,6 +33,7 @@ import java.util.function.Supplier;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -167,7 +169,7 @@ class SpringApplicationTests {
|
||||
|
||||
private String headlessProperty;
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
private @Nullable ConfigurableApplicationContext context;
|
||||
|
||||
private Environment getEnvironment() {
|
||||
if (this.context != null) {
|
||||
@@ -202,6 +204,8 @@ class SpringApplicationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway")
|
||||
// Test null check
|
||||
void sourcesMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new SpringApplication((Class<?>[]) null).run())
|
||||
.withMessageContaining("'primarySources' must not be null");
|
||||
@@ -360,7 +364,9 @@ class SpringApplicationTests {
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
AtomicReference<ApplicationReadyEvent> reference = addListener(application, ApplicationReadyEvent.class);
|
||||
this.context = application.run("--foo=bar");
|
||||
assertThat(application).isSameAs(reference.get().getSpringApplication());
|
||||
ApplicationReadyEvent event = reference.get();
|
||||
assertThat(event).isNotNull();
|
||||
assertThat(application).isSameAs(event.getSpringApplication());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -369,7 +375,9 @@ class SpringApplicationTests {
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
AtomicReference<ContextRefreshedEvent> reference = addListener(application, ContextRefreshedEvent.class);
|
||||
this.context = application.run("--foo=bar");
|
||||
assertThat(this.context).isSameAs(reference.get().getApplicationContext());
|
||||
ContextRefreshedEvent event = reference.get();
|
||||
assertThat(event).isNotNull();
|
||||
assertThat(this.context).isSameAs(event.getApplicationContext());
|
||||
// Custom initializers do not switch off the defaults
|
||||
assertThat(getEnvironment().getProperty("foo")).isEqualTo("bar");
|
||||
}
|
||||
@@ -487,6 +495,7 @@ class SpringApplicationTests {
|
||||
assertThat(environment.getProperty("foo")).isEqualTo("bar");
|
||||
CompositePropertySource composite = (CompositePropertySource) environment.getPropertySources()
|
||||
.get("commandLineArgs");
|
||||
assertThat(composite).isNotNull();
|
||||
assertThat(composite.getPropertySources()).hasSize(2);
|
||||
assertThat(composite.getPropertySources()).first()
|
||||
.matches((source) -> source.getName().equals("springApplicationCommandLineArgs"),
|
||||
@@ -878,8 +887,9 @@ class SpringApplicationTests {
|
||||
@Test
|
||||
void defaultCommandLineArgs() {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
application.setDefaultProperties(
|
||||
StringUtils.splitArrayElementsIntoProperties(new String[] { "baz=", "bar=spam" }, "="));
|
||||
Properties properties = StringUtils.splitArrayElementsIntoProperties(new String[] { "baz=", "bar=spam" }, "=");
|
||||
assertThat(properties).isNotNull();
|
||||
application.setDefaultProperties(properties);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
this.context = application.run("--bar=foo", "bucket", "crap");
|
||||
assertThat(this.context).isInstanceOf(AnnotationConfigApplicationContext.class);
|
||||
@@ -936,7 +946,7 @@ class SpringApplicationTests {
|
||||
this.context = application.run();
|
||||
assertThat(events).hasAtLeastOneElementOfType(ApplicationPreparedEvent.class);
|
||||
assertThat(events).hasAtLeastOneElementOfType(ContextRefreshedEvent.class);
|
||||
verifyRegisteredListenerSuccessEvents();
|
||||
verifyRegisteredListenerSuccessEvents(this.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -949,12 +959,12 @@ class SpringApplicationTests {
|
||||
this.context = application.run();
|
||||
assertThat(events).hasAtLeastOneElementOfType(ApplicationPreparedEvent.class);
|
||||
assertThat(events).hasAtLeastOneElementOfType(ContextRefreshedEvent.class);
|
||||
verifyRegisteredListenerSuccessEvents();
|
||||
verifyRegisteredListenerSuccessEvents(this.context);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void verifyRegisteredListenerSuccessEvents() {
|
||||
ApplicationListener<ApplicationEvent> listener = this.context.getBean("testApplicationListener",
|
||||
private void verifyRegisteredListenerSuccessEvents(ConfigurableApplicationContext context) {
|
||||
ApplicationListener<ApplicationEvent> listener = context.getBean("testApplicationListener",
|
||||
ApplicationListener.class);
|
||||
InOrder inOrder = Mockito.inOrder(listener);
|
||||
then(listener).should(inOrder).onApplicationEvent(isA(ContextRefreshedEvent.class));
|
||||
@@ -1224,9 +1234,11 @@ class SpringApplicationTests {
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
application.addBootstrapRegistryInitializer((bootstrapContext) -> {
|
||||
bootstrapContext.register(String.class, InstanceSupplier.of("boot"));
|
||||
bootstrapContext.addCloseListener((event) -> event.getApplicationContext()
|
||||
.getBeanFactory()
|
||||
.registerSingleton("test", event.getBootstrapContext().get(String.class)));
|
||||
bootstrapContext.addCloseListener((event) -> {
|
||||
String string = event.getBootstrapContext().get(String.class);
|
||||
assertThat(string).isNotNull();
|
||||
event.getApplicationContext().getBeanFactory().registerSingleton("test", string);
|
||||
});
|
||||
});
|
||||
ConfigurableApplicationContext applicationContext = application.run();
|
||||
assertThat(applicationContext.getBean("test")).isEqualTo("boot");
|
||||
@@ -1272,8 +1284,9 @@ class SpringApplicationTests {
|
||||
.map(ApplicationFailedEvent.class::cast)
|
||||
.findFirst()
|
||||
.get();
|
||||
assertThat(SpringApplicationShutdownHookInstance.get())
|
||||
.didNotRegisterApplicationContext(failure.getApplicationContext());
|
||||
ConfigurableApplicationContext context = failure.getApplicationContext();
|
||||
assertThat(context).isNotNull();
|
||||
assertThat(SpringApplicationShutdownHookInstance.get()).didNotRegisterApplicationContext(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1283,6 +1296,7 @@ class SpringApplicationTests {
|
||||
SpringApplicationRunListener runListener = mock(SpringApplicationRunListener.class);
|
||||
SpringApplicationHook hook = (springApplication) -> runListener;
|
||||
SpringApplication.withHook(hook, () -> this.context = application.run());
|
||||
assertThat(this.context).isNotNull();
|
||||
then(runListener).should().starting(any());
|
||||
then(runListener).should().contextPrepared(this.context);
|
||||
then(runListener).should().ready(eq(this.context), any());
|
||||
@@ -1320,7 +1334,11 @@ class SpringApplicationTests {
|
||||
SpringApplicationHook hook = (springApplication) -> runListener;
|
||||
assertThatExceptionOfType(SpringApplication.AbandonedRunException.class)
|
||||
.isThrownBy(() -> SpringApplication.withHook(hook, () -> application.run()))
|
||||
.satisfies((ex) -> assertThat(ex.getApplicationContext().isRunning()).isFalse());
|
||||
.satisfies((ex) -> {
|
||||
ConfigurableApplicationContext context = ex.getApplicationContext();
|
||||
assertThat(context).isNotNull();
|
||||
assertThat(context.isRunning()).isFalse();
|
||||
});
|
||||
then(runListener).should().starting(any());
|
||||
then(runListener).should().contextPrepared(any());
|
||||
then(runListener).should(never()).ready(any(), any());
|
||||
@@ -1389,7 +1407,10 @@ class SpringApplicationTests {
|
||||
.with(SingleUseAdditionalConfig.class)
|
||||
.run()
|
||||
.getApplicationContext();
|
||||
assertThatNoException().isThrownBy(() -> this.context.getBean(SingleUseAdditionalConfig.class));
|
||||
assertThatNoException().isThrownBy(() -> {
|
||||
assertThat(this.context).isNotNull();
|
||||
this.context.getBean(SingleUseAdditionalConfig.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1540,7 +1561,7 @@ class SpringApplicationTests {
|
||||
|
||||
static class TestSpringApplication extends SpringApplication {
|
||||
|
||||
private BeanDefinitionLoader loader;
|
||||
private @Nullable BeanDefinitionLoader loader;
|
||||
|
||||
private boolean useMockLoader;
|
||||
|
||||
@@ -1567,7 +1588,7 @@ class SpringApplicationTests {
|
||||
return this.loader;
|
||||
}
|
||||
|
||||
BeanDefinitionLoader getLoader() {
|
||||
@Nullable BeanDefinitionLoader getLoader() {
|
||||
return this.loader;
|
||||
}
|
||||
|
||||
@@ -1855,6 +1876,7 @@ class SpringApplicationTests {
|
||||
|
||||
private final String[] expectedBefore;
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private final int order;
|
||||
@@ -1926,14 +1948,14 @@ class SpringApplicationTests {
|
||||
|
||||
static class ExitCodeListener implements ApplicationListener<ExitCodeEvent> {
|
||||
|
||||
private Integer exitCode;
|
||||
private @Nullable Integer exitCode;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ExitCodeEvent event) {
|
||||
this.exitCode = event.getExitCode();
|
||||
}
|
||||
|
||||
Integer getExitCode() {
|
||||
@Nullable Integer getExitCode() {
|
||||
return this.exitCode;
|
||||
}
|
||||
|
||||
@@ -1971,7 +1993,9 @@ class SpringApplicationTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<E extends ApplicationEvent> E getEvent(Class<E> type) {
|
||||
return (E) this.events.get(type).get(0);
|
||||
List<ApplicationEvent> events = this.events.get(type);
|
||||
assertThat(events).isNotNull();
|
||||
return (E) events.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.boot;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -133,11 +134,11 @@ class StartupInfoLoggerTests {
|
||||
|
||||
private final long startTime = System.currentTimeMillis();
|
||||
|
||||
private final Long uptime;
|
||||
private final @Nullable Long uptime;
|
||||
|
||||
private final String action;
|
||||
|
||||
TestStartup(Long uptime, String action) {
|
||||
TestStartup(@Nullable Long uptime, String action) {
|
||||
this.uptime = uptime;
|
||||
this.action = action;
|
||||
started();
|
||||
@@ -149,7 +150,7 @@ class StartupInfoLoggerTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Long processUptime() {
|
||||
protected @Nullable Long processUptime() {
|
||||
return this.uptime;
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -24,6 +24,7 @@ import javax.management.MBeanServer;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -54,7 +55,7 @@ class SpringApplicationAdminMXBeanRegistrarTests {
|
||||
|
||||
private MBeanServer mBeanServer;
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
private @Nullable ConfigurableApplicationContext context;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
@@ -90,15 +91,18 @@ class SpringApplicationAdminMXBeanRegistrarTests {
|
||||
SpringApplicationAdminMXBeanRegistrar registrar = new SpringApplicationAdminMXBeanRegistrar(OBJECT_NAME);
|
||||
ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class);
|
||||
registrar.setApplicationContext(context);
|
||||
registrar.onApplicationReadyEvent(new ApplicationReadyEvent(new SpringApplication(), null,
|
||||
registrar.onApplicationReadyEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0],
|
||||
mock(ConfigurableApplicationContext.class), null));
|
||||
assertThat(isApplicationReady(registrar)).isFalse();
|
||||
registrar.onApplicationReadyEvent(new ApplicationReadyEvent(new SpringApplication(), null, context, null));
|
||||
registrar
|
||||
.onApplicationReadyEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context, null));
|
||||
assertThat(isApplicationReady(registrar)).isTrue();
|
||||
}
|
||||
|
||||
private boolean isApplicationReady(SpringApplicationAdminMXBeanRegistrar registrar) {
|
||||
return (Boolean) ReflectionTestUtils.getField(registrar, "ready");
|
||||
Object field = ReflectionTestUtils.getField(registrar, "ready");
|
||||
assertThat(field).isNotNull();
|
||||
return (Boolean) field;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
@@ -40,6 +40,7 @@ class AvailabilityChangeEventTests {
|
||||
private final Object source = new Object();
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenStateIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new AvailabilityChangeEvent<>(this.source, null))
|
||||
.withMessage("Payload must not be null");
|
||||
|
||||
+16
-8
@@ -18,9 +18,11 @@ package org.springframework.boot.bootstrap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.AssertProvider;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.bootstrap.BootstrapRegistry.InstanceSupplier;
|
||||
@@ -34,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIOException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultBootstrapContext}.
|
||||
@@ -49,12 +52,14 @@ class DefaultBootstrapContextTests {
|
||||
private final StaticApplicationContext applicationContext = new StaticApplicationContext();
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void registerWhenTypeIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.context.register(null, InstanceSupplier.of(1)))
|
||||
.withMessage("'type' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void registerWhenRegistrationIsNullThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.context.register(Integer.class, null))
|
||||
.withMessage("'instanceSupplier' must not be null");
|
||||
@@ -206,20 +211,23 @@ class DefaultBootstrapContextTests {
|
||||
@Test
|
||||
void getOrElseSupplyWhenNoRegistrationReturnsSupplied() {
|
||||
this.context.register(Number.class, InstanceSupplier.of(1));
|
||||
assertThat(this.context.getOrElseSupply(Long.class, () -> -1L)).isEqualTo(-1);
|
||||
Supplier<@Nullable Long> supplier = () -> -1L;
|
||||
assertThat(this.context.getOrElseSupply(Long.class, supplier)).isEqualTo(-1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOrElseSupplyWhenRegisteredAsNullReturnsNull() {
|
||||
this.context.register(Number.class, InstanceSupplier.of(null));
|
||||
assertThat(this.context.getOrElseSupply(Number.class, () -> -1L)).isNull();
|
||||
Supplier<@Nullable Number> supplier = () -> -1L;
|
||||
assertThat(this.context.getOrElseSupply(Number.class, supplier)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOrElseSupplyCreatesOnlyOneInstance() {
|
||||
this.context.register(Integer.class, InstanceSupplier.from(this.counter::getAndIncrement));
|
||||
assertThat(this.context.getOrElseSupply(Integer.class, () -> -1)).isZero();
|
||||
assertThat(this.context.getOrElseSupply(Integer.class, () -> -1)).isZero();
|
||||
Supplier<@Nullable Integer> supplier = () -> -1;
|
||||
assertThat(this.context.getOrElseSupply(Integer.class, supplier)).isZero();
|
||||
assertThat(this.context.getOrElseSupply(Integer.class, supplier)).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -265,14 +273,14 @@ class DefaultBootstrapContextTests {
|
||||
void instanceSupplierGetScopeWhenNotConfiguredReturnsSingleton() {
|
||||
InstanceSupplier<String> supplier = InstanceSupplier.of("test");
|
||||
assertThat(supplier.getScope()).isEqualTo(Scope.SINGLETON);
|
||||
assertThat(supplier.get(null)).isEqualTo("test");
|
||||
assertThat(supplier.get(mock(BootstrapContext.class))).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void instanceSupplierWithScopeChangesScope() {
|
||||
InstanceSupplier<String> supplier = InstanceSupplier.of("test").withScope(Scope.PROTOTYPE);
|
||||
assertThat(supplier.getScope()).isEqualTo(Scope.PROTOTYPE);
|
||||
assertThat(supplier.get(null)).isEqualTo("test");
|
||||
assertThat(supplier.get(mock(BootstrapContext.class))).isEqualTo("test");
|
||||
}
|
||||
|
||||
private static final class TestCloseListener
|
||||
@@ -280,9 +288,9 @@ class DefaultBootstrapContextTests {
|
||||
|
||||
private int called;
|
||||
|
||||
private BootstrapContext bootstrapContext;
|
||||
private @Nullable BootstrapContext bootstrapContext;
|
||||
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
private @Nullable ConfigurableApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(BootstrapContextClosedEvent event) {
|
||||
|
||||
+38
-20
@@ -19,8 +19,10 @@ package org.springframework.boot.builder;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -56,7 +58,7 @@ import static org.mockito.Mockito.spy;
|
||||
*/
|
||||
class SpringApplicationBuilderTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
private @Nullable ConfigurableApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void close() {
|
||||
@@ -64,7 +66,7 @@ class SpringApplicationBuilderTests {
|
||||
SpringApplicationShutdownHookInstance.reset();
|
||||
}
|
||||
|
||||
private void close(ApplicationContext context) {
|
||||
private void close(@Nullable ApplicationContext context) {
|
||||
if (context != null) {
|
||||
if (context instanceof ConfigurableApplicationContext configurableContext) {
|
||||
configurableContext.close();
|
||||
@@ -103,9 +105,11 @@ class SpringApplicationBuilderTests {
|
||||
|
||||
@Test
|
||||
void propertiesAsProperties() {
|
||||
Properties properties = StringUtils.splitArrayElementsIntoProperties(new String[] { "bar=foo" }, "=");
|
||||
assertThat(properties).isNotNull();
|
||||
SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class)
|
||||
.contextFactory(ApplicationContextFactory.ofContextClass(StaticApplicationContext.class))
|
||||
.properties(StringUtils.splitArrayElementsIntoProperties(new String[] { "bar=foo" }, "="));
|
||||
.properties(properties);
|
||||
this.context = application.run();
|
||||
assertThat(this.context.getEnvironment().getProperty("bar")).isEqualTo("foo");
|
||||
}
|
||||
@@ -140,8 +144,9 @@ class SpringApplicationBuilderTests {
|
||||
then(((SpyApplicationContext) this.context).getApplicationContext()).should()
|
||||
.setParent(any(ApplicationContext.class));
|
||||
assertThat(SpringApplicationShutdownHookInstance.get()).didNotRegisterApplicationContext(this.context);
|
||||
assertThat(this.context.getParent().getBean(ApplicationArguments.class).getNonOptionArgs())
|
||||
.contains("foo.bar=baz");
|
||||
ApplicationContext parent = this.context.getParent();
|
||||
assertThat(parent).isNotNull();
|
||||
assertThat(parent.getBean(ApplicationArguments.class).getNonOptionArgs()).contains("foo.bar=baz");
|
||||
assertThat(this.context.getBean(ApplicationArguments.class).getNonOptionArgs()).contains("foo.bar=baz");
|
||||
}
|
||||
|
||||
@@ -154,7 +159,9 @@ class SpringApplicationBuilderTests {
|
||||
then(((SpyApplicationContext) this.context).getApplicationContext()).should()
|
||||
.setParent(any(ApplicationContext.class));
|
||||
assertThat(SpringApplicationShutdownHookInstance.get()).didNotRegisterApplicationContext(this.context);
|
||||
assertThat(this.context.getParent().getBean(ApplicationArguments.class).getNonOptionArgs()).contains("a=alpha");
|
||||
ApplicationContext parent = this.context.getParent();
|
||||
assertThat(parent).isNotNull();
|
||||
assertThat(parent.getBean(ApplicationArguments.class).getNonOptionArgs()).contains("a=alpha");
|
||||
assertThat(this.context.getBean(ApplicationArguments.class).getNonOptionArgs()).contains("b=bravo");
|
||||
}
|
||||
|
||||
@@ -188,7 +195,9 @@ class SpringApplicationBuilderTests {
|
||||
application.resourceLoader(new DefaultResourceLoader(classLoader));
|
||||
application.parent(ExampleConfig.class);
|
||||
this.context = application.run();
|
||||
assertThat(((SpyApplicationContext) this.context).getResourceLoader().getClassLoader()).isEqualTo(classLoader);
|
||||
ResourceLoader resourceLoader = ((SpyApplicationContext) this.context).getResourceLoader();
|
||||
assertThat(resourceLoader).isNotNull();
|
||||
assertThat(resourceLoader.getClassLoader()).isEqualTo(classLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -212,8 +221,10 @@ class SpringApplicationBuilderTests {
|
||||
this.context = application.run();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("node"))).isTrue();
|
||||
assertThat(this.context.getEnvironment().getProperty("transport")).isEqualTo("redis");
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles(Profiles.of("node"))).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment().getProperty("transport")).isEqualTo("redis");
|
||||
ApplicationContext parent = this.context.getParent();
|
||||
assertThat(parent).isNotNull();
|
||||
assertThat(parent.getEnvironment().acceptsProfiles(Profiles.of("node"))).isTrue();
|
||||
assertThat(parent.getEnvironment().getProperty("transport")).isEqualTo("redis");
|
||||
// only defined in node profile
|
||||
assertThat(this.context.getEnvironment().getProperty("bar")).isEqualTo("spam");
|
||||
}
|
||||
@@ -227,7 +238,9 @@ class SpringApplicationBuilderTests {
|
||||
.web(WebApplicationType.NONE);
|
||||
this.context = application.run();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("node", "admin"))).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles(Profiles.of("admin"))).isFalse();
|
||||
ApplicationContext parent = this.context.getParent();
|
||||
assertThat(parent).isNotNull();
|
||||
assertThat(parent.getEnvironment().acceptsProfiles(Profiles.of("admin"))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -240,8 +253,10 @@ class SpringApplicationBuilderTests {
|
||||
shared.profiles("parent");
|
||||
this.context = application.run();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("node", "admin"))).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles(Profiles.of("node", "parent"))).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles(Profiles.of("admin"))).isFalse();
|
||||
ApplicationContext parent = this.context.getParent();
|
||||
assertThat(parent).isNotNull();
|
||||
assertThat(parent.getEnvironment().acceptsProfiles(Profiles.of("node", "parent"))).isTrue();
|
||||
assertThat(parent.getEnvironment().acceptsProfiles(Profiles.of("admin"))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -257,7 +272,9 @@ class SpringApplicationBuilderTests {
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("node", "admin"))).isTrue();
|
||||
// Now they share an Environment explicitly so there's no way to keep the profiles
|
||||
// separate
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles(Profiles.of("admin"))).isTrue();
|
||||
ApplicationContext parent = this.context.getParent();
|
||||
assertThat(parent).isNotNull();
|
||||
assertThat(parent.getEnvironment().acceptsProfiles(Profiles.of("admin"))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -330,7 +347,8 @@ class SpringApplicationBuilderTests {
|
||||
SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(resourceLoader,
|
||||
ExampleConfig.class) {
|
||||
@Override
|
||||
protected SpringApplication createSpringApplication(ResourceLoader resourceLoader, Class<?>... sources) {
|
||||
protected SpringApplication createSpringApplication(@Nullable ResourceLoader resourceLoader,
|
||||
Class<?>... sources) {
|
||||
return new CustomSpringApplication(resourceLoader, sources);
|
||||
}
|
||||
};
|
||||
@@ -351,9 +369,9 @@ class SpringApplicationBuilderTests {
|
||||
|
||||
static class CustomSpringApplication extends SpringApplication {
|
||||
|
||||
private final ResourceLoader resourceLoader;
|
||||
private final @Nullable ResourceLoader resourceLoader;
|
||||
|
||||
CustomSpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
|
||||
CustomSpringApplication(@Nullable ResourceLoader resourceLoader, Class<?>... primarySources) {
|
||||
super(resourceLoader, primarySources);
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
@@ -364,10 +382,10 @@ class SpringApplicationBuilderTests {
|
||||
|
||||
private final ConfigurableApplicationContext applicationContext = spy(new AnnotationConfigApplicationContext());
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
private @Nullable ResourceLoader resourceLoader;
|
||||
|
||||
@Override
|
||||
public void setParent(ApplicationContext parent) {
|
||||
public void setParent(@Nullable ApplicationContext parent) {
|
||||
this.applicationContext.setParent(parent);
|
||||
}
|
||||
|
||||
@@ -381,7 +399,7 @@ class SpringApplicationBuilderTests {
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
ResourceLoader getResourceLoader() {
|
||||
@Nullable ResourceLoader getResourceLoader() {
|
||||
return this.resourceLoader;
|
||||
}
|
||||
|
||||
@@ -392,7 +410,7 @@ class SpringApplicationBuilderTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationContext getParent() {
|
||||
public @Nullable ApplicationContext getParent() {
|
||||
return this.applicationContext.getParent();
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ class CloudPlatformTests {
|
||||
void getActiveWhenHasVcapApplicationShouldReturnCloudFoundry() {
|
||||
Environment environment = new MockEnvironment().withProperty("VCAP_APPLICATION", "---");
|
||||
CloudPlatform platform = CloudPlatform.getActive(environment);
|
||||
assertThat(platform).isNotNull();
|
||||
assertThat(platform).isEqualTo(CloudPlatform.CLOUD_FOUNDRY);
|
||||
assertThat(platform.isActive(environment)).isTrue();
|
||||
}
|
||||
@@ -66,6 +67,7 @@ class CloudPlatformTests {
|
||||
void getActiveWhenHasVcapServicesShouldReturnCloudFoundry() {
|
||||
Environment environment = new MockEnvironment().withProperty("VCAP_SERVICES", "---");
|
||||
CloudPlatform platform = CloudPlatform.getActive(environment);
|
||||
assertThat(platform).isNotNull();
|
||||
assertThat(platform).isEqualTo(CloudPlatform.CLOUD_FOUNDRY);
|
||||
assertThat(platform.isActive(environment)).isTrue();
|
||||
}
|
||||
@@ -74,6 +76,7 @@ class CloudPlatformTests {
|
||||
void getActiveWhenHasDynoShouldReturnHeroku() {
|
||||
Environment environment = new MockEnvironment().withProperty("DYNO", "---");
|
||||
CloudPlatform platform = CloudPlatform.getActive(environment);
|
||||
assertThat(platform).isNotNull();
|
||||
assertThat(platform).isEqualTo(CloudPlatform.HEROKU);
|
||||
assertThat(platform.isActive(environment)).isTrue();
|
||||
}
|
||||
@@ -82,6 +85,7 @@ class CloudPlatformTests {
|
||||
void getActiveWhenHasHcLandscapeShouldReturnSap() {
|
||||
Environment environment = new MockEnvironment().withProperty("HC_LANDSCAPE", "---");
|
||||
CloudPlatform platform = CloudPlatform.getActive(environment);
|
||||
assertThat(platform).isNotNull();
|
||||
assertThat(platform).isEqualTo(CloudPlatform.SAP);
|
||||
assertThat(platform.isActive(environment)).isTrue();
|
||||
}
|
||||
@@ -90,6 +94,7 @@ class CloudPlatformTests {
|
||||
void getActiveWhenHasNomadAllocIdShouldReturnNomad() {
|
||||
Environment environment = new MockEnvironment().withProperty("NOMAD_ALLOC_ID", "---");
|
||||
CloudPlatform platform = CloudPlatform.getActive(environment);
|
||||
assertThat(platform).isNotNull();
|
||||
assertThat(platform).isEqualTo(CloudPlatform.NOMAD);
|
||||
assertThat(platform.isActive(environment)).isTrue();
|
||||
}
|
||||
@@ -101,6 +106,7 @@ class CloudPlatformTests {
|
||||
envVars.put("KUBERNETES_SERVICE_PORT", "8080");
|
||||
Environment environment = getEnvironmentWithEnvVariables(envVars);
|
||||
CloudPlatform platform = CloudPlatform.getActive(environment);
|
||||
assertThat(platform).isNotNull();
|
||||
assertThat(platform).isEqualTo(CloudPlatform.KUBERNETES);
|
||||
assertThat(platform.isActive(environment)).isTrue();
|
||||
}
|
||||
@@ -128,6 +134,7 @@ class CloudPlatformTests {
|
||||
envVars.put("EXAMPLE_SERVICE_PORT", "8080");
|
||||
Environment environment = getEnvironmentWithEnvVariables(envVars);
|
||||
CloudPlatform platform = CloudPlatform.getActive(environment);
|
||||
assertThat(platform).isNotNull();
|
||||
assertThat(platform).isEqualTo(CloudPlatform.KUBERNETES);
|
||||
assertThat(platform.isActive(environment)).isTrue();
|
||||
}
|
||||
@@ -149,6 +156,7 @@ class CloudPlatformTests {
|
||||
envVars.put("WEBSITE_SKU", "1234");
|
||||
Environment environment = getEnvironmentWithEnvVariables(envVars);
|
||||
CloudPlatform platform = CloudPlatform.getActive(environment);
|
||||
assertThat(platform).isNotNull();
|
||||
assertThat(platform).isEqualTo(CloudPlatform.AZURE_APP_SERVICE);
|
||||
assertThat(platform.isActive(environment)).isTrue();
|
||||
}
|
||||
|
||||
+1
@@ -57,6 +57,7 @@ class ApplicationPidFileWriterTests {
|
||||
new String[] {}, mock(ConfigurableApplicationContext.class));
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File tempDir;
|
||||
|
||||
@BeforeEach
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -87,7 +88,8 @@ class ContextIdApplicationContextInitializerTests {
|
||||
assertThat(createContext(parent).getId()).isEqualTo("application");
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext createContext(ConfigurableApplicationContext parent, String... properties) {
|
||||
private ConfigurableApplicationContext createContext(@Nullable ConfigurableApplicationContext parent,
|
||||
String... properties) {
|
||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, properties);
|
||||
if (parent != null) {
|
||||
|
||||
+6
-3
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot.context;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -39,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
*/
|
||||
class TypeExcludeFilterTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
private @Nullable AnnotationConfigApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
@@ -56,8 +57,10 @@ class TypeExcludeFilterTests {
|
||||
this.context.register(Config.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleComponent.class)).isNotNull();
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean(ExampleFilteredComponent.class));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() -> {
|
||||
assertThat(this.context).isNotNull();
|
||||
this.context.getBean(ExampleFilteredComponent.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
|
||||
+3
-1
@@ -27,6 +27,7 @@ import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
@@ -44,6 +45,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class ConfigurationsTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenClassesIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new TestConfigurations((Collection<Class<?>>) null))
|
||||
.withMessageContaining("'classes' must not be null");
|
||||
@@ -91,7 +93,7 @@ class ConfigurationsTests {
|
||||
}
|
||||
|
||||
TestConfigurations(UnaryOperator<Collection<Class<?>>> sorter, Collection<Class<?>> classes,
|
||||
Function<Class<?>, String> beanNameGenerator) {
|
||||
@Nullable Function<Class<?>, String> beanNameGenerator) {
|
||||
super(sorter, classes, beanNameGenerator);
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.origin.Origin;
|
||||
@@ -120,7 +121,9 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests {
|
||||
private Consumer<InactiveConfigDataAccessException> propertyNameAndOriginOf(String propertyName, String origin) {
|
||||
return (ex) -> {
|
||||
assertThat(ex.getPropertyName()).isEqualTo(propertyName);
|
||||
assertThat(((PropertySourceOrigin) (ex.getOrigin())).getPropertySource().getName()).isEqualTo(origin);
|
||||
PropertySourceOrigin actualOrigin = (PropertySourceOrigin) (ex.getOrigin());
|
||||
assertThat(actualOrigin).isNotNull();
|
||||
assertThat(actualOrigin.getPropertySource().getName()).isEqualTo(origin);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -135,7 +138,7 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Origin getOrigin(String key) {
|
||||
public @Nullable Origin getOrigin(String key) {
|
||||
if (getSource().containsKey(key)) {
|
||||
return new PropertySourceOrigin(this, key);
|
||||
}
|
||||
@@ -155,7 +158,7 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isActive(ConfigDataActivationContext activationContext) {
|
||||
boolean isActive(@Nullable ConfigDataActivationContext activationContext) {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
|
||||
+13
-6
@@ -23,6 +23,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
@@ -30,7 +31,9 @@ import org.springframework.boot.context.config.ConfigData.Option;
|
||||
import org.springframework.boot.context.config.ConfigData.PropertySourceOptions;
|
||||
import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.ImportPhase;
|
||||
import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.Kind;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationProperty;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.mock.env.MockPropertySource;
|
||||
@@ -110,9 +113,11 @@ class ConfigDataEnvironmentContributorTests {
|
||||
ConfigData configData = new ConfigData(Collections.singleton(propertySource));
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null, null,
|
||||
false, configData, 0, this.conversionService, ConfigDataEnvironmentUpdateListener.NONE);
|
||||
assertThat(contributor.getConfigurationPropertySource()
|
||||
.getConfigurationProperty(ConfigurationPropertyName.of("spring"))
|
||||
.getValue()).isEqualTo("boot");
|
||||
ConfigurationPropertySource source = contributor.getConfigurationPropertySource();
|
||||
assertThat(source).isNotNull();
|
||||
ConfigurationProperty spring = source.getConfigurationProperty(ConfigurationPropertyName.of("spring"));
|
||||
assertThat(spring).isNotNull();
|
||||
assertThat(spring.getValue()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -379,8 +384,8 @@ class ConfigDataEnvironmentContributorTests {
|
||||
new ConfigData(Collections.singleton(new MockPropertySource())), 0);
|
||||
}
|
||||
|
||||
private ConfigDataEnvironmentContributor createBoundContributor(ConfigDataResource resource, ConfigData configData,
|
||||
int propertySourceIndex) {
|
||||
private ConfigDataEnvironmentContributor createBoundContributor(@Nullable ConfigDataResource resource,
|
||||
ConfigData configData, int propertySourceIndex) {
|
||||
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION,
|
||||
resource, false, configData, propertySourceIndex, this.conversionService,
|
||||
ConfigDataEnvironmentUpdateListener.NONE);
|
||||
@@ -394,7 +399,9 @@ class ConfigDataEnvironmentContributorTests {
|
||||
}
|
||||
|
||||
private String getLocationName(ConfigDataEnvironmentContributor contributor) {
|
||||
return contributor.getResource().toString();
|
||||
ConfigDataResource resource = contributor.getResource();
|
||||
assertThat(resource).isNotNull();
|
||||
return resource.toString();
|
||||
}
|
||||
|
||||
static class TestResource extends ConfigDataResource {
|
||||
|
||||
+1
@@ -63,6 +63,7 @@ class ConfigDataEnvironmentPostProcessorImportCombinedWithProfileSpecificIntegra
|
||||
private SpringApplication application;
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
public File temp;
|
||||
|
||||
@BeforeEach
|
||||
|
||||
+8
-3
@@ -32,6 +32,7 @@ import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -84,6 +85,7 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
|
||||
private SpringApplication application;
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
public File temp;
|
||||
|
||||
@BeforeEach
|
||||
@@ -814,7 +816,7 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
|
||||
MapPropertySource propertySource = new MapPropertySource("defaultProperties", source) {
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
public @Nullable Object getProperty(String name) {
|
||||
if ("spring.config.name".equals(name)) {
|
||||
return "gh17001";
|
||||
}
|
||||
@@ -1088,8 +1090,11 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
|
||||
binder.bind("my.value", Bindable.of(String.class), bindHandler);
|
||||
assertThat(properties).hasSize(1);
|
||||
Origin origin = properties.get(0).getOrigin();
|
||||
assertThat(origin).isNotNull();
|
||||
assertThat(origin.toString()).contains("imported.properties");
|
||||
assertThat(origin.getParent().toString()).contains("application.properties");
|
||||
Origin parent = origin.getParent();
|
||||
assertThat(parent).isNotNull();
|
||||
assertThat(parent.toString()).contains("application.properties");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1315,7 +1320,7 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
|
||||
static class Loader implements ConfigDataLoader<TestConfigDataResource> {
|
||||
|
||||
@Override
|
||||
public ConfigData load(ConfigDataLoaderContext context, TestConfigDataResource resource)
|
||||
public @Nullable ConfigData load(ConfigDataLoaderContext context, TestConfigDataResource resource)
|
||||
throws IOException, ConfigDataResourceNotFoundException {
|
||||
if (resource.isOptional()) {
|
||||
return null;
|
||||
|
||||
+15
-4
@@ -19,6 +19,7 @@ package org.springframework.boot.context.config;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
@@ -51,13 +52,15 @@ class ConfigDataEnvironmentPostProcessorTests {
|
||||
|
||||
private final SpringApplication application = new SpringApplication();
|
||||
|
||||
private ConfigDataEnvironment configDataEnvironment;
|
||||
private @Nullable ConfigDataEnvironment configDataEnvironment;
|
||||
|
||||
private ConfigDataEnvironmentPostProcessor postProcessor;
|
||||
private @Nullable ConfigDataEnvironmentPostProcessor postProcessor;
|
||||
|
||||
@Test
|
||||
void postProcessEnvironmentWhenNoLoaderCreatesDefaultLoaderInstance() {
|
||||
setupMocksAndSpies();
|
||||
assertThat(this.configDataEnvironment).isNotNull();
|
||||
assertThat(this.postProcessor).isNotNull();
|
||||
willReturn(this.configDataEnvironment).given(this.postProcessor).getConfigDataEnvironment(any(), any(), any());
|
||||
this.postProcessor.postProcessEnvironment(this.environment, this.application);
|
||||
then(this.postProcessor).should()
|
||||
@@ -70,6 +73,8 @@ class ConfigDataEnvironmentPostProcessorTests {
|
||||
@Test
|
||||
void postProcessEnvironmentWhenCustomLoaderUsesSpecifiedLoaderInstance() {
|
||||
setupMocksAndSpies();
|
||||
assertThat(this.configDataEnvironment).isNotNull();
|
||||
assertThat(this.postProcessor).isNotNull();
|
||||
ResourceLoader resourceLoader = mock(ResourceLoader.class);
|
||||
this.application.setResourceLoader(resourceLoader);
|
||||
willReturn(this.configDataEnvironment).given(this.postProcessor).getConfigDataEnvironment(any(), any(), any());
|
||||
@@ -83,6 +88,8 @@ class ConfigDataEnvironmentPostProcessorTests {
|
||||
@Test
|
||||
void postProcessEnvironmentWhenHasAdditionalProfilesOnSpringApplicationUsesAdditionalProfiles() {
|
||||
setupMocksAndSpies();
|
||||
assertThat(this.configDataEnvironment).isNotNull();
|
||||
assertThat(this.postProcessor).isNotNull();
|
||||
this.application.setAdditionalProfiles("dev");
|
||||
willReturn(this.configDataEnvironment).given(this.postProcessor).getConfigDataEnvironment(any(), any(), any());
|
||||
this.postProcessor.postProcessEnvironment(this.environment, this.application);
|
||||
@@ -95,6 +102,8 @@ class ConfigDataEnvironmentPostProcessorTests {
|
||||
@Test
|
||||
void postProcessEnvironmentWhenNoActiveProfiles() {
|
||||
setupMocksAndSpies();
|
||||
assertThat(this.configDataEnvironment).isNotNull();
|
||||
assertThat(this.postProcessor).isNotNull();
|
||||
willReturn(this.configDataEnvironment).given(this.postProcessor).getConfigDataEnvironment(any(), any(), any());
|
||||
this.postProcessor.postProcessEnvironment(this.environment, this.application);
|
||||
then(this.postProcessor).should().getConfigDataEnvironment(any(), any(ResourceLoader.class), any());
|
||||
@@ -113,7 +122,9 @@ class ConfigDataEnvironmentPostProcessorTests {
|
||||
assertThat(this.environment.getPropertySources()).hasSizeGreaterThan(before);
|
||||
assertThat(this.environment.getActiveProfiles()).containsExactly("dev");
|
||||
assertThat(listener.getAddedPropertySources()).isNotEmpty();
|
||||
assertThat(listener.getProfiles().getActive()).containsExactly("dev");
|
||||
Profiles profiles = listener.getProfiles();
|
||||
assertThat(profiles).isNotNull();
|
||||
assertThat(profiles.getActive()).containsExactly("dev");
|
||||
assertThat(listener.getAddedPropertySources().stream().anyMatch((added) -> hasDevProfile(added.getResource())))
|
||||
.isTrue();
|
||||
}
|
||||
@@ -147,7 +158,7 @@ class ConfigDataEnvironmentPostProcessorTests {
|
||||
this.postProcessor = spy(new ConfigDataEnvironmentPostProcessor(Supplier::get, new DefaultBootstrapContext()));
|
||||
}
|
||||
|
||||
private boolean hasDevProfile(ConfigDataResource resource) {
|
||||
private boolean hasDevProfile(@Nullable ConfigDataResource resource) {
|
||||
return (resource instanceof StandardConfigDataResource standardResource)
|
||||
&& "dev".equals(standardResource.getProfile());
|
||||
}
|
||||
|
||||
+15
-9
@@ -27,6 +27,7 @@ import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -81,8 +82,9 @@ class ConfigDataEnvironmentTests {
|
||||
this.environment.setProperty("spring", "boot");
|
||||
TestConfigDataEnvironment configDataEnvironment = new TestConfigDataEnvironment(this.logFactory,
|
||||
this.bootstrapContext, this.environment, this.resourceLoader, this.additionalProfiles, null);
|
||||
assertThat(configDataEnvironment.getConfigDataLocationResolversBinder().bind("spring", String.class).get())
|
||||
.isEqualTo("boot");
|
||||
Binder binder = configDataEnvironment.getConfigDataLocationResolversBinder();
|
||||
assertThat(binder).isNotNull();
|
||||
assertThat(binder.bind("spring", String.class).get()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -335,8 +337,9 @@ class ConfigDataEnvironmentTests {
|
||||
AddedPropertySource addedPropertySource = listener.getAddedPropertySources().get(0);
|
||||
assertThat(addedPropertySource.getPropertySource().getProperty("spring")).isEqualTo("boot");
|
||||
assertThat(addedPropertySource.getLocation()).hasToString("classpath:custom/config.properties");
|
||||
assertThat(addedPropertySource.getResource().toString()).contains("class path resource")
|
||||
.contains("custom/config.properties");
|
||||
ConfigDataResource resource = addedPropertySource.getResource();
|
||||
assertThat(resource).isNotNull();
|
||||
assertThat(resource.toString()).contains("class path resource").contains("custom/config.properties");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -346,7 +349,9 @@ class ConfigDataEnvironmentTests {
|
||||
ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext,
|
||||
this.environment, this.resourceLoader, this.additionalProfiles, listener);
|
||||
configDataEnvironment.processAndApply();
|
||||
assertThat(listener.getProfiles().getActive()).containsExactly("one", "two", "three");
|
||||
Profiles profiles = listener.getProfiles();
|
||||
assertThat(profiles).isNotNull();
|
||||
assertThat(profiles.getActive()).containsExactly("one", "two", "three");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -384,11 +389,12 @@ class ConfigDataEnvironmentTests {
|
||||
|
||||
static class TestConfigDataEnvironment extends ConfigDataEnvironment {
|
||||
|
||||
private Binder configDataLocationResolversBinder;
|
||||
private @Nullable Binder configDataLocationResolversBinder;
|
||||
|
||||
TestConfigDataEnvironment(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext,
|
||||
ConfigurableEnvironment environment, ResourceLoader resourceLoader,
|
||||
Collection<String> additionalProfiles, ConfigDataEnvironmentUpdateListener environmentUpdateListener) {
|
||||
Collection<String> additionalProfiles,
|
||||
@Nullable ConfigDataEnvironmentUpdateListener environmentUpdateListener) {
|
||||
super(logFactory, bootstrapContext, environment, resourceLoader, additionalProfiles,
|
||||
environmentUpdateListener);
|
||||
}
|
||||
@@ -400,7 +406,7 @@ class ConfigDataEnvironmentTests {
|
||||
return super.createConfigDataLocationResolvers(logFactory, bootstrapContext, binder, resourceLoader);
|
||||
}
|
||||
|
||||
Binder getConfigDataLocationResolversBinder() {
|
||||
@Nullable Binder getConfigDataLocationResolversBinder() {
|
||||
return this.configDataLocationResolversBinder;
|
||||
}
|
||||
|
||||
@@ -409,7 +415,7 @@ class ConfigDataEnvironmentTests {
|
||||
static class SeparateClassLoaderConfigDataLoader implements ConfigDataLoader<ConfigDataResource> {
|
||||
|
||||
@Override
|
||||
public ConfigData load(ConfigDataLoaderContext context, ConfigDataResource resource)
|
||||
public @Nullable ConfigData load(ConfigDataLoaderContext context, ConfigDataResource resource)
|
||||
throws IOException, ConfigDataResourceNotFoundException {
|
||||
return null;
|
||||
}
|
||||
|
||||
+7
@@ -47,24 +47,31 @@ class ConfigDataImporterTests {
|
||||
private final DeferredLogFactory logFactory = Supplier::get;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ConfigDataLocationResolvers resolvers;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ConfigDataLoaders loaders;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Binder binder;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ConfigDataLocationResolverContext locationResolverContext;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ConfigDataLoaderContext loaderContext;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ConfigDataActivationContext activationContext;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Profiles profiles;
|
||||
|
||||
@BeforeEach
|
||||
|
||||
+3
-1
@@ -18,6 +18,7 @@ package org.springframework.boot.context.config;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -43,7 +44,8 @@ class ConfigDataLoaderTests {
|
||||
static class TestConfigDataLoader implements ConfigDataLoader<TestConfigDataResource> {
|
||||
|
||||
@Override
|
||||
public ConfigData load(ConfigDataLoaderContext context, TestConfigDataResource resource) throws IOException {
|
||||
public @Nullable ConfigData load(ConfigDataLoaderContext context, TestConfigDataResource resource)
|
||||
throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -25,7 +24,6 @@ import java.util.function.Supplier;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.bootstrap.BootstrapContext;
|
||||
import org.springframework.boot.bootstrap.BootstrapRegistry;
|
||||
@@ -56,9 +54,6 @@ class ConfigDataLoadersTests {
|
||||
|
||||
private final ConfigDataLoaderContext context = mock(ConfigDataLoaderContext.class);
|
||||
|
||||
@TempDir
|
||||
private File tempDir;
|
||||
|
||||
@Test
|
||||
void createWhenLoaderHasDeferredLogFactoryParameterInjectsDeferredLogFactory() {
|
||||
MockSpringFactoriesLoader springFactoriesLoader = new MockSpringFactoriesLoader();
|
||||
@@ -103,6 +98,7 @@ class ConfigDataLoadersTests {
|
||||
springFactoriesLoader);
|
||||
TestConfigDataResource location = new TestConfigDataResource("test");
|
||||
ConfigData loaded = loaders.load(this.context, location);
|
||||
assertThat(loaded).isNotNull();
|
||||
assertThat(getLoader(loaded)).isInstanceOf(TestConfigDataLoader.class);
|
||||
}
|
||||
|
||||
@@ -136,11 +132,14 @@ class ConfigDataLoadersTests {
|
||||
springFactoriesLoader);
|
||||
TestConfigDataResource location = new TestConfigDataResource("test");
|
||||
ConfigData loaded = loaders.load(this.context, location);
|
||||
assertThat(loaded).isNotNull();
|
||||
assertThat(getLoader(loaded)).isInstanceOf(SpecificConfigDataLoader.class);
|
||||
}
|
||||
|
||||
private ConfigDataLoader<?> getLoader(ConfigData loaded) {
|
||||
return (ConfigDataLoader<?>) loaded.getPropertySources().get(0).getProperty("loader");
|
||||
ConfigDataLoader<?> result = (ConfigDataLoader<?>) loaded.getPropertySources().get(0).getProperty("loader");
|
||||
assertThat(result).isNotNull();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ConfigData createConfigData(ConfigDataLoader<?> loader, ConfigDataResource resource) {
|
||||
|
||||
+1
@@ -39,6 +39,7 @@ class ConfigDataLocationNotFoundExceptionTests {
|
||||
this.location);
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenLocationIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigDataLocationNotFoundException(null))
|
||||
.withMessage("'location' must not be null");
|
||||
|
||||
+9
-2
@@ -16,10 +16,14 @@
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@@ -37,7 +41,10 @@ class ConfigDataLocationResolverTests {
|
||||
|
||||
@Test
|
||||
void resolveProfileSpecificReturnsEmptyList() {
|
||||
assertThat(this.resolver.resolveProfileSpecific(this.context, null, null)).isEmpty();
|
||||
ConfigDataLocation location = ConfigDataLocation.of("location");
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
Profiles profiles = new Profiles(environment, Binder.get(environment), null);
|
||||
assertThat(this.resolver.resolveProfileSpecific(this.context, location, profiles)).isEmpty();
|
||||
}
|
||||
|
||||
static class TestConfigDataLocationResolver implements ConfigDataLocationResolver<ConfigDataResource> {
|
||||
@@ -50,7 +57,7 @@ class ConfigDataLocationResolverTests {
|
||||
@Override
|
||||
public List<ConfigDataResource> resolve(ConfigDataLocationResolverContext context,
|
||||
ConfigDataLocation location) {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
@@ -56,15 +56,19 @@ class ConfigDataLocationResolversTests {
|
||||
private final DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Binder binder;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ConfigDataLocationResolverContext context;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Profiles profiles;
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private File tempDir;
|
||||
|
||||
@Test
|
||||
|
||||
+6
-5
@@ -20,6 +20,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.ResourcePatternHint;
|
||||
@@ -60,7 +61,7 @@ class ConfigDataLocationRuntimeHintsTests {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
new TestConfigDataLocationRuntimeHints() {
|
||||
@Override
|
||||
protected List<String> getFileNames(ClassLoader classLoader) {
|
||||
protected List<String> getFileNames(@Nullable ClassLoader classLoader) {
|
||||
return List.of("test");
|
||||
}
|
||||
|
||||
@@ -77,7 +78,7 @@ class ConfigDataLocationRuntimeHintsTests {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
new TestConfigDataLocationRuntimeHints() {
|
||||
@Override
|
||||
protected List<String> getLocations(ClassLoader classLoader) {
|
||||
protected List<String> getLocations(@Nullable ClassLoader classLoader) {
|
||||
return List.of("config/");
|
||||
}
|
||||
}.registerHints(hints, Thread.currentThread().getContextClassLoader());
|
||||
@@ -93,7 +94,7 @@ class ConfigDataLocationRuntimeHintsTests {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
new ConfigDataLocationRuntimeHints() {
|
||||
@Override
|
||||
protected List<String> getExtensions(ClassLoader classLoader) {
|
||||
protected List<String> getExtensions(@Nullable ClassLoader classLoader) {
|
||||
return List.of(".conf");
|
||||
}
|
||||
}.registerHints(hints, Thread.currentThread().getContextClassLoader());
|
||||
@@ -106,7 +107,7 @@ class ConfigDataLocationRuntimeHintsTests {
|
||||
RuntimeHints hints = new RuntimeHints();
|
||||
new ConfigDataLocationRuntimeHints() {
|
||||
@Override
|
||||
protected List<String> getLocations(ClassLoader classLoader) {
|
||||
protected List<String> getLocations(@Nullable ClassLoader classLoader) {
|
||||
return List.of(UUID.randomUUID().toString());
|
||||
}
|
||||
}.registerHints(hints, Thread.currentThread().getContextClassLoader());
|
||||
@@ -138,7 +139,7 @@ class ConfigDataLocationRuntimeHintsTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SpringFactoriesLoader getSpringFactoriesLoader(ClassLoader classLoader) {
|
||||
protected SpringFactoriesLoader getSpringFactoriesLoader(@Nullable ClassLoader classLoader) {
|
||||
return this.springFactoriesLoader;
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -38,6 +38,7 @@ class ConfigDataNotFoundFailureAnalyzerTests {
|
||||
ConfigDataLocation location = ConfigDataLocation.of("test");
|
||||
ConfigDataLocationNotFoundException exception = new ConfigDataLocationNotFoundException(location);
|
||||
FailureAnalysis result = this.analyzer.analyze(exception);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getDescription()).isEqualTo("Config data location 'test' does not exist");
|
||||
assertThat(result.getAction())
|
||||
.isEqualTo("Check that the value 'test' is correct, or prefix it with 'optional:'");
|
||||
@@ -48,6 +49,7 @@ class ConfigDataNotFoundFailureAnalyzerTests {
|
||||
ConfigDataLocation location = ConfigDataLocation.of("optional:test");
|
||||
ConfigDataLocationNotFoundException exception = new ConfigDataLocationNotFoundException(location);
|
||||
FailureAnalysis result = this.analyzer.analyze(exception);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getDescription()).isEqualTo("Config data location 'optional:test' does not exist");
|
||||
assertThat(result.getAction()).isEqualTo("Check that the value 'optional:test' is correct");
|
||||
}
|
||||
@@ -57,6 +59,7 @@ class ConfigDataNotFoundFailureAnalyzerTests {
|
||||
ConfigDataLocation location = ConfigDataLocation.of("test").withOrigin(new TestOrigin("origin"));
|
||||
ConfigDataLocationNotFoundException exception = new ConfigDataLocationNotFoundException(location);
|
||||
FailureAnalysis result = this.analyzer.analyze(exception);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getDescription()).isEqualTo("Config data location 'test' does not exist");
|
||||
assertThat(result.getAction())
|
||||
.isEqualTo("Check that the value 'test' at origin is correct, or prefix it with 'optional:'");
|
||||
@@ -67,6 +70,7 @@ class ConfigDataNotFoundFailureAnalyzerTests {
|
||||
ConfigDataResource resource = new TestConfigDataResource("myresource");
|
||||
ConfigDataResourceNotFoundException exception = new ConfigDataResourceNotFoundException(resource);
|
||||
FailureAnalysis result = this.analyzer.analyze(exception);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getDescription()).isEqualTo("Config data resource 'myresource' does not exist");
|
||||
assertThat(result.getAction()).isEqualTo("Check that the value is correct");
|
||||
}
|
||||
@@ -78,6 +82,7 @@ class ConfigDataNotFoundFailureAnalyzerTests {
|
||||
ConfigDataResourceNotFoundException exception = new ConfigDataResourceNotFoundException(resource)
|
||||
.withLocation(location);
|
||||
FailureAnalysis result = this.analyzer.analyze(exception);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getDescription())
|
||||
.isEqualTo("Config data resource 'myresource' via location 'test' does not exist");
|
||||
assertThat(result.getAction())
|
||||
|
||||
+9
-2
@@ -20,6 +20,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
@@ -39,9 +40,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class ConfigDataPropertiesTests {
|
||||
|
||||
private static final CloudPlatform NULL_CLOUD_PLATFORM = null;
|
||||
private static final @Nullable CloudPlatform NULL_CLOUD_PLATFORM = null;
|
||||
|
||||
private static final Profiles NULL_PROFILES = null;
|
||||
private static final @Nullable Profiles NULL_PROFILES = null;
|
||||
|
||||
private static final List<ConfigDataLocation> NO_IMPORTS = Collections.emptyList();
|
||||
|
||||
@@ -173,6 +174,7 @@ class ConfigDataPropertiesTests {
|
||||
ConfigDataProperties properties = ConfigDataProperties.get(binder);
|
||||
ConfigDataActivationContext context = new ConfigDataActivationContext(CloudPlatform.KUBERNETES,
|
||||
createTestProfiles());
|
||||
assertThat(properties).isNotNull();
|
||||
assertThat(properties.isActive(context)).isTrue();
|
||||
}
|
||||
|
||||
@@ -185,6 +187,7 @@ class ConfigDataPropertiesTests {
|
||||
ConfigDataProperties properties = ConfigDataProperties.get(binder);
|
||||
ConfigDataActivationContext context = new ConfigDataActivationContext(CloudPlatform.KUBERNETES,
|
||||
createTestProfiles());
|
||||
assertThat(properties).isNotNull();
|
||||
assertThat(properties.isActive(context)).isFalse();
|
||||
}
|
||||
|
||||
@@ -197,6 +200,7 @@ class ConfigDataPropertiesTests {
|
||||
ConfigDataProperties properties = ConfigDataProperties.get(binder);
|
||||
ConfigDataActivationContext context = new ConfigDataActivationContext(CloudPlatform.KUBERNETES,
|
||||
createTestProfiles());
|
||||
assertThat(properties).isNotNull();
|
||||
assertThat(properties.isActive(context)).isFalse();
|
||||
}
|
||||
|
||||
@@ -208,6 +212,7 @@ class ConfigDataPropertiesTests {
|
||||
ConfigDataProperties properties = ConfigDataProperties.get(binder);
|
||||
ConfigDataActivationContext context = new ConfigDataActivationContext(NULL_CLOUD_PLATFORM,
|
||||
createTestProfiles());
|
||||
assertThat(properties).isNotNull();
|
||||
assertThat(properties.isActive(context)).isTrue();
|
||||
}
|
||||
|
||||
@@ -217,6 +222,7 @@ class ConfigDataPropertiesTests {
|
||||
source.put("spring.config.import", "one,two,three");
|
||||
Binder binder = new Binder(source);
|
||||
ConfigDataProperties properties = ConfigDataProperties.get(binder);
|
||||
assertThat(properties).isNotNull();
|
||||
assertThat(properties.getImports().get(1).getOrigin())
|
||||
.hasToString("\"spring.config.import\" from property source \"source\"");
|
||||
}
|
||||
@@ -229,6 +235,7 @@ class ConfigDataPropertiesTests {
|
||||
source.put("spring.config.import[2]", "three");
|
||||
Binder binder = new Binder(source);
|
||||
ConfigDataProperties properties = ConfigDataProperties.get(binder);
|
||||
assertThat(properties).isNotNull();
|
||||
assertThat(properties.getImports().get(1).getOrigin())
|
||||
.hasToString("\"spring.config.import[1]\" from property source \"source\"");
|
||||
}
|
||||
|
||||
+2
@@ -49,6 +49,7 @@ class ConfigDataResourceNotFoundExceptionTests {
|
||||
private File missing;
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File temp;
|
||||
|
||||
@BeforeEach
|
||||
@@ -61,6 +62,7 @@ class ConfigDataResourceNotFoundExceptionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenResourceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigDataResourceNotFoundException(null))
|
||||
.withMessage("'resource' must not be null");
|
||||
|
||||
+5
-2
@@ -42,12 +42,14 @@ import static org.mockito.Mockito.mock;
|
||||
class ConfigDataTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenPropertySourcesIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigData(null))
|
||||
.withMessage("'propertySources' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenOptionsIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigData(Collections.emptyList(), (Option[]) null))
|
||||
.withMessage("'options' must not be null");
|
||||
@@ -127,8 +129,9 @@ class ConfigDataTests {
|
||||
@Test
|
||||
void propertySourceOptionsAlwaysReturnsSameOptionsEachTime() {
|
||||
PropertySourceOptions options = PropertySourceOptions.always(Option.IGNORE_IMPORTS, Option.IGNORE_PROFILES);
|
||||
assertThat(options.get(mock(PropertySource.class)).asSet()).containsExactly(Option.IGNORE_IMPORTS,
|
||||
Option.IGNORE_PROFILES);
|
||||
Options propertySourceOptions = options.get(mock(PropertySource.class));
|
||||
assertThat(propertySourceOptions).isNotNull();
|
||||
assertThat(propertySourceOptions.asSet()).containsExactly(Option.IGNORE_IMPORTS, Option.IGNORE_PROFILES);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
@@ -44,6 +44,7 @@ class ConfigTreeConfigDataLoaderTests {
|
||||
private final ConfigDataLoaderContext loaderContext = mock(ConfigDataLoaderContext.class);
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
Path directory;
|
||||
|
||||
@Test
|
||||
|
||||
+1
@@ -42,6 +42,7 @@ class ConfigTreeConfigDataLocationResolverTests {
|
||||
private final ConfigDataLocationResolverContext context = mock(ConfigDataLocationResolverContext.class);
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File temp;
|
||||
|
||||
@Test
|
||||
|
||||
+2
@@ -33,12 +33,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class ConfigTreeConfigDataResourceTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void constructorWhenPathStringIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigTreeConfigDataResource((String) null))
|
||||
.withMessage("'path' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void constructorWhenPathIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigTreeConfigDataResource((Path) null))
|
||||
.withMessage("'path' must not be null");
|
||||
|
||||
+1
@@ -40,6 +40,7 @@ class LocationResourceLoaderTests {
|
||||
private final LocationResourceLoader loader = new LocationResourceLoader(new DefaultResourceLoader());
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File temp;
|
||||
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -258,7 +258,7 @@ class StandardConfigDataLocationResolverTests {
|
||||
assertThat(locations).hasSize(1);
|
||||
StandardConfigDataResource resolved = locations.get(0);
|
||||
assertThat(resolved.getResource().getFilename()).endsWith("application-props-no-extension");
|
||||
ConfigData loaded = new StandardConfigDataLoader().load(null, resolved);
|
||||
ConfigData loaded = new StandardConfigDataLoader().load(mock(ConfigDataLoaderContext.class), resolved);
|
||||
PropertySource<?> propertySource = loaded.getPropertySources().get(0);
|
||||
assertThat(propertySource.getProperty("withnoextension")).isEqualTo("test");
|
||||
}
|
||||
|
||||
+3
@@ -46,12 +46,14 @@ class StandardConfigDataResourceTests {
|
||||
private final Resource resource = mock(Resource.class);
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenReferenceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new StandardConfigDataResource(null, this.resource))
|
||||
.withMessage("'reference' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenResourceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new StandardConfigDataResource(this.reference, null))
|
||||
.withMessage("'resource' must not be null");
|
||||
@@ -78,6 +80,7 @@ class StandardConfigDataResourceTests {
|
||||
@WithResource(name = "test.resource", content = "test")
|
||||
void equalsAndHashCodeWhenSameUnderlyingResource(@ResourcePath("test.resource") Path path) throws IOException {
|
||||
Path directory = path.getParent();
|
||||
assertThat(directory).isNotNull();
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[] { directory.toUri().toURL() },
|
||||
getClass().getClassLoader());
|
||||
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
+8
-2
@@ -21,12 +21,16 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.bootstrap.BootstrapContextClosedEvent;
|
||||
import org.springframework.boot.bootstrap.BootstrapRegistry.InstanceSupplier;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test classes used with
|
||||
* {@link ConfigDataEnvironmentPostProcessorBootstrapContextIntegrationTests} to show how
|
||||
@@ -50,6 +54,7 @@ class TestConfigDataBootstrap {
|
||||
context.getBootstrapContext()
|
||||
.registerIfAbsent(ResolverHelper.class, InstanceSupplier.from(() -> new ResolverHelper(location)));
|
||||
ResolverHelper helper = context.getBootstrapContext().get(ResolverHelper.class);
|
||||
assertThat(helper).isNotNull();
|
||||
return Collections.singletonList(new Resource(helper));
|
||||
}
|
||||
|
||||
@@ -63,6 +68,7 @@ class TestConfigDataBootstrap {
|
||||
.registerIfAbsent(LoaderHelper.class,
|
||||
(bootstrapContext) -> new LoaderHelper(location, () -> bootstrapContext.get(Binder.class)));
|
||||
LoaderHelper helper = context.getBootstrapContext().get(LoaderHelper.class);
|
||||
assertThat(helper).isNotNull();
|
||||
context.getBootstrapContext().addCloseListener(helper);
|
||||
return new ConfigData(
|
||||
Collections.singleton(new MapPropertySource("loaded", Collections.singletonMap("test", "test"))));
|
||||
@@ -118,11 +124,11 @@ class TestConfigDataBootstrap {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
String getBound() {
|
||||
@Nullable String getBound() {
|
||||
return this.binder.get().bind("myprop", String.class).orElse(null);
|
||||
}
|
||||
|
||||
String getProfileBound() {
|
||||
@Nullable String getProfileBound() {
|
||||
return this.binder.get().bind("myprofileprop", String.class).orElse(null);
|
||||
}
|
||||
|
||||
|
||||
+12
-10
@@ -20,17 +20,19 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
class TestConfigDataEnvironmentUpdateListener implements ConfigDataEnvironmentUpdateListener {
|
||||
|
||||
private final List<AddedPropertySource> addedPropertySources = new ArrayList<>();
|
||||
|
||||
private Profiles profiles;
|
||||
private @Nullable Profiles profiles;
|
||||
|
||||
@Override
|
||||
public void onPropertySourceAdded(PropertySource<?> propertySource, ConfigDataLocation location,
|
||||
ConfigDataResource resource) {
|
||||
public void onPropertySourceAdded(PropertySource<?> propertySource, @Nullable ConfigDataLocation location,
|
||||
@Nullable ConfigDataResource resource) {
|
||||
this.addedPropertySources.add(new AddedPropertySource(propertySource, location, resource));
|
||||
}
|
||||
|
||||
@@ -43,7 +45,7 @@ class TestConfigDataEnvironmentUpdateListener implements ConfigDataEnvironmentUp
|
||||
return Collections.unmodifiableList(this.addedPropertySources);
|
||||
}
|
||||
|
||||
Profiles getProfiles() {
|
||||
@Nullable Profiles getProfiles() {
|
||||
return this.profiles;
|
||||
}
|
||||
|
||||
@@ -51,12 +53,12 @@ class TestConfigDataEnvironmentUpdateListener implements ConfigDataEnvironmentUp
|
||||
|
||||
private final PropertySource<?> propertySource;
|
||||
|
||||
private final ConfigDataLocation location;
|
||||
private final @Nullable ConfigDataLocation location;
|
||||
|
||||
private final ConfigDataResource resource;
|
||||
private final @Nullable ConfigDataResource resource;
|
||||
|
||||
AddedPropertySource(PropertySource<?> propertySource, ConfigDataLocation location,
|
||||
ConfigDataResource resource) {
|
||||
AddedPropertySource(PropertySource<?> propertySource, @Nullable ConfigDataLocation location,
|
||||
@Nullable ConfigDataResource resource) {
|
||||
this.propertySource = propertySource;
|
||||
this.location = location;
|
||||
this.resource = resource;
|
||||
@@ -66,11 +68,11 @@ class TestConfigDataEnvironmentUpdateListener implements ConfigDataEnvironmentUp
|
||||
return this.propertySource;
|
||||
}
|
||||
|
||||
ConfigDataLocation getLocation() {
|
||||
@Nullable ConfigDataLocation getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
ConfigDataResource getResource() {
|
||||
@Nullable ConfigDataResource getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -32,6 +32,7 @@ import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
@@ -45,6 +46,8 @@ import static org.mockito.Mockito.mock;
|
||||
*/
|
||||
class EventPublishingRunListenerTests {
|
||||
|
||||
private static final String[] NO_ARGS = new String[0];
|
||||
|
||||
@Test
|
||||
void shouldPublishLifecycleEvents() {
|
||||
DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
|
||||
@@ -52,11 +55,11 @@ class EventPublishingRunListenerTests {
|
||||
TestApplicationListener applicationListener = new TestApplicationListener();
|
||||
SpringApplication application = mock(SpringApplication.class);
|
||||
given(application.getListeners()).willReturn(Collections.singleton(applicationListener));
|
||||
EventPublishingRunListener publishingListener = new EventPublishingRunListener(application, null);
|
||||
EventPublishingRunListener publishingListener = new EventPublishingRunListener(application, NO_ARGS);
|
||||
applicationListener.assertReceivedNoEvents();
|
||||
publishingListener.starting(bootstrapContext);
|
||||
applicationListener.assertReceivedEvent(ApplicationStartingEvent.class);
|
||||
publishingListener.environmentPrepared(bootstrapContext, null);
|
||||
publishingListener.environmentPrepared(bootstrapContext, new MockEnvironment());
|
||||
applicationListener.assertReceivedEvent(ApplicationEnvironmentPreparedEvent.class);
|
||||
publishingListener.contextPrepared(context);
|
||||
applicationListener.assertReceivedEvent(ApplicationContextInitializedEvent.class);
|
||||
@@ -78,7 +81,7 @@ class EventPublishingRunListenerTests {
|
||||
ApplicationListener<ApplicationStartingEvent> listener = (event) -> event.getSpringApplication()
|
||||
.addListeners(lateAddedApplicationListener);
|
||||
application.addListeners(listener);
|
||||
EventPublishingRunListener runListener = new EventPublishingRunListener(application, null);
|
||||
EventPublishingRunListener runListener = new EventPublishingRunListener(application, NO_ARGS);
|
||||
runListener.starting(bootstrapContext);
|
||||
runListener.environmentPrepared(bootstrapContext, environment);
|
||||
lateAddedApplicationListener.assertReceivedEvent(ApplicationEnvironmentPreparedEvent.class);
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package org.springframework.boot.context.logging;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -103,7 +104,7 @@ class LoggingApplicationListenerIntegrationTests {
|
||||
|
||||
private final LoggingSystem loggingSystem;
|
||||
|
||||
private final LogFile logFile;
|
||||
private final @Nullable LogFile logFile;
|
||||
|
||||
SampleService(LoggingSystem loggingSystem, ObjectProvider<LogFile> logFile) {
|
||||
this.loggingSystem = loggingSystem;
|
||||
|
||||
+82
-58
@@ -40,6 +40,7 @@ import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -59,6 +60,7 @@ import org.springframework.boot.logging.AbstractLoggingSystem;
|
||||
import org.springframework.boot.logging.LogFile;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.boot.logging.LoggerConfiguration;
|
||||
import org.springframework.boot.logging.LoggerGroup;
|
||||
import org.springframework.boot.logging.LoggerGroups;
|
||||
import org.springframework.boot.logging.LoggingInitializationContext;
|
||||
import org.springframework.boot.logging.LoggingSystem;
|
||||
@@ -118,6 +120,7 @@ class LoggingApplicationListenerTests {
|
||||
private final GenericApplicationContext context = new GenericApplicationContext();
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
public Path tempDir;
|
||||
|
||||
private File logFile;
|
||||
@@ -149,14 +152,12 @@ class LoggingApplicationListenerTests {
|
||||
System.clearProperty(LoggingSystem.class.getName());
|
||||
System.clearProperty(LoggingSystem.SYSTEM_PROPERTY);
|
||||
System.getProperties().keySet().retainAll(this.systemPropertyNames);
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
this.context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void baseConfigLocation() {
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.info("Hello world", new RuntimeException("Expected"));
|
||||
assertThat(this.output).contains("Hello world");
|
||||
assertThat(this.output).doesNotContain("???");
|
||||
@@ -168,7 +169,7 @@ class LoggingApplicationListenerTests {
|
||||
@WithNonDefaultXmlResource
|
||||
void overrideConfigLocation() {
|
||||
addPropertiesToEnvironment(this.context, "logging.config=classpath:nondefault.xml");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.info("Hello world");
|
||||
assertThat(this.output).contains("Hello world").doesNotContain("???").startsWith("null ").endsWith("BOOTBOOT");
|
||||
}
|
||||
@@ -179,7 +180,7 @@ class LoggingApplicationListenerTests {
|
||||
multicastEvent(this.listener,
|
||||
new ApplicationStartingEvent(this.bootstrapContext, new SpringApplication(), NO_ARGS));
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader()));
|
||||
.isThrownBy(() -> this.listener.initialize(this.context.getEnvironment(), getClassLoader()));
|
||||
assertThat(output).contains("Deliberately broken");
|
||||
}
|
||||
|
||||
@@ -187,7 +188,7 @@ class LoggingApplicationListenerTests {
|
||||
@WithNonDefaultXmlResource
|
||||
void trailingWhitespaceInLoggingConfigShouldBeTrimmed() {
|
||||
addPropertiesToEnvironment(this.context, "logging.config=classpath:nondefault.xml ");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.info("Hello world");
|
||||
assertThat(this.output).contains("Hello world").doesNotContain("???").startsWith("null ").endsWith("BOOTBOOT");
|
||||
}
|
||||
@@ -196,7 +197,7 @@ class LoggingApplicationListenerTests {
|
||||
void overrideConfigDoesNotExist() {
|
||||
addPropertiesToEnvironment(this.context, "logging.config=doesnotexist.xml");
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader()));
|
||||
.isThrownBy(() -> this.listener.initialize(this.context.getEnvironment(), getClassLoader()));
|
||||
assertThat(this.output)
|
||||
.contains("Logging system failed to initialize using configuration from 'doesnotexist.xml'")
|
||||
.doesNotContain("JoranException");
|
||||
@@ -206,7 +207,7 @@ class LoggingApplicationListenerTests {
|
||||
void azureDefaultLoggingConfigDoesNotCauseAFailure() {
|
||||
addPropertiesToEnvironment(this.context,
|
||||
"logging.config=-Djava.util.logging.config.file=\"d:\\home\\site\\wwwroot\\bin\\apache-tomcat-7.0.52\\conf\\logging.properties\"");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.info("Hello world");
|
||||
assertThat(this.output).contains("Hello world").doesNotContain("???");
|
||||
assertThat(new File(this.tempDir.toFile(), "/spring.log")).doesNotExist();
|
||||
@@ -215,7 +216,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void tomcatNopLoggingConfigDoesNotCauseAFailure() {
|
||||
addPropertiesToEnvironment(this.context, "LOGGING_CONFIG=-Dnop");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.info("Hello world");
|
||||
assertThat(this.output).contains("Hello world").doesNotContain("???");
|
||||
assertThat(new File(this.tempDir.toFile(), "/spring.log")).doesNotExist();
|
||||
@@ -225,7 +226,7 @@ class LoggingApplicationListenerTests {
|
||||
void overrideConfigBroken() {
|
||||
addPropertiesToEnvironment(this.context, "logging.config=classpath:logback-broken.xml");
|
||||
assertThatIllegalStateException().isThrownBy(() -> {
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertThat(this.output).contains(
|
||||
"Logging system failed to initialize using configuration from 'classpath:logback-broken.xml'");
|
||||
assertThat(this.output).contains("ConsolAppender");
|
||||
@@ -237,7 +238,7 @@ class LoggingApplicationListenerTests {
|
||||
void addLogFileProperty() {
|
||||
addPropertiesToEnvironment(this.context, "logging.config=classpath:nondefault.xml",
|
||||
"logging.file.name=" + this.logFile);
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
Log logger = LogFactory.getLog(LoggingApplicationListenerTests.class);
|
||||
String existingOutput = this.output.toString();
|
||||
logger.info("Hello world");
|
||||
@@ -249,7 +250,7 @@ class LoggingApplicationListenerTests {
|
||||
void addLogFilePropertyWithDefault() {
|
||||
assertThat(this.logFile).doesNotExist();
|
||||
addPropertiesToEnvironment(this.context, "logging.file.name=" + this.logFile);
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
Log logger = LogFactory.getLog(LoggingApplicationListenerTests.class);
|
||||
logger.info("Hello world");
|
||||
assertThat(this.logFile).isFile();
|
||||
@@ -260,7 +261,7 @@ class LoggingApplicationListenerTests {
|
||||
void addLogPathProperty() {
|
||||
addPropertiesToEnvironment(this.context, "logging.config=classpath:nondefault.xml",
|
||||
"logging.file.path=" + this.tempDir);
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
Log logger = LogFactory.getLog(LoggingApplicationListenerTests.class);
|
||||
String existingOutput = this.output.toString();
|
||||
logger.info("Hello world");
|
||||
@@ -271,7 +272,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void parseDebugArg() {
|
||||
addPropertiesToEnvironment(this.context, "debug");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.trace("testattrace");
|
||||
assertThat(this.output).contains("testatdebug");
|
||||
@@ -281,19 +282,22 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void parseDebugArgExpandGroups() {
|
||||
addPropertiesToEnvironment(this.context, "debug");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.loggerContext.getLogger("org.springframework.boot.actuate.endpoint.web").debug("testdebugwebgroup");
|
||||
this.loggerContext.getLogger("org.hibernate.SQL").debug("testdebugsqlgroup");
|
||||
assertThat(this.output).contains("testdebugwebgroup");
|
||||
assertThat(this.output).contains("testdebugsqlgroup");
|
||||
LoggerGroups loggerGroups = (LoggerGroups) ReflectionTestUtils.getField(this.listener, "loggerGroups");
|
||||
assertThat(loggerGroups.get("web").getConfiguredLevel()).isEqualTo(LogLevel.DEBUG);
|
||||
assertThat(loggerGroups).isNotNull();
|
||||
LoggerGroup loggerGroup = loggerGroups.get("web");
|
||||
assertThat(loggerGroup).isNotNull();
|
||||
assertThat(loggerGroup.getConfiguredLevel()).isEqualTo(LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseTraceArg() {
|
||||
addPropertiesToEnvironment(this.context, "trace");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.trace("testattrace");
|
||||
assertThat(this.output).contains("testatdebug");
|
||||
@@ -312,7 +316,7 @@ class LoggingApplicationListenerTests {
|
||||
|
||||
private void disableDebugTraceArg(String... environment) {
|
||||
addPropertiesToEnvironment(this.context, environment);
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.trace("testattrace");
|
||||
assertThat(this.output).doesNotContain("testatdebug");
|
||||
@@ -322,7 +326,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void parseLevels() {
|
||||
addPropertiesToEnvironment(this.context, "logging.level.org.springframework.boot=TRACE");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.trace("testattrace");
|
||||
assertThat(this.output).contains("testatdebug");
|
||||
@@ -332,7 +336,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void parseLevelsCaseInsensitive() {
|
||||
addPropertiesToEnvironment(this.context, "logging.level.org.springframework.boot=TrAcE");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.trace("testattrace");
|
||||
assertThat(this.output).contains("testatdebug");
|
||||
@@ -342,7 +346,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void parseLevelsTrimsWhitespace() {
|
||||
addPropertiesToEnvironment(this.context, "logging.level.org.springframework.boot= trace ");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.trace("testattrace");
|
||||
assertThat(this.output).contains("testatdebug");
|
||||
@@ -352,7 +356,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void parseLevelsWithPlaceholder() {
|
||||
addPropertiesToEnvironment(this.context, "foo=TRACE", "logging.level.org.springframework.boot=${foo}");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.trace("testattrace");
|
||||
assertThat(this.output).contains("testatdebug");
|
||||
@@ -364,13 +368,13 @@ class LoggingApplicationListenerTests {
|
||||
this.logger.setLevel(Level.INFO);
|
||||
addPropertiesToEnvironment(this.context, "logging.level.org.springframework.boot=GARBAGE");
|
||||
assertThatExceptionOfType(BindException.class)
|
||||
.isThrownBy(() -> this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader()));
|
||||
.isThrownBy(() -> this.listener.initialize(this.context.getEnvironment(), getClassLoader()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseLevelsNone() {
|
||||
addPropertiesToEnvironment(this.context, "logging.level.org.springframework.boot=OFF");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.error("testaterror");
|
||||
assertThat(this.output).doesNotContain("testatdebug").doesNotContain("testaterror");
|
||||
@@ -379,7 +383,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void parseLevelsMapsFalseToOff() {
|
||||
addPropertiesToEnvironment(this.context, "logging.level.org.springframework.boot=false");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
this.logger.error("testaterror");
|
||||
assertThat(this.output).doesNotContain("testatdebug").doesNotContain("testaterror");
|
||||
@@ -389,7 +393,7 @@ class LoggingApplicationListenerTests {
|
||||
void parseArgsDisabled() {
|
||||
this.listener.setParseArgs(false);
|
||||
addPropertiesToEnvironment(this.context, "debug");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
assertThat(this.output).doesNotContain("testatdebug");
|
||||
}
|
||||
@@ -400,7 +404,7 @@ class LoggingApplicationListenerTests {
|
||||
this.listener.setParseArgs(false);
|
||||
multicastEvent(new ApplicationStartingEvent(this.bootstrapContext, this.springApplication,
|
||||
new String[] { "--debug" }));
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
assertThat(this.output).doesNotContain("testatdebug");
|
||||
}
|
||||
@@ -414,7 +418,7 @@ class LoggingApplicationListenerTests {
|
||||
|
||||
@Test
|
||||
void defaultExceptionConversionWord() {
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.info("Hello world", new RuntimeException("Wrapper", new RuntimeException("Expected")));
|
||||
assertThat(this.output).contains("Hello world");
|
||||
assertThat(this.output).doesNotContain("Wrapped by: java.lang.RuntimeException: Wrapper");
|
||||
@@ -423,7 +427,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void overrideExceptionConversionWord() {
|
||||
addPropertiesToEnvironment(this.context, "logging.exceptionConversionWord=%rEx");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.info("Hello world", new RuntimeException("Wrapper", new RuntimeException("Expected")));
|
||||
assertThat(this.output).contains("Hello world");
|
||||
assertThat(this.output).contains("Wrapped by: java.lang.RuntimeException: Wrapper");
|
||||
@@ -434,13 +438,16 @@ class LoggingApplicationListenerTests {
|
||||
TestLoggingApplicationListener listener = new TestLoggingApplicationListener();
|
||||
Object registered = ReflectionTestUtils.getField(listener, TestLoggingApplicationListener.class,
|
||||
"shutdownHookRegistered");
|
||||
assertThat(registered).isNotNull();
|
||||
((AtomicBoolean) registered).set(false);
|
||||
System.setProperty(LoggingSystem.class.getName(), TestShutdownHandlerLoggingSystem.class.getName());
|
||||
multicastEvent(listener, new ApplicationStartingEvent(this.bootstrapContext, new SpringApplication(), NO_ARGS));
|
||||
listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertThat(listener.shutdownHook).isNotNull();
|
||||
listener.shutdownHook.run();
|
||||
assertThat(TestShutdownHandlerLoggingSystem.shutdownLatch.await(30, TimeUnit.SECONDS)).isTrue();
|
||||
CountDownLatch shutdownLatch = TestShutdownHandlerLoggingSystem.shutdownLatch;
|
||||
assertThat(shutdownLatch).isNotNull();
|
||||
assertThat(shutdownLatch.await(30, TimeUnit.SECONDS)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -448,11 +455,12 @@ class LoggingApplicationListenerTests {
|
||||
TestLoggingApplicationListener listener = new TestLoggingApplicationListener();
|
||||
Object registered = ReflectionTestUtils.getField(listener, TestLoggingApplicationListener.class,
|
||||
"shutdownHookRegistered");
|
||||
assertThat(registered).isNotNull();
|
||||
((AtomicBoolean) registered).set(false);
|
||||
System.setProperty(LoggingSystem.class.getName(), TestShutdownHandlerLoggingSystem.class.getName());
|
||||
addPropertiesToEnvironment(this.context, "logging.register_shutdown_hook=false");
|
||||
multicastEvent(listener, new ApplicationStartingEvent(this.bootstrapContext, new SpringApplication(), NO_ARGS));
|
||||
listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertThat(listener.shutdownHook).isNull();
|
||||
}
|
||||
|
||||
@@ -462,6 +470,7 @@ class LoggingApplicationListenerTests {
|
||||
multicastEvent(new ApplicationStartingEvent(this.bootstrapContext, this.springApplication, new String[0]));
|
||||
TestCleanupLoggingSystem loggingSystem = (TestCleanupLoggingSystem) ReflectionTestUtils.getField(this.listener,
|
||||
"loggingSystem");
|
||||
assertThat(loggingSystem).isNotNull();
|
||||
assertThat(loggingSystem.cleanedUp).isFalse();
|
||||
multicastEvent(new ContextClosedEvent(this.context));
|
||||
assertThat(loggingSystem.cleanedUp).isTrue();
|
||||
@@ -473,6 +482,7 @@ class LoggingApplicationListenerTests {
|
||||
multicastEvent(new ApplicationStartingEvent(this.bootstrapContext, this.springApplication, new String[0]));
|
||||
TestCleanupLoggingSystem loggingSystem = (TestCleanupLoggingSystem) ReflectionTestUtils.getField(this.listener,
|
||||
"loggingSystem");
|
||||
assertThat(loggingSystem).isNotNull();
|
||||
assertThat(loggingSystem.cleanedUp).isFalse();
|
||||
GenericApplicationContext childContext = new GenericApplicationContext();
|
||||
childContext.setParent(this.context);
|
||||
@@ -489,7 +499,7 @@ class LoggingApplicationListenerTests {
|
||||
"logging.file.name=" + this.logFile, "logging.file.path=path", "logging.pattern.console=console",
|
||||
"logging.pattern.file=file", "logging.pattern.level=level", "logging.pattern.correlation=correlation",
|
||||
"logging.pattern.rolling-file-name=my.log.%d{yyyyMMdd}.%i.gz");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_PATTERN)).isEqualTo("console");
|
||||
assertThat(getSystemProperty(LoggingSystemProperty.FILE_PATTERN)).isEqualTo("file");
|
||||
assertThat(getSystemProperty(LoggingSystemProperty.EXCEPTION_CONVERSION_WORD)).isEqualTo("conversion");
|
||||
@@ -503,14 +513,14 @@ class LoggingApplicationListenerTests {
|
||||
void environmentPropertiesIgnoreUnresolvablePlaceholders() {
|
||||
// gh-7719
|
||||
addPropertiesToEnvironment(this.context, "logging.pattern.console=console ${doesnotexist}");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_PATTERN)).isEqualTo("console ${doesnotexist}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void environmentPropertiesResolvePlaceholders() {
|
||||
addPropertiesToEnvironment(this.context, "logging.pattern.console=console ${pid}");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertThat(getSystemProperty(LoggingSystemProperty.CONSOLE_PATTERN))
|
||||
.isEqualTo(this.context.getEnvironment().getProperty("logging.pattern.console"));
|
||||
}
|
||||
@@ -518,7 +528,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void logFilePropertiesCanReferenceSystemProperties() {
|
||||
addPropertiesToEnvironment(this.context, "logging.file.name=" + this.tempDir + "${PID}.log");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertThat(getSystemProperty(LoggingSystemProperty.LOG_FILE))
|
||||
.isEqualTo(this.tempDir + new ApplicationPid().toString() + ".log");
|
||||
}
|
||||
@@ -529,6 +539,7 @@ class LoggingApplicationListenerTests {
|
||||
multicastEvent(new ApplicationStartingEvent(this.bootstrapContext, this.springApplication, new String[0]));
|
||||
TestCleanupLoggingSystem loggingSystem = (TestCleanupLoggingSystem) ReflectionTestUtils.getField(this.listener,
|
||||
"loggingSystem");
|
||||
assertThat(loggingSystem).isNotNull();
|
||||
assertThat(loggingSystem.cleanedUp).isFalse();
|
||||
multicastEvent(new ApplicationFailedEvent(this.springApplication, new String[0],
|
||||
new GenericApplicationContext(), new Exception()));
|
||||
@@ -547,6 +558,7 @@ class LoggingApplicationListenerTests {
|
||||
.get();
|
||||
TestCleanupLoggingSystem loggingSystem = (TestCleanupLoggingSystem) ReflectionTestUtils.getField(listener,
|
||||
"loggingSystem");
|
||||
assertThat(loggingSystem).isNotNull();
|
||||
assertThat(loggingSystem.cleanedUp).isFalse();
|
||||
WebServerStyleLifecycle lifecycle = context.getBean(WebServerStyleLifecycle.class);
|
||||
AtomicBoolean called = new AtomicBoolean();
|
||||
@@ -567,7 +579,7 @@ class LoggingApplicationListenerTests {
|
||||
propertySources
|
||||
.addFirst(new MapPropertySource("test1", Collections.singletonMap("logging.level.ROOT", "DEBUG")));
|
||||
propertySources.addLast(new MapPropertySource("test2", Collections.singletonMap("logging.level.root", "WARN")));
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
this.logger.debug("testatdebug");
|
||||
assertThat(this.output).contains("testatdebug");
|
||||
}
|
||||
@@ -575,7 +587,7 @@ class LoggingApplicationListenerTests {
|
||||
@Test
|
||||
void loggingGroupsDefaultsAreApplied() {
|
||||
addPropertiesToEnvironment(this.context, "logging.level.web=TRACE");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertTraceEnabled("org.springframework.core", false);
|
||||
assertTraceEnabled("org.springframework.core.codec", true);
|
||||
assertTraceEnabled("org.springframework.http", true);
|
||||
@@ -588,12 +600,18 @@ class LoggingApplicationListenerTests {
|
||||
void loggingGroupsCanBeDefined() {
|
||||
addPropertiesToEnvironment(this.context, "logging.group.foo=com.foo.bar,com.foo.baz",
|
||||
"logging.level.foo=TRACE");
|
||||
this.listener.initialize(this.context.getEnvironment(), this.context.getClassLoader());
|
||||
this.listener.initialize(this.context.getEnvironment(), getClassLoader());
|
||||
assertTraceEnabled("com.foo", false);
|
||||
assertTraceEnabled("com.foo.bar", true);
|
||||
assertTraceEnabled("com.foo.baz", true);
|
||||
}
|
||||
|
||||
private ClassLoader getClassLoader() {
|
||||
ClassLoader classLoader = this.context.getClassLoader();
|
||||
assertThat(classLoader).isNotNull();
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
private String getSystemProperty(LoggingSystemProperty property) {
|
||||
return System.getProperty(property.getEnvironmentVariableName());
|
||||
}
|
||||
@@ -636,7 +654,7 @@ class LoggingApplicationListenerTests {
|
||||
|
||||
static class TestShutdownHandlerLoggingSystem extends AbstractLoggingSystem {
|
||||
|
||||
private static CountDownLatch shutdownLatch;
|
||||
private static @Nullable CountDownLatch shutdownLatch;
|
||||
|
||||
TestShutdownHandlerLoggingSystem(ClassLoader classLoader) {
|
||||
super(classLoader);
|
||||
@@ -649,38 +667,42 @@ class LoggingApplicationListenerTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) {
|
||||
protected void loadDefaults(LoggingInitializationContext initializationContext, @Nullable LogFile logFile) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadConfiguration(LoggingInitializationContext initializationContext, String location,
|
||||
LogFile logFile) {
|
||||
@Nullable LogFile logFile) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(String loggerName, LogLevel level) {
|
||||
public void setLogLevel(@Nullable String loggerName, @Nullable LogLevel level) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoggerConfiguration> getLoggerConfigurations() {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoggerConfiguration getLoggerConfiguration(String loggerName) {
|
||||
public @Nullable LoggerConfiguration getLoggerConfiguration(String loggerName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Runnable getShutdownHandler() {
|
||||
return () -> TestShutdownHandlerLoggingSystem.shutdownLatch.countDown();
|
||||
return () -> {
|
||||
CountDownLatch shutdownLatch = TestShutdownHandlerLoggingSystem.shutdownLatch;
|
||||
assertThat(shutdownLatch).isNotNull();
|
||||
shutdownLatch.countDown();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestLoggingApplicationListener extends LoggingApplicationListener {
|
||||
|
||||
private Runnable shutdownHook;
|
||||
private @Nullable Runnable shutdownHook;
|
||||
|
||||
@Override
|
||||
void registerShutdownHook(Runnable shutdownHook) {
|
||||
@@ -701,16 +723,16 @@ class LoggingApplicationListenerTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(String loggerName, LogLevel level) {
|
||||
public void setLogLevel(@Nullable String loggerName, @Nullable LogLevel level) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoggerConfiguration> getLoggerConfigurations() {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoggerConfiguration getLoggerConfiguration(String loggerName) {
|
||||
public @Nullable LoggerConfiguration getLoggerConfiguration(String loggerName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -732,22 +754,22 @@ class LoggingApplicationListenerTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(LoggingInitializationContext initializationContext, String configLocation,
|
||||
LogFile logFile) {
|
||||
public void initialize(LoggingInitializationContext initializationContext, @Nullable String configLocation,
|
||||
@Nullable LogFile logFile) {
|
||||
throw new Error("Deliberately broken");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(String loggerName, LogLevel level) {
|
||||
public void setLogLevel(@Nullable String loggerName, @Nullable LogLevel level) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LoggerConfiguration> getLoggerConfigurations() {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoggerConfiguration getLoggerConfiguration(String loggerName) {
|
||||
public @Nullable LoggerConfiguration getLoggerConfiguration(String loggerName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -763,7 +785,7 @@ class LoggingApplicationListenerTests {
|
||||
|
||||
private volatile boolean running;
|
||||
|
||||
Runnable onStop;
|
||||
@Nullable Runnable onStop;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
@@ -773,7 +795,9 @@ class LoggingApplicationListenerTests {
|
||||
@Override
|
||||
public void stop() {
|
||||
this.running = false;
|
||||
this.onStop.run();
|
||||
if (this.onStop != null) {
|
||||
this.onStop.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+18
-9
@@ -21,6 +21,7 @@ import java.util.stream.Stream;
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.AssertProvider;
|
||||
import org.assertj.core.error.BasicErrorMessageFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.TypeHint;
|
||||
@@ -28,6 +29,7 @@ import org.springframework.aot.hint.TypeReference;
|
||||
import org.springframework.aot.test.generate.TestGenerationContext;
|
||||
import org.springframework.beans.factory.aot.AotServices;
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationCode;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBeanFactoryInitializationAotProcessor.ConfigurationPropertiesReflectionHintsContribution;
|
||||
@@ -38,6 +40,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ConfigurationPropertiesBeanFactoryInitializationAotProcessor}.
|
||||
@@ -67,6 +70,7 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
beanFactory.registerSingleton("test", new SampleProperties());
|
||||
ConfigurationPropertiesReflectionHintsContribution contribution = process(beanFactory);
|
||||
assertThat(contribution).isNotNull();
|
||||
assertThat(singleBindable(contribution)).hasBindMethod(BindMethod.JAVA_BEAN).hasType(SampleProperties.class);
|
||||
assertThat(typeHints(contribution).map(TypeHint::getType))
|
||||
.containsExactly(TypeReference.of(SampleProperties.class));
|
||||
@@ -75,6 +79,7 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
|
||||
@Test
|
||||
void javaBeanConfigurationPropertiesBindAsJavaBean() {
|
||||
ConfigurationPropertiesReflectionHintsContribution contribution = process(EnableJavaBeanProperties.class);
|
||||
assertThat(contribution).isNotNull();
|
||||
assertThat(singleBindable(contribution)).hasBindMethod(BindMethod.JAVA_BEAN).hasType(JavaBeanProperties.class);
|
||||
assertThat(typeHints(contribution).map(TypeHint::getType))
|
||||
.containsExactly(TypeReference.of(JavaBeanProperties.class));
|
||||
@@ -84,6 +89,7 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
|
||||
void constructorBindingConfigurationPropertiesBindAsValueObject() {
|
||||
ConfigurationPropertiesReflectionHintsContribution contribution = process(
|
||||
EnableConstructorBindingProperties.class);
|
||||
assertThat(contribution).isNotNull();
|
||||
assertThat(singleBindable(contribution)).hasBindMethod(BindMethod.VALUE_OBJECT)
|
||||
.hasType(ConstructorBindingProperties.class);
|
||||
assertThat(typeHints(contribution).map(TypeHint::getType))
|
||||
@@ -94,6 +100,7 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
|
||||
void possibleConstructorBindingPropertiesDefinedThroughBeanMethodBindAsJavaBean() {
|
||||
ConfigurationPropertiesReflectionHintsContribution contribution = process(
|
||||
PossibleConstructorBindingPropertiesBeanMethodConfiguration.class);
|
||||
assertThat(contribution).isNotNull();
|
||||
assertThat(singleBindable(contribution)).hasBindMethod(BindMethod.JAVA_BEAN)
|
||||
.hasType(PossibleConstructorBindingProperties.class);
|
||||
assertThat(typeHints(contribution).map(TypeHint::getType))
|
||||
@@ -104,6 +111,7 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
|
||||
void possibleConstructorBindingPropertiesDefinedThroughEnabledAnnotationBindAsValueObject() {
|
||||
ConfigurationPropertiesReflectionHintsContribution contribution = process(
|
||||
EnablePossibleConstructorBindingProperties.class);
|
||||
assertThat(contribution).isNotNull();
|
||||
assertThat(singleBindable(contribution)).hasBindMethod(BindMethod.VALUE_OBJECT)
|
||||
.hasType(PossibleConstructorBindingProperties.class);
|
||||
assertThat(typeHints(contribution).map(TypeHint::getType))
|
||||
@@ -112,17 +120,18 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
private Stream<TypeHint> typeHints(ConfigurationPropertiesReflectionHintsContribution contribution) {
|
||||
TestGenerationContext generationContext = new TestGenerationContext();
|
||||
contribution.applyTo(generationContext, null);
|
||||
contribution.applyTo(generationContext, mock(BeanFactoryInitializationCode.class));
|
||||
return generationContext.getRuntimeHints().reflection().typeHints();
|
||||
}
|
||||
|
||||
private ConfigurationPropertiesReflectionHintsContribution process(Class<?> config) {
|
||||
private @Nullable ConfigurationPropertiesReflectionHintsContribution process(Class<?> config) {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(config)) {
|
||||
return process(context.getBeanFactory());
|
||||
}
|
||||
}
|
||||
|
||||
private ConfigurationPropertiesReflectionHintsContribution process(ConfigurableListableBeanFactory beanFactory) {
|
||||
private @Nullable ConfigurationPropertiesReflectionHintsContribution process(
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
return this.processor.processAheadOfTime(beanFactory);
|
||||
}
|
||||
|
||||
@@ -144,13 +153,13 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
|
||||
@ConfigurationProperties("java-bean")
|
||||
static class JavaBeanProperties {
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(String value) {
|
||||
void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -195,17 +204,17 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
|
||||
@ConfigurationProperties("possible-constructor-binding")
|
||||
static class PossibleConstructorBindingProperties {
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
PossibleConstructorBindingProperties(String arg) {
|
||||
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(String value) {
|
||||
void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -19,6 +19,7 @@ package org.springframework.boot.context.properties;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.test.generate.TestGenerationContext;
|
||||
@@ -81,7 +82,7 @@ class ConfigurationPropertiesBeanRegistrationAotProcessorTests {
|
||||
assertThat(contribution).isNotNull();
|
||||
}
|
||||
|
||||
private BeanRegistrationAotContribution process(Class<?> type) {
|
||||
private @Nullable BeanRegistrationAotContribution process(Class<?> type) {
|
||||
ConfigurationPropertiesBeanRegistrar beanRegistrar = new ConfigurationPropertiesBeanRegistrar(this.beanFactory);
|
||||
beanRegistrar.register(type);
|
||||
RegisteredBean registeredBean = RegisteredBean.of(this.beanFactory,
|
||||
@@ -177,13 +178,13 @@ class ConfigurationPropertiesBeanRegistrationAotProcessorTests {
|
||||
@ConfigurationProperties("test")
|
||||
public static class JavaBeanSampleBean {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
public String getName() {
|
||||
public @Nullable String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
public void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
+21
-6
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.ClassFileVersion;
|
||||
import net.bytebuddy.description.annotation.AnnotationDescription;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.function.ThrowingConsumer;
|
||||
|
||||
@@ -60,18 +61,21 @@ class ConfigurationPropertiesBeanTests {
|
||||
Map<String, ConfigurationPropertiesBean> all = ConfigurationPropertiesBean.getAll(context);
|
||||
assertThat(all).containsOnlyKeys("annotatedComponent", "annotatedBean", ValueObject.class.getName());
|
||||
ConfigurationPropertiesBean component = all.get("annotatedComponent");
|
||||
assertThat(component).isNotNull();
|
||||
assertThat(component.getName()).isEqualTo("annotatedComponent");
|
||||
assertThat(component.getInstance()).isInstanceOf(AnnotatedComponent.class);
|
||||
assertThat(component.getAnnotation()).isNotNull();
|
||||
assertThat(component.getType()).isEqualTo(AnnotatedComponent.class);
|
||||
assertThat(component.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ConfigurationPropertiesBean bean = all.get("annotatedBean");
|
||||
assertThat(bean).isNotNull();
|
||||
assertThat(bean.getName()).isEqualTo("annotatedBean");
|
||||
assertThat(bean.getInstance()).isInstanceOf(AnnotatedBean.class);
|
||||
assertThat(bean.getType()).isEqualTo(AnnotatedBean.class);
|
||||
assertThat(bean.getAnnotation()).isNotNull();
|
||||
assertThat(bean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ConfigurationPropertiesBean valueObject = all.get(ValueObject.class.getName());
|
||||
assertThat(valueObject).isNotNull();
|
||||
assertThat(valueObject.getName()).isEqualTo(ValueObject.class.getName());
|
||||
assertThat(valueObject.getInstance()).isInstanceOf(ValueObject.class);
|
||||
assertThat(valueObject.getType()).isEqualTo(ValueObject.class);
|
||||
@@ -157,6 +161,7 @@ class ConfigurationPropertiesBeanTests {
|
||||
@Test
|
||||
void getWhenHasFactoryMethodBindsUsingMethodReturnType() throws Throwable {
|
||||
get(NonAnnotatedGenericBeanConfiguration.class, "nonAnnotatedGenericBean", (propertiesBean) -> {
|
||||
assertThat(propertiesBean).isNotNull();
|
||||
assertThat(propertiesBean.getType()).isEqualTo(NonAnnotatedGenericBean.class);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ResolvableType type = propertiesBean.asBindTarget().getType();
|
||||
@@ -168,6 +173,7 @@ class ConfigurationPropertiesBeanTests {
|
||||
@Test
|
||||
void getWhenHasFactoryMethodWithoutAnnotationBindsUsingMethodType() throws Throwable {
|
||||
get(AnnotatedGenericBeanConfiguration.class, "annotatedGenericBean", (propertiesBean) -> {
|
||||
assertThat(propertiesBean).isNotNull();
|
||||
assertThat(propertiesBean.getType()).isEqualTo(AnnotatedGenericBean.class);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ResolvableType type = propertiesBean.asBindTarget().getType();
|
||||
@@ -179,6 +185,7 @@ class ConfigurationPropertiesBeanTests {
|
||||
@Test
|
||||
void getWhenHasNoFactoryMethodBindsUsingObjectType() throws Throwable {
|
||||
get(AnnotatedGenericComponent.class, "annotatedGenericComponent", (propertiesBean) -> {
|
||||
assertThat(propertiesBean).isNotNull();
|
||||
assertThat(propertiesBean.getType()).isEqualTo(AnnotatedGenericComponent.class);
|
||||
assertThat(propertiesBean.asBindTarget().getBindMethod()).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
ResolvableType type = propertiesBean.asBindTarget().getType();
|
||||
@@ -189,14 +196,18 @@ class ConfigurationPropertiesBeanTests {
|
||||
|
||||
@Test
|
||||
void getWhenHasFactoryMethodAndBeanAnnotationFavorsFactoryMethod() throws Throwable {
|
||||
get(AnnotatedBeanConfiguration.class, "annotatedBean",
|
||||
(propertiesBean) -> assertThat(propertiesBean.getAnnotation().prefix()).isEqualTo("factory"));
|
||||
get(AnnotatedBeanConfiguration.class, "annotatedBean", (propertiesBean) -> {
|
||||
assertThat(propertiesBean).isNotNull();
|
||||
assertThat(propertiesBean.getAnnotation().prefix()).isEqualTo("factory");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenHasValidatedBeanBindsWithBeanAnnotation() throws Throwable {
|
||||
get(ValidatedBeanConfiguration.class, "validatedBean", (propertiesBean) -> {
|
||||
assertThat(propertiesBean).isNotNull();
|
||||
Validated validated = propertiesBean.asBindTarget().getAnnotation(Validated.class);
|
||||
assertThat(validated).isNotNull();
|
||||
assertThat(validated.value()).containsExactly(BeanGroup.class);
|
||||
});
|
||||
}
|
||||
@@ -204,7 +215,9 @@ class ConfigurationPropertiesBeanTests {
|
||||
@Test
|
||||
void getWhenHasValidatedFactoryMethodBindsWithFactoryMethodAnnotation() throws Throwable {
|
||||
get(ValidatedMethodConfiguration.class, "annotatedBean", (propertiesBean) -> {
|
||||
assertThat(propertiesBean).isNotNull();
|
||||
Validated validated = propertiesBean.asBindTarget().getAnnotation(Validated.class);
|
||||
assertThat(validated).isNotNull();
|
||||
assertThat(validated.value()).containsExactly(FactoryMethodGroup.class);
|
||||
});
|
||||
}
|
||||
@@ -212,7 +225,9 @@ class ConfigurationPropertiesBeanTests {
|
||||
@Test
|
||||
void getWhenHasValidatedBeanAndFactoryMethodBindsWithFactoryMethodAnnotation() throws Throwable {
|
||||
get(ValidatedMethodAndBeanConfiguration.class, "validatedBean", (propertiesBean) -> {
|
||||
assertThat(propertiesBean).isNotNull();
|
||||
Validated validated = propertiesBean.asBindTarget().getAnnotation(Validated.class);
|
||||
assertThat(validated).isNotNull();
|
||||
assertThat(validated.value()).containsExactly(FactoryMethodGroup.class);
|
||||
});
|
||||
}
|
||||
@@ -336,18 +351,18 @@ class ConfigurationPropertiesBeanTests {
|
||||
assertThat(bindType).isEqualTo(BindMethod.JAVA_BEAN);
|
||||
}
|
||||
|
||||
private void get(Class<?> configuration, String beanName, ThrowingConsumer<ConfigurationPropertiesBean> consumer)
|
||||
throws Throwable {
|
||||
private void get(Class<?> configuration, String beanName,
|
||||
ThrowingConsumer<@Nullable ConfigurationPropertiesBean> consumer) throws Throwable {
|
||||
get(configuration, beanName, true, consumer);
|
||||
}
|
||||
|
||||
private void getWithoutBeanMetadataCaching(Class<?> configuration, String beanName,
|
||||
ThrowingConsumer<ConfigurationPropertiesBean> consumer) throws Throwable {
|
||||
ThrowingConsumer<@Nullable ConfigurationPropertiesBean> consumer) throws Throwable {
|
||||
get(configuration, beanName, false, consumer);
|
||||
}
|
||||
|
||||
private void get(Class<?> configuration, String beanName, boolean cacheBeanMetadata,
|
||||
ThrowingConsumer<ConfigurationPropertiesBean> consumer) throws Throwable {
|
||||
ThrowingConsumer<@Nullable ConfigurationPropertiesBean> consumer) throws Throwable {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.getBeanFactory().setCacheBeanMetadata(cacheBeanMetadata);
|
||||
context.register(configuration);
|
||||
|
||||
+1
@@ -36,6 +36,7 @@ class ConfigurationPropertiesBindExceptionTests {
|
||||
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Example.class);
|
||||
ConfigurationPropertiesBean bean = ConfigurationPropertiesBean.get(applicationContext,
|
||||
applicationContext.getBean(Example.class), "example");
|
||||
assertThat(bean).isNotNull();
|
||||
ConfigurationPropertiesBindException exception = new ConfigurationPropertiesBindException(bean,
|
||||
new IllegalStateException());
|
||||
assertThat(exception.getMessage()).isEqualTo("Error creating bean with name 'example': "
|
||||
|
||||
+11
-5
@@ -20,6 +20,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -57,9 +58,11 @@ class ConfigurationPropertiesBindHandlerAdvisorTests {
|
||||
"foo.bar.bindings.output.destination=d2");
|
||||
BindingServiceProperties properties = this.context.getBean(BindingServiceProperties.class);
|
||||
BindingProperties input = properties.getBindings().get("input");
|
||||
assertThat(input).isNotNull();
|
||||
assertThat(input.getDestination()).isEqualTo("d1");
|
||||
assertThat(input.getContentType()).isEqualTo("text/xml");
|
||||
BindingProperties output = properties.getBindings().get("output");
|
||||
assertThat(output).isNotNull();
|
||||
assertThat(output.getDestination()).isEqualTo("d2");
|
||||
assertThat(output.getContentType()).isEqualTo("application/json");
|
||||
}
|
||||
@@ -71,9 +74,11 @@ class ConfigurationPropertiesBindHandlerAdvisorTests {
|
||||
"foo.bar.bindings.output.destination=d2");
|
||||
BindingServiceProperties properties = this.context.getBean(BindingServiceProperties.class);
|
||||
BindingProperties input = properties.getBindings().get("input");
|
||||
assertThat(input).isNotNull();
|
||||
assertThat(input.getDestination()).isEqualTo("d1");
|
||||
assertThat(input.getContentType()).isEqualTo("text/xml");
|
||||
BindingProperties output = properties.getBindings().get("output");
|
||||
assertThat(output).isNotNull();
|
||||
assertThat(output.getDestination()).isEqualTo("d2");
|
||||
assertThat(output.getContentType()).isEqualTo("text/plain");
|
||||
}
|
||||
@@ -124,7 +129,8 @@ class ConfigurationPropertiesBindHandlerAdvisorTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Bindable<T> onStart(ConfigurationPropertyName name, Bindable<T> target, BindContext context) {
|
||||
public <T> @Nullable Bindable<T> onStart(ConfigurationPropertyName name, Bindable<T> target,
|
||||
BindContext context) {
|
||||
ConfigurationPropertyName defaultName = getDefaultName(name);
|
||||
if (defaultName != null) {
|
||||
BindResult<T> result = context.getBinder().bind(defaultName, target);
|
||||
@@ -135,7 +141,7 @@ class ConfigurationPropertiesBindHandlerAdvisorTests {
|
||||
return super.onStart(name, target, context);
|
||||
}
|
||||
|
||||
private ConfigurationPropertyName getDefaultName(ConfigurationPropertyName name) {
|
||||
private @Nullable ConfigurationPropertyName getDefaultName(ConfigurationPropertyName name) {
|
||||
for (Map.Entry<ConfigurationPropertyName, ConfigurationPropertyName> mapping : this.mappings.entrySet()) {
|
||||
ConfigurationPropertyName from = mapping.getKey();
|
||||
ConfigurationPropertyName to = mapping.getValue();
|
||||
@@ -161,15 +167,15 @@ class ConfigurationPropertiesBindHandlerAdvisorTests {
|
||||
|
||||
static class BindingProperties {
|
||||
|
||||
private String destination;
|
||||
private @Nullable String destination;
|
||||
|
||||
private String contentType = "application/json";
|
||||
|
||||
String getDestination() {
|
||||
@Nullable String getDestination() {
|
||||
return this.destination;
|
||||
}
|
||||
|
||||
void setDestination(String destination) {
|
||||
void setDestination(@Nullable String destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ package org.springframework.boot.context.properties;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -151,7 +152,7 @@ class ConfigurationPropertiesScanTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
return (this == o);
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -37,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class ConfigurationPropertiesTestBeanTests {
|
||||
|
||||
@TestBean
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ImmutableProperties properties;
|
||||
|
||||
@Autowired
|
||||
|
||||
+202
-156
@@ -38,6 +38,7 @@ import jakarta.annotation.PostConstruct;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -56,6 +57,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesTests.JavaBeanNestedConstructorBindingProperties.Nested;
|
||||
import org.springframework.boot.context.properties.bind.BindException;
|
||||
import org.springframework.boot.context.properties.bind.ConstructorBinding;
|
||||
import org.springframework.boot.context.properties.bind.DefaultValue;
|
||||
@@ -368,7 +370,9 @@ class ConfigurationPropertiesTests {
|
||||
void loadShouldBindToJavaTimeDuration() {
|
||||
load(BasicConfiguration.class, "duration=PT1M");
|
||||
BasicProperties bean = this.context.getBean(BasicProperties.class);
|
||||
assertThat(bean.getDuration().getSeconds()).isEqualTo(60);
|
||||
Duration duration = bean.getDuration();
|
||||
assertThat(duration).isNotNull();
|
||||
assertThat(duration.getSeconds()).isEqualTo(60);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -480,7 +484,9 @@ class ConfigurationPropertiesTests {
|
||||
void loadShouldBindToMapWithNumericKey() {
|
||||
load(MapWithNumericKeyProperties.class, "sample.properties.1.name=One");
|
||||
MapWithNumericKeyProperties bean = this.context.getBean(MapWithNumericKeyProperties.class);
|
||||
assertThat(bean.getProperties().get("1").name).isEqualTo("One");
|
||||
BasicProperties one = bean.getProperties().get("1");
|
||||
assertThat(one).isNotNull();
|
||||
assertThat(one.name).isEqualTo("One");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -491,8 +497,10 @@ class ConfigurationPropertiesTests {
|
||||
Collections.singletonMap("TEST_MAP_FOO_BAR", "baz")));
|
||||
load(WithComplexMapProperties.class);
|
||||
WithComplexMapProperties bean = this.context.getBean(WithComplexMapProperties.class);
|
||||
assertThat(bean.getMap()).containsOnlyKeys("foo");
|
||||
assertThat(bean.getMap().get("foo")).containsOnly(entry("bar", "baz"));
|
||||
Map<String, Map<String, String>> map = bean.getMap();
|
||||
assertThat(map).isNotNull();
|
||||
assertThat(map).containsOnlyKeys("foo");
|
||||
assertThat(map.get("foo")).containsOnly(entry("bar", "baz"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -692,6 +700,7 @@ class ConfigurationPropertiesTests {
|
||||
void loadShouldUseConverterBean() {
|
||||
prepareConverterContext(PersonConverterConfiguration.class, PersonProperties.class);
|
||||
Person person = this.context.getBean(PersonProperties.class).getPerson();
|
||||
assertThat(person).isNotNull();
|
||||
assertThat(person.firstName).isEqualTo("John");
|
||||
assertThat(person.lastName).isEqualTo("Smith");
|
||||
}
|
||||
@@ -727,6 +736,7 @@ class ConfigurationPropertiesTests {
|
||||
this.context.getEnvironment().getPropertySources().addLast(testProperties);
|
||||
this.context.refresh();
|
||||
Person person = this.context.getBean(PersonProperties.class).getPerson();
|
||||
assertThat(person).isNotNull();
|
||||
assertThat(person.firstName).isEqualTo("John");
|
||||
assertThat(person.lastName).isEqualTo("Smith");
|
||||
}
|
||||
@@ -739,9 +749,13 @@ class ConfigurationPropertiesTests {
|
||||
load(new Class<?>[] { PersonConverterConfiguration.class, PersonAndAlienProperties.class },
|
||||
"test.person=John Smith", "test.alien=Alf Tanner");
|
||||
PersonAndAlienProperties properties = this.context.getBean(PersonAndAlienProperties.class);
|
||||
assertThat(properties.getPerson().firstName).isEqualTo("John");
|
||||
assertThat(properties.getPerson().lastName).isEqualTo("Smith");
|
||||
assertThat(properties.getAlien().name).isEqualTo("rennaT flA");
|
||||
Person person = properties.getPerson();
|
||||
assertThat(person).isNotNull();
|
||||
assertThat(person.firstName).isEqualTo("John");
|
||||
assertThat(person.lastName).isEqualTo("Smith");
|
||||
Alien alien = properties.getAlien();
|
||||
assertThat(alien).isNotNull();
|
||||
assertThat(alien.name).isEqualTo("rennaT flA");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -752,9 +766,13 @@ class ConfigurationPropertiesTests {
|
||||
load(new Class<?>[] { AlienConverterConfiguration.class, PersonAndAlienProperties.class },
|
||||
"test.person=John Smith", "test.alien=Alf Tanner");
|
||||
PersonAndAlienProperties properties = this.context.getBean(PersonAndAlienProperties.class);
|
||||
assertThat(properties.getPerson().firstName).isEqualTo("John");
|
||||
assertThat(properties.getPerson().lastName).isEqualTo("Smith");
|
||||
assertThat(properties.getAlien().name).isEqualTo("rennaT flA");
|
||||
Person person = properties.getPerson();
|
||||
assertThat(person).isNotNull();
|
||||
assertThat(person.firstName).isEqualTo("John");
|
||||
assertThat(person.lastName).isEqualTo("Smith");
|
||||
Alien alien = properties.getAlien();
|
||||
assertThat(alien).isNotNull();
|
||||
assertThat(alien.name).isEqualTo("rennaT flA");
|
||||
}
|
||||
|
||||
@Test // gh-38734
|
||||
@@ -765,10 +783,14 @@ class ConfigurationPropertiesTests {
|
||||
load(new Class<?>[] { AlienConverterConfiguration.class, PersonAndAliensProperties.class },
|
||||
"test.person=John Smith", "test.aliens=Alf Tanner,Gilbert");
|
||||
PersonAndAliensProperties properties = this.context.getBean(PersonAndAliensProperties.class);
|
||||
assertThat(properties.getPerson().firstName).isEqualTo("John");
|
||||
assertThat(properties.getPerson().lastName).isEqualTo("Smith");
|
||||
assertThat(properties.getAliens().get(0).name).isEqualTo("rennaT flA");
|
||||
assertThat(properties.getAliens().get(1).name).isEqualTo("trebliG");
|
||||
Person person = properties.getPerson();
|
||||
assertThat(person).isNotNull();
|
||||
assertThat(person.firstName).isEqualTo("John");
|
||||
assertThat(person.lastName).isEqualTo("Smith");
|
||||
List<Alien> aliens = properties.getAliens();
|
||||
assertThat(aliens).isNotNull();
|
||||
assertThat(aliens.get(0).name).isEqualTo("rennaT flA");
|
||||
assertThat(aliens.get(1).name).isEqualTo("trebliG");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -782,6 +804,7 @@ class ConfigurationPropertiesTests {
|
||||
void loadShouldUseGenericConverterBean() {
|
||||
prepareConverterContext(GenericConverterConfiguration.class, PersonProperties.class);
|
||||
Person person = this.context.getBean(PersonProperties.class).getPerson();
|
||||
assertThat(person).isNotNull();
|
||||
assertThat(person.firstName).isEqualTo("John");
|
||||
assertThat(person.lastName).isEqualTo("Smith");
|
||||
}
|
||||
@@ -790,6 +813,7 @@ class ConfigurationPropertiesTests {
|
||||
void loadShouldUseFormatterBean() {
|
||||
prepareConverterContext(FormatterConfiguration.class, PersonProperties.class);
|
||||
Person person = this.context.getBean(PersonProperties.class).getPerson();
|
||||
assertThat(person).isNotNull();
|
||||
assertThat(person.firstName).isEqualTo("John");
|
||||
assertThat(person.lastName).isEqualTo("Smith");
|
||||
}
|
||||
@@ -875,8 +899,10 @@ class ConfigurationPropertiesTests {
|
||||
this.context.getBeanFactory().registerCustomEditor(Person.class, PersonPropertyEditor.class);
|
||||
load(PersonProperties.class, "test.person=boot,spring");
|
||||
PersonProperties bean = this.context.getBean(PersonProperties.class);
|
||||
assertThat(bean.getPerson().firstName).isEqualTo("spring");
|
||||
assertThat(bean.getPerson().lastName).isEqualTo("boot");
|
||||
Person person = bean.getPerson();
|
||||
assertThat(person).isNotNull();
|
||||
assertThat(person.firstName).isEqualTo("spring");
|
||||
assertThat(person.lastName).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -918,11 +944,18 @@ class ConfigurationPropertiesTests {
|
||||
sources.addLast(new MapPropertySource("test", source));
|
||||
load(WithIntegerMapProperties.class);
|
||||
WithIntegerMapProperties bean = this.context.getBean(WithIntegerMapProperties.class);
|
||||
Map<Integer, Foo> x = bean.getMap().get("x");
|
||||
assertThat(x.get(-1).getA()).isEqualTo("baz");
|
||||
assertThat(x.get(-1).getB()).isZero();
|
||||
assertThat(x.get(1).getA()).isEqualTo("bar");
|
||||
assertThat(x.get(1).getB()).isOne();
|
||||
Map<String, Map<Integer, Foo>> map = bean.getMap();
|
||||
assertThat(map).isNotNull();
|
||||
Map<Integer, Foo> x = map.get("x");
|
||||
assertThat(x).isNotNull();
|
||||
Foo minus1 = x.get(-1);
|
||||
assertThat(minus1).isNotNull();
|
||||
assertThat(minus1.getA()).isEqualTo("baz");
|
||||
assertThat(minus1.getB()).isZero();
|
||||
Foo one = x.get(1);
|
||||
assertThat(one).isNotNull();
|
||||
assertThat(one.getA()).isEqualTo("bar");
|
||||
assertThat(one.getB()).isOne();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1133,7 +1166,9 @@ class ConfigurationPropertiesTests {
|
||||
load(JavaBeanNestedConstructorBindingPropertiesConfiguration.class);
|
||||
JavaBeanNestedConstructorBindingProperties bean = this.context
|
||||
.getBean(JavaBeanNestedConstructorBindingProperties.class);
|
||||
assertThat(bean.getNested().getAge()).isEqualTo(5);
|
||||
Nested nested = bean.getNested();
|
||||
assertThat(nested).isNotNull();
|
||||
assertThat(nested.getAge()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1156,7 +1191,9 @@ class ConfigurationPropertiesTests {
|
||||
load(JavaBeanNonDefaultConstructorPropertiesConfiguration.class);
|
||||
JavaBeanNonDefaultConstructorProperties bean = this.context
|
||||
.getBean(JavaBeanNonDefaultConstructorProperties.class);
|
||||
assertThat(bean.getNested().getAge()).isEqualTo(10);
|
||||
JavaBeanNonDefaultConstructorProperties.Nested nested = bean.getNested();
|
||||
assertThat(nested).isNotNull();
|
||||
assertThat(nested.getAge()).isEqualTo(10);
|
||||
}
|
||||
|
||||
@Test // gh-18652
|
||||
@@ -1177,7 +1214,9 @@ class ConfigurationPropertiesTests {
|
||||
load(ConstructorBindingWithOuterClassConstructorBoundConfiguration.class);
|
||||
ConstructorBindingWithOuterClassConstructorBoundProperties bean = this.context
|
||||
.getBean(ConstructorBindingWithOuterClassConstructorBoundProperties.class);
|
||||
assertThat(bean.getNested().getOuter().getAge()).isEqualTo(5);
|
||||
Outer outer = bean.getNested().getOuter();
|
||||
assertThat(outer).isNotNull();
|
||||
assertThat(outer.getAge()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1218,6 +1257,7 @@ class ConfigurationPropertiesTests {
|
||||
void boundPropertiesShouldBeRecorded() {
|
||||
load(NestedConfiguration.class, "name=foo", "nested.name=bar");
|
||||
BoundConfigurationProperties bound = BoundConfigurationProperties.get(this.context);
|
||||
assertThat(bound).isNotNull();
|
||||
Set<ConfigurationPropertyName> keys = bound.getAll().keySet();
|
||||
assertThat(keys.stream().map(ConfigurationPropertyName::toString)).contains("name", "nested.name");
|
||||
}
|
||||
@@ -1228,7 +1268,9 @@ class ConfigurationPropertiesTests {
|
||||
load(WithCustomConverterAndObjectToObjectMethodConfiguration.class, "test.item=foo");
|
||||
WithCustomConverterAndObjectToObjectMethodProperties bean = this.context
|
||||
.getBean(WithCustomConverterAndObjectToObjectMethodProperties.class);
|
||||
assertThat(bean.getItem().getValue()).isEqualTo("foo");
|
||||
WithPublicObjectToObjectMethod item = bean.getItem();
|
||||
assertThat(item).isNotNull();
|
||||
assertThat(item.getValue()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test // gh-33710
|
||||
@@ -1465,15 +1507,15 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties
|
||||
static class WithPostConstructConfiguration {
|
||||
|
||||
private String bar;
|
||||
private @Nullable String bar;
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
void setBar(String bar) {
|
||||
void setBar(@Nullable String bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
String getBar() {
|
||||
@Nullable String getBar() {
|
||||
return this.bar;
|
||||
}
|
||||
|
||||
@@ -1564,13 +1606,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class PropertiesWithResource {
|
||||
|
||||
private Resource resource;
|
||||
private @Nullable Resource resource;
|
||||
|
||||
Resource getResource() {
|
||||
@Nullable Resource getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
void setResource(Resource resource) {
|
||||
void setResource(@Nullable Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
@@ -1581,7 +1623,7 @@ class ConfigurationPropertiesTests {
|
||||
static final String PREFIX = "test:/";
|
||||
|
||||
@Override
|
||||
public Resource resolve(String location, ResourceLoader resourceLoader) {
|
||||
public @Nullable Resource resolve(String location, ResourceLoader resourceLoader) {
|
||||
if (location.startsWith(PREFIX)) {
|
||||
String path = location.substring(PREFIX.length());
|
||||
return new ClassPathResource(path);
|
||||
@@ -1691,13 +1733,13 @@ class ConfigurationPropertiesTests {
|
||||
|
||||
static class AGenericClass<T> {
|
||||
|
||||
private T bar;
|
||||
private @Nullable T bar;
|
||||
|
||||
T getBar() {
|
||||
@Nullable T getBar() {
|
||||
return this.bar;
|
||||
}
|
||||
|
||||
void setBar(T bar) {
|
||||
void setBar(@Nullable T bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
@@ -1705,23 +1747,23 @@ class ConfigurationPropertiesTests {
|
||||
|
||||
static class PrototypeBean {
|
||||
|
||||
private String one;
|
||||
private @Nullable String one;
|
||||
|
||||
private String two;
|
||||
private @Nullable String two;
|
||||
|
||||
String getOne() {
|
||||
@Nullable String getOne() {
|
||||
return this.one;
|
||||
}
|
||||
|
||||
void setOne(String one) {
|
||||
void setOne(@Nullable String one) {
|
||||
this.one = one;
|
||||
}
|
||||
|
||||
String getTwo() {
|
||||
@Nullable String getTwo() {
|
||||
return this.two;
|
||||
}
|
||||
|
||||
void setTwo(String two) {
|
||||
void setTwo(@Nullable String two) {
|
||||
this.two = two;
|
||||
}
|
||||
|
||||
@@ -1737,7 +1779,7 @@ class ConfigurationPropertiesTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
public @Nullable Class<?> getObjectType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1756,17 +1798,17 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties
|
||||
public static class BasicProperties {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
private int[] array;
|
||||
private int @Nullable [] array;
|
||||
|
||||
private List<Integer> list = new ArrayList<>();
|
||||
private @Nullable List<Integer> list = new ArrayList<>();
|
||||
|
||||
private Duration duration;
|
||||
private @Nullable Duration duration;
|
||||
|
||||
// No getter - you should be able to bind to a write-only bean
|
||||
|
||||
public void setName(String name) {
|
||||
public void setName(@Nullable String name) {
|
||||
// Must be public for XML
|
||||
this.name = name;
|
||||
}
|
||||
@@ -1775,23 +1817,23 @@ class ConfigurationPropertiesTests {
|
||||
this.array = values;
|
||||
}
|
||||
|
||||
int[] getArray() {
|
||||
int @Nullable [] getArray() {
|
||||
return this.array;
|
||||
}
|
||||
|
||||
List<Integer> getList() {
|
||||
@Nullable List<Integer> getList() {
|
||||
return this.list;
|
||||
}
|
||||
|
||||
void setList(List<Integer> list) {
|
||||
void setList(@Nullable List<Integer> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
Duration getDuration() {
|
||||
@Nullable Duration getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
void setDuration(Duration duration) {
|
||||
void setDuration(@Nullable Duration duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@@ -1800,11 +1842,11 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties
|
||||
static class NestedProperties {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
private final Nested nested = new Nested();
|
||||
|
||||
void setName(String name) {
|
||||
void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -1814,9 +1856,9 @@ class ConfigurationPropertiesTests {
|
||||
|
||||
static class Nested {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
void setName(String name) {
|
||||
void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -1863,6 +1905,7 @@ class ConfigurationPropertiesTests {
|
||||
static class Jsr303Properties extends BasicProperties {
|
||||
|
||||
@NotEmpty
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private String description;
|
||||
|
||||
String getDescription() {
|
||||
@@ -1920,9 +1963,9 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties
|
||||
static class WithoutAnnotationValueProperties {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
void setName(String name) {
|
||||
void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -1934,13 +1977,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties
|
||||
static class MapProperties {
|
||||
|
||||
private Map<String, String> mymap;
|
||||
private @Nullable Map<String, String> mymap;
|
||||
|
||||
void setMymap(Map<String, String> mymap) {
|
||||
void setMymap(@Nullable Map<String, String> mymap) {
|
||||
this.mymap = mymap;
|
||||
}
|
||||
|
||||
Map<String, String> getMymap() {
|
||||
@Nullable Map<String, String> getMymap() {
|
||||
return this.mymap;
|
||||
}
|
||||
|
||||
@@ -1957,7 +2000,7 @@ class ConfigurationPropertiesTests {
|
||||
assertThat(this.properties).isNotNull();
|
||||
}
|
||||
|
||||
String getName() {
|
||||
@Nullable String getName() {
|
||||
return this.properties.name;
|
||||
}
|
||||
|
||||
@@ -1974,6 +2017,7 @@ class ConfigurationPropertiesTests {
|
||||
static class ValidatedImplementationProperties implements InterfaceForValidatedImplementation {
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private String foo;
|
||||
|
||||
@Override
|
||||
@@ -1992,13 +2036,13 @@ class ConfigurationPropertiesTests {
|
||||
static class WithPropertyPlaceholderValueProperties {
|
||||
|
||||
@Value("${default.value}")
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
void setValue(String value) {
|
||||
void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@@ -2008,23 +2052,23 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class WithEnumProperties {
|
||||
|
||||
private FooEnum theValue;
|
||||
private @Nullable FooEnum theValue;
|
||||
|
||||
private List<FooEnum> theValues;
|
||||
private @Nullable List<FooEnum> theValues;
|
||||
|
||||
void setTheValue(FooEnum value) {
|
||||
void setTheValue(@Nullable FooEnum value) {
|
||||
this.theValue = value;
|
||||
}
|
||||
|
||||
FooEnum getTheValue() {
|
||||
@Nullable FooEnum getTheValue() {
|
||||
return this.theValue;
|
||||
}
|
||||
|
||||
List<FooEnum> getTheValues() {
|
||||
@Nullable List<FooEnum> getTheValues() {
|
||||
return this.theValues;
|
||||
}
|
||||
|
||||
void setTheValues(List<FooEnum> theValues) {
|
||||
void setTheValues(@Nullable List<FooEnum> theValues) {
|
||||
this.theValues = theValues;
|
||||
}
|
||||
|
||||
@@ -2040,13 +2084,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties(prefix = "test", ignoreUnknownFields = false)
|
||||
static class WithCharArrayProperties {
|
||||
|
||||
private char[] chars;
|
||||
private char @Nullable [] chars;
|
||||
|
||||
char[] getChars() {
|
||||
char @Nullable [] getChars() {
|
||||
return this.chars;
|
||||
}
|
||||
|
||||
void setChars(char[] chars) {
|
||||
void setChars(char @Nullable [] chars) {
|
||||
this.chars = chars;
|
||||
}
|
||||
|
||||
@@ -2056,23 +2100,23 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class WithRelaxedNamesProperties {
|
||||
|
||||
private String fooBar;
|
||||
private @Nullable String fooBar;
|
||||
|
||||
private String barBAZ;
|
||||
private @Nullable String barBAZ;
|
||||
|
||||
String getFooBar() {
|
||||
@Nullable String getFooBar() {
|
||||
return this.fooBar;
|
||||
}
|
||||
|
||||
void setFooBar(String fooBar) {
|
||||
void setFooBar(@Nullable String fooBar) {
|
||||
this.fooBar = fooBar;
|
||||
}
|
||||
|
||||
String getBarBAZ() {
|
||||
@Nullable String getBarBAZ() {
|
||||
return this.barBAZ;
|
||||
}
|
||||
|
||||
void setBarBAZ(String barBAZ) {
|
||||
void setBarBAZ(@Nullable String barBAZ) {
|
||||
this.barBAZ = barBAZ;
|
||||
}
|
||||
|
||||
@@ -2083,13 +2127,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class WithMapProperties {
|
||||
|
||||
private Map<String, String> map;
|
||||
private @Nullable Map<String, String> map;
|
||||
|
||||
Map<String, String> getMap() {
|
||||
@Nullable Map<String, String> getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
void setMap(Map<String, String> map) {
|
||||
void setMap(@Nullable Map<String, String> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@@ -2099,13 +2143,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class WithComplexMapProperties {
|
||||
|
||||
private Map<String, Map<String, String>> map;
|
||||
private @Nullable Map<String, Map<String, String>> map;
|
||||
|
||||
Map<String, Map<String, String>> getMap() {
|
||||
@Nullable Map<String, Map<String, String>> getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
void setMap(Map<String, Map<String, String>> map) {
|
||||
void setMap(@Nullable Map<String, Map<String, String>> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@@ -2115,13 +2159,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class WithIntegerMapProperties {
|
||||
|
||||
private Map<String, Map<Integer, Foo>> map;
|
||||
private @Nullable Map<String, Map<Integer, Foo>> map;
|
||||
|
||||
Map<String, Map<Integer, Foo>> getMap() {
|
||||
@Nullable Map<String, Map<Integer, Foo>> getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
void setMap(Map<String, Map<Integer, Foo>> map) {
|
||||
void setMap(@Nullable Map<String, Map<Integer, Foo>> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@@ -2133,13 +2177,13 @@ class ConfigurationPropertiesTests {
|
||||
|
||||
private int foo;
|
||||
|
||||
private String bar;
|
||||
private @Nullable String bar;
|
||||
|
||||
String getBar() {
|
||||
@Nullable String getBar() {
|
||||
return this.bar;
|
||||
}
|
||||
|
||||
void setBar(String bar) {
|
||||
void setBar(@Nullable String bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
@@ -2157,13 +2201,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class PersonProperties {
|
||||
|
||||
private Person person;
|
||||
private @Nullable Person person;
|
||||
|
||||
Person getPerson() {
|
||||
@Nullable Person getPerson() {
|
||||
return this.person;
|
||||
}
|
||||
|
||||
void setPerson(Person person) {
|
||||
void setPerson(@Nullable Person person) {
|
||||
this.person = person;
|
||||
}
|
||||
|
||||
@@ -2173,23 +2217,23 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class PersonAndAlienProperties {
|
||||
|
||||
private Person person;
|
||||
private @Nullable Person person;
|
||||
|
||||
private Alien alien;
|
||||
private @Nullable Alien alien;
|
||||
|
||||
Person getPerson() {
|
||||
@Nullable Person getPerson() {
|
||||
return this.person;
|
||||
}
|
||||
|
||||
void setPerson(Person person) {
|
||||
void setPerson(@Nullable Person person) {
|
||||
this.person = person;
|
||||
}
|
||||
|
||||
Alien getAlien() {
|
||||
@Nullable Alien getAlien() {
|
||||
return this.alien;
|
||||
}
|
||||
|
||||
void setAlien(Alien alien) {
|
||||
void setAlien(@Nullable Alien alien) {
|
||||
this.alien = alien;
|
||||
}
|
||||
|
||||
@@ -2199,23 +2243,23 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class PersonAndAliensProperties {
|
||||
|
||||
private Person person;
|
||||
private @Nullable Person person;
|
||||
|
||||
private List<Alien> aliens;
|
||||
private @Nullable List<Alien> aliens;
|
||||
|
||||
Person getPerson() {
|
||||
@Nullable Person getPerson() {
|
||||
return this.person;
|
||||
}
|
||||
|
||||
void setPerson(Person person) {
|
||||
void setPerson(@Nullable Person person) {
|
||||
this.person = person;
|
||||
}
|
||||
|
||||
List<Alien> getAliens() {
|
||||
@Nullable List<Alien> getAliens() {
|
||||
return this.aliens;
|
||||
}
|
||||
|
||||
void setAliens(List<Alien> aliens) {
|
||||
void setAliens(@Nullable List<Alien> aliens) {
|
||||
this.aliens = aliens;
|
||||
}
|
||||
|
||||
@@ -2237,7 +2281,7 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties
|
||||
static class ValidatorProperties implements Validator {
|
||||
|
||||
private String foo;
|
||||
private @Nullable String foo;
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> type) {
|
||||
@@ -2249,11 +2293,11 @@ class ConfigurationPropertiesTests {
|
||||
ValidationUtils.rejectIfEmpty(errors, "foo", "TEST1");
|
||||
}
|
||||
|
||||
String getFoo() {
|
||||
@Nullable String getFoo() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
void setFoo(String foo) {
|
||||
void setFoo(@Nullable String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
@@ -2293,9 +2337,9 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class WithSetterThatThrowsValidationExceptionProperties {
|
||||
|
||||
private String foo;
|
||||
private @Nullable String foo;
|
||||
|
||||
String getFoo() {
|
||||
@Nullable String getFoo() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
@@ -2311,13 +2355,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("custom")
|
||||
static class WithCustomValidatorProperties {
|
||||
|
||||
private String foo;
|
||||
private @Nullable String foo;
|
||||
|
||||
String getFoo() {
|
||||
@Nullable String getFoo() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
void setFoo(String foo) {
|
||||
void setFoo(@Nullable String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
@@ -2327,13 +2371,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class ListOfGenericClassProperties {
|
||||
|
||||
private List<Class<? extends Throwable>> list;
|
||||
private @Nullable List<Class<? extends Throwable>> list;
|
||||
|
||||
List<Class<? extends Throwable>> getList() {
|
||||
@Nullable List<Class<? extends Throwable>> getList() {
|
||||
return this.list;
|
||||
}
|
||||
|
||||
void setList(List<Class<? extends Throwable>> list) {
|
||||
void setList(@Nullable List<Class<? extends Throwable>> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@@ -2343,13 +2387,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class FileProperties {
|
||||
|
||||
private File file;
|
||||
private @Nullable File file;
|
||||
|
||||
File getFile() {
|
||||
@Nullable File getFile() {
|
||||
return this.file;
|
||||
}
|
||||
|
||||
void setFile(File file) {
|
||||
void setFile(@Nullable File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@@ -2359,24 +2403,24 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class DataSizeProperties {
|
||||
|
||||
private DataSize size;
|
||||
private @Nullable DataSize size;
|
||||
|
||||
@DataSizeUnit(DataUnit.KILOBYTES)
|
||||
private DataSize anotherSize;
|
||||
private @Nullable DataSize anotherSize;
|
||||
|
||||
DataSize getSize() {
|
||||
@Nullable DataSize getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
void setSize(DataSize size) {
|
||||
void setSize(@Nullable DataSize size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
DataSize getAnotherSize() {
|
||||
@Nullable DataSize getAnotherSize() {
|
||||
return this.anotherSize;
|
||||
}
|
||||
|
||||
void setAnotherSize(DataSize anotherSize) {
|
||||
void setAnotherSize(@Nullable DataSize anotherSize) {
|
||||
this.anotherSize = anotherSize;
|
||||
}
|
||||
|
||||
@@ -2385,7 +2429,7 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class OtherInjectedProperties {
|
||||
|
||||
final DataSizeProperties dataSizeProperties;
|
||||
final @Nullable DataSizeProperties dataSizeProperties;
|
||||
|
||||
OtherInjectedProperties(ObjectProvider<DataSizeProperties> dataSizeProperties) {
|
||||
this.dataSizeProperties = dataSizeProperties.getIfUnique();
|
||||
@@ -2578,6 +2622,7 @@ class ConfigurationPropertiesTests {
|
||||
@Override
|
||||
public Person convert(String source) {
|
||||
String[] content = StringUtils.split(source, " ");
|
||||
assertThat(content).isNotNull();
|
||||
return new Person(content[0], content[1]);
|
||||
}
|
||||
|
||||
@@ -2600,8 +2645,9 @@ class ConfigurationPropertiesTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
String[] content = StringUtils.split((String) source, " ");
|
||||
assertThat(content).isNotNull();
|
||||
return new Person(content[0], content[1]);
|
||||
}
|
||||
|
||||
@@ -2669,15 +2715,15 @@ class ConfigurationPropertiesTests {
|
||||
|
||||
static class Foo {
|
||||
|
||||
private String a;
|
||||
private @Nullable String a;
|
||||
|
||||
private int b;
|
||||
|
||||
String getA() {
|
||||
@Nullable String getA() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
void setA(String a) {
|
||||
void setA(@Nullable String a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
@@ -2796,13 +2842,13 @@ class ConfigurationPropertiesTests {
|
||||
|
||||
static class Nested {
|
||||
|
||||
private Outer outer;
|
||||
private @Nullable Outer outer;
|
||||
|
||||
Outer getOuter() {
|
||||
@Nullable Outer getOuter() {
|
||||
return this.outer;
|
||||
}
|
||||
|
||||
void setOuter(Outer nested) {
|
||||
void setOuter(@Nullable Outer nested) {
|
||||
this.outer = nested;
|
||||
}
|
||||
|
||||
@@ -2890,13 +2936,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class JavaBeanNestedConstructorBindingProperties {
|
||||
|
||||
private Nested nested;
|
||||
private @Nullable Nested nested;
|
||||
|
||||
Nested getNested() {
|
||||
@Nullable Nested getNested() {
|
||||
return this.nested;
|
||||
}
|
||||
|
||||
void setNested(Nested nested) {
|
||||
void setNested(@Nullable Nested nested) {
|
||||
this.nested = nested;
|
||||
}
|
||||
|
||||
@@ -2926,13 +2972,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class JavaBeanNonDefaultConstructorProperties {
|
||||
|
||||
private Nested nested;
|
||||
private @Nullable Nested nested;
|
||||
|
||||
Nested getNested() {
|
||||
@Nullable Nested getNested() {
|
||||
return this.nested;
|
||||
}
|
||||
|
||||
void setNested(Nested nested) {
|
||||
void setNested(@Nullable Nested nested) {
|
||||
this.nested = nested;
|
||||
}
|
||||
|
||||
@@ -3076,13 +3122,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class WithCustomConverterAndObjectToObjectMethodProperties {
|
||||
|
||||
private WithPublicObjectToObjectMethod item;
|
||||
private @Nullable WithPublicObjectToObjectMethod item;
|
||||
|
||||
WithPublicObjectToObjectMethod getItem() {
|
||||
@Nullable WithPublicObjectToObjectMethod getItem() {
|
||||
return this.item;
|
||||
}
|
||||
|
||||
void setItem(WithPublicObjectToObjectMethod item) {
|
||||
void setItem(@Nullable WithPublicObjectToObjectMethod item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@@ -3199,17 +3245,17 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class PotentiallyConstructorBoundProperties {
|
||||
|
||||
private String prop;
|
||||
private @Nullable String prop;
|
||||
|
||||
PotentiallyConstructorBoundProperties(String notAProperty) {
|
||||
|
||||
}
|
||||
|
||||
String getProp() {
|
||||
@Nullable String getProp() {
|
||||
return this.prop;
|
||||
}
|
||||
|
||||
void setProp(String prop) {
|
||||
void setProp(@Nullable String prop) {
|
||||
this.prop = prop;
|
||||
}
|
||||
|
||||
@@ -3223,13 +3269,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class ResourceArrayProperties {
|
||||
|
||||
private Resource[] resources;
|
||||
private Resource @Nullable [] resources;
|
||||
|
||||
Resource[] getResources() {
|
||||
Resource @Nullable [] getResources() {
|
||||
return this.resources;
|
||||
}
|
||||
|
||||
void setResources(Resource[] resources) {
|
||||
void setResources(Resource @Nullable [] resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
@@ -3243,13 +3289,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class ResourceCollectionProperties {
|
||||
|
||||
private Collection<Resource> resources;
|
||||
private @Nullable Collection<Resource> resources;
|
||||
|
||||
Collection<Resource> getResources() {
|
||||
@Nullable Collection<Resource> getResources() {
|
||||
return this.resources;
|
||||
}
|
||||
|
||||
void setResources(Collection<Resource> resources) {
|
||||
void setResources(@Nullable Collection<Resource> resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
@@ -3311,13 +3357,13 @@ class ConfigurationPropertiesTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class SetterBoundCustomListProperties {
|
||||
|
||||
private CustomList<String> values;
|
||||
private @Nullable CustomList<String> values;
|
||||
|
||||
CustomList<String> getValues() {
|
||||
@Nullable CustomList<String> getValues() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
void setValues(CustomList<String> values) {
|
||||
void setValues(@Nullable CustomList<String> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -70,6 +70,7 @@ class ConversionServiceDeducerTests {
|
||||
applicationContext.getBeanFactory().setConversionService(conversionService);
|
||||
ConversionServiceDeducer deducer = new ConversionServiceDeducer(applicationContext);
|
||||
List<ConversionService> conversionServices = deducer.getConversionServices();
|
||||
assertThat(conversionServices).isNotNull();
|
||||
assertThat(conversionServices).containsOnly(conversionService);
|
||||
assertThat(conversionServices.get(0)).isSameAs(conversionService);
|
||||
}
|
||||
@@ -106,6 +107,7 @@ class ConversionServiceDeducerTests {
|
||||
ConversionServiceDeducer deducer = new ConversionServiceDeducer(applicationContext);
|
||||
List<ConversionService> conversionServices = deducer.getConversionServices();
|
||||
InputStream inputStream = new ByteArrayInputStream("test".getBytes(StandardCharsets.UTF_8));
|
||||
assertThat(conversionServices).isNotNull();
|
||||
assertThat(conversionServices.get(0).convert(inputStream, String.class)).isEqualTo("test");
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot.context.properties;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||
@@ -32,13 +33,14 @@ class IncompatibleConfigurationFailureAnalyzerTests {
|
||||
@Test
|
||||
void incompatibleConfigurationListsKeys() {
|
||||
FailureAnalysis failureAnalysis = performAnalysis("spring.first.key", "spring.second.key");
|
||||
assertThat(failureAnalysis).isNotNull();
|
||||
assertThat(failureAnalysis.getDescription()).contains(
|
||||
"The following configuration properties have incompatible values: [spring.first.key, spring.second.key]");
|
||||
assertThat(failureAnalysis.getAction())
|
||||
.contains("Review the docs for spring.first.key, spring.second.key and change the configured values.");
|
||||
}
|
||||
|
||||
private FailureAnalysis performAnalysis(String... keys) {
|
||||
private @Nullable FailureAnalysis performAnalysis(String... keys) {
|
||||
IncompatibleConfigurationException failure = new IncompatibleConfigurationException(keys);
|
||||
return new IncompatibleConfigurationFailureAnalyzer().analyze(failure);
|
||||
}
|
||||
|
||||
+5
-3
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.context.properties;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Class used to test multi-constructor binding. Must be public and have public
|
||||
* constructors.
|
||||
@@ -24,7 +26,7 @@ package org.springframework.boot.context.properties;
|
||||
*/
|
||||
public class MultiConstructorConfigurationProperties {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
private int age;
|
||||
|
||||
@@ -35,11 +37,11 @@ public class MultiConstructorConfigurationProperties {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
public @Nullable String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
public void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
+7
-5
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot.context.properties;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
@@ -42,6 +43,7 @@ class NotConstructorBoundInjectionFailureAnalyzerTests {
|
||||
void failureAnalysisForConfigurationPropertiesThatShouldHaveBeenConstructorBound() {
|
||||
FailureAnalysis analysis = analyzeFailure(
|
||||
createFailure(ShouldHaveUsedConstructorBindingPropertiesConfiguration.class));
|
||||
assertThat(analysis).isNotNull();
|
||||
assertThat(analysis.getDescription()).isEqualTo(ConstructorBoundProperties.class.getSimpleName()
|
||||
+ " is annotated with @" + ConstructorBinding.class.getSimpleName()
|
||||
+ " but it is defined as a regular bean which caused dependency injection to fail.");
|
||||
@@ -57,7 +59,7 @@ class NotConstructorBoundInjectionFailureAnalyzerTests {
|
||||
assertThat(analysis).isNull();
|
||||
}
|
||||
|
||||
private FatalBeanException createFailure(Class<?> config) {
|
||||
private @Nullable FatalBeanException createFailure(Class<?> config) {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
|
||||
context.register(config);
|
||||
context.refresh();
|
||||
@@ -68,7 +70,7 @@ class NotConstructorBoundInjectionFailureAnalyzerTests {
|
||||
}
|
||||
}
|
||||
|
||||
private FailureAnalysis analyzeFailure(Exception failure) {
|
||||
private @Nullable FailureAnalysis analyzeFailure(@Nullable Exception failure) {
|
||||
assertThat(failure).isNotNull();
|
||||
FailureAnalysis analysis = this.analyzer.analyze(failure);
|
||||
if (analysis != null) {
|
||||
@@ -101,18 +103,18 @@ class NotConstructorBoundInjectionFailureAnalyzerTests {
|
||||
@ConfigurationProperties("test")
|
||||
static class JavaBeanBoundProperties {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
@Autowired
|
||||
JavaBeanBoundProperties(String dependency) {
|
||||
|
||||
}
|
||||
|
||||
String getName() {
|
||||
@Nullable String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
+15
-8
@@ -22,6 +22,7 @@ import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -63,6 +64,7 @@ class PropertyMapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void fromWhenSupplierIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.map.from((Supplier<?>) null))
|
||||
.withMessageContaining("'supplier' must not be null");
|
||||
@@ -80,6 +82,7 @@ class PropertyMapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void toWhenConsumerIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.map.from(() -> "").to(null))
|
||||
.withMessageContaining("'consumer' must not be null");
|
||||
@@ -100,6 +103,7 @@ class PropertyMapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void asWhenAdapterIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.map.from(() -> "").as(null))
|
||||
.withMessageContaining("'adapter' must not be null");
|
||||
@@ -262,7 +266,10 @@ class PropertyMapperTests {
|
||||
|
||||
@Test
|
||||
void asWhenNull() {
|
||||
String value = this.map.from((String) null).always().as(String::valueOf).toInstance((string) -> string);
|
||||
String value = this.map.from((String) null).always().as(String::valueOf).toInstance((string) -> {
|
||||
assertThat(string).isNotNull();
|
||||
return string;
|
||||
});
|
||||
assertThat(value).isEqualTo("null");
|
||||
}
|
||||
|
||||
@@ -336,16 +343,16 @@ class PropertyMapperTests {
|
||||
|
||||
static class ExampleDest {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
boolean setNameCalled;
|
||||
|
||||
void setName(String name) {
|
||||
void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
this.setNameCalled = true;
|
||||
}
|
||||
|
||||
String getName() {
|
||||
@Nullable String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@@ -355,21 +362,21 @@ class PropertyMapperTests {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Integer age;
|
||||
private final @Nullable Integer age;
|
||||
|
||||
final boolean withAgeCalled;
|
||||
|
||||
Immutable(String name, Integer age) {
|
||||
Immutable(String name, @Nullable Integer age) {
|
||||
this(name, age, false);
|
||||
}
|
||||
|
||||
private Immutable(String name, Integer age, boolean withAgeCalled) {
|
||||
private Immutable(String name, @Nullable Integer age, boolean withAgeCalled) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.withAgeCalled = withAgeCalled;
|
||||
}
|
||||
|
||||
Immutable withAge(Integer age) {
|
||||
Immutable withAge(@Nullable Integer age) {
|
||||
return new Immutable(this.name, age, true);
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.context.properties;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A {@link ConfigurationProperties @ConfigurationProperties} with an additional
|
||||
* single-arg public constructor. Used in {@link ConfigurationPropertiesTests}.
|
||||
@@ -25,7 +27,7 @@ package org.springframework.boot.context.properties;
|
||||
@ConfigurationProperties("test")
|
||||
public class WithPublicStringConstructorProperties {
|
||||
|
||||
private String a;
|
||||
private @Nullable String a;
|
||||
|
||||
public WithPublicStringConstructorProperties() {
|
||||
}
|
||||
@@ -34,11 +36,11 @@ public class WithPublicStringConstructorProperties {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public String getA() {
|
||||
public @Nullable String getA() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
public void setA(String a) {
|
||||
public void setA(@Nullable String a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -142,7 +142,9 @@ class ArrayBinderTests {
|
||||
this.sources.add(source);
|
||||
assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.binder.bind("foo", INTEGER_ARRAY))
|
||||
.satisfies((ex) -> {
|
||||
Set<ConfigurationProperty> unbound = ((UnboundConfigurationPropertiesException) ex.getCause())
|
||||
Throwable cause = ex.getCause();
|
||||
assertThat(cause).isNotNull();
|
||||
Set<ConfigurationProperty> unbound = ((UnboundConfigurationPropertiesException) cause)
|
||||
.getUnboundProperties();
|
||||
assertThat(unbound).hasSize(1);
|
||||
ConfigurationProperty property = unbound.iterator().next();
|
||||
|
||||
+7
-6
@@ -18,6 +18,7 @@ package org.springframework.boot.context.properties.bind;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
@@ -60,13 +61,13 @@ class BackCompatibilityBinderIntegrationTests {
|
||||
|
||||
static class ExampleCamelCaseBean {
|
||||
|
||||
private String zkNodes;
|
||||
private @Nullable String zkNodes;
|
||||
|
||||
String getZkNodes() {
|
||||
@Nullable String getZkNodes() {
|
||||
return this.zkNodes;
|
||||
}
|
||||
|
||||
void setZkNodes(String zkNodes) {
|
||||
void setZkNodes(@Nullable String zkNodes) {
|
||||
this.zkNodes = zkNodes;
|
||||
}
|
||||
|
||||
@@ -74,13 +75,13 @@ class BackCompatibilityBinderIntegrationTests {
|
||||
|
||||
static class PasswordProperties {
|
||||
|
||||
private String password;
|
||||
private @Nullable String password;
|
||||
|
||||
String getPassword() {
|
||||
@Nullable String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
void setPassword(String password) {
|
||||
void setPassword(@Nullable String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
|
||||
+17
-9
@@ -24,6 +24,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
@@ -53,6 +54,7 @@ import static org.mockito.BDDMockito.then;
|
||||
class BindConverterTests {
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Consumer<PropertyEditorRegistry> propertyEditorInitializer;
|
||||
|
||||
@Test
|
||||
@@ -121,6 +123,7 @@ class BindConverterTests {
|
||||
void convertWhenHasCustomEditorShouldConvert() {
|
||||
BindConverter bindConverter = getPropertyEditorOnlyBindConverter(this::registerSampleTypeEditor);
|
||||
SampleType converted = bindConverter.convert("test", ResolvableType.forClass(SampleType.class));
|
||||
assertThat(converted).isNotNull();
|
||||
assertThat(converted.getText()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@@ -128,6 +131,7 @@ class BindConverterTests {
|
||||
void convertWhenHasEditorByConventionShouldConvert() {
|
||||
BindConverter bindConverter = getPropertyEditorOnlyBindConverter(null);
|
||||
ConventionType converted = bindConverter.convert("test", ResolvableType.forClass(ConventionType.class));
|
||||
assertThat(converted).isNotNull();
|
||||
assertThat(converted.getText()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@@ -144,6 +148,7 @@ class BindConverterTests {
|
||||
void convertWhenHasEditorForArrayElementShouldConvert() {
|
||||
BindConverter bindConverter = getPropertyEditorOnlyBindConverter(this::registerSampleTypeEditor);
|
||||
SampleType[] converted = bindConverter.convert("test", ResolvableType.forClass(SampleType[].class));
|
||||
assertThat(converted).isNotNull();
|
||||
assertThat(converted).isNotEmpty();
|
||||
assertThat(converted[0].getText()).isEqualTo("test");
|
||||
}
|
||||
@@ -152,6 +157,7 @@ class BindConverterTests {
|
||||
void convertWhenConversionServiceCanConvertShouldConvert() {
|
||||
BindConverter bindConverter = getBindConverter(new SampleTypeConverter());
|
||||
SampleType converted = bindConverter.convert("test", ResolvableType.forClass(SampleType.class));
|
||||
assertThat(converted).isNotNull();
|
||||
assertThat(converted.getText()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@@ -169,6 +175,7 @@ class BindConverterTests {
|
||||
BindConverter bindConverter = BindConverter.get(Collections.singletonList(new GenericConversionService()),
|
||||
null);
|
||||
File result = bindConverter.convert(".", ResolvableType.forClass(File.class));
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPath()).isEqualTo(".");
|
||||
}
|
||||
|
||||
@@ -177,6 +184,7 @@ class BindConverterTests {
|
||||
BindConverter bindConverter = BindConverter.get(Collections.singletonList(new GenericConversionService()),
|
||||
null);
|
||||
Duration result = bindConverter.convert("10s", ResolvableType.forClass(Duration.class));
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getSeconds()).isEqualTo(10);
|
||||
}
|
||||
|
||||
@@ -215,7 +223,7 @@ class BindConverterTests {
|
||||
}
|
||||
|
||||
private BindConverter getPropertyEditorOnlyBindConverter(
|
||||
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
|
||||
@Nullable Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
|
||||
return BindConverter.get(Collections.singletonList(new ThrowingConversionService()), propertyEditorInitializer);
|
||||
}
|
||||
|
||||
@@ -231,9 +239,9 @@ class BindConverterTests {
|
||||
|
||||
static class SampleType {
|
||||
|
||||
private String text;
|
||||
private @Nullable String text;
|
||||
|
||||
String getText() {
|
||||
@Nullable String getText() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
@@ -266,9 +274,9 @@ class BindConverterTests {
|
||||
|
||||
static class ConventionType {
|
||||
|
||||
private String text;
|
||||
private @Nullable String text;
|
||||
|
||||
String getText() {
|
||||
@Nullable String getText() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
@@ -291,22 +299,22 @@ class BindConverterTests {
|
||||
static class ThrowingConversionService implements ConversionService {
|
||||
|
||||
@Override
|
||||
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
|
||||
public boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType) {
|
||||
throw new AssertionError("Should not call conversion service");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
public boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
throw new AssertionError("Should not call conversion service");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T convert(Object source, Class<T> targetType) {
|
||||
public <T> T convert(@Nullable Object source, Class<T> targetType) {
|
||||
throw new AssertionError("Should not call conversion service");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
public Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
throw new AssertionError("Should not call conversion service");
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -44,12 +44,15 @@ import static org.mockito.BDDMockito.then;
|
||||
class BindResultTests {
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Consumer<String> consumer;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Function<String, String> mapper;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Supplier<String> supplier;
|
||||
|
||||
@Test
|
||||
@@ -78,6 +81,7 @@ class BindResultTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void ifBoundWhenConsumerIsNullShouldThrowException() {
|
||||
BindResult<String> result = BindResult.of("foo");
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> result.ifBound(null))
|
||||
@@ -99,6 +103,7 @@ class BindResultTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void mapWhenMapperIsNullShouldThrowException() {
|
||||
BindResult<String> result = BindResult.of("foo");
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> result.map(null))
|
||||
|
||||
+52
-49
@@ -25,6 +25,7 @@ import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.tomcat.jdbc.pool.PoolProperties;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.hint.ExecutableHint;
|
||||
@@ -295,7 +296,7 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
throws NoSuchMethodException, SecurityException {
|
||||
Constructor<?> constructor = PoolProperties.InterceptorProperty.class.getConstructor(String.class,
|
||||
String.class);
|
||||
String[] parameterNames = new StandardReflectionParameterNameDiscoverer().getParameterNames(constructor);
|
||||
@Nullable String[] parameterNames = new StandardReflectionParameterNameDiscoverer().getParameterNames(constructor);
|
||||
assertThat(parameterNames).isNull();
|
||||
assertThatNoException().isThrownBy(() -> registerHints(PoolProperties.class));
|
||||
}
|
||||
@@ -425,24 +426,24 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public static class WithExternalNested {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private SampleType sampleType;
|
||||
private @Nullable SampleType sampleType;
|
||||
|
||||
public String getName() {
|
||||
public @Nullable String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
public void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SampleType getSampleType() {
|
||||
public @Nullable SampleType getSampleType() {
|
||||
return this.sampleType;
|
||||
}
|
||||
|
||||
public void setSampleType(SampleType sampleType) {
|
||||
public void setSampleType(@Nullable SampleType sampleType) {
|
||||
this.sampleType = sampleType;
|
||||
}
|
||||
|
||||
@@ -451,13 +452,13 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
public static class WithRecursive {
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private Recursive recursive;
|
||||
private @Nullable Recursive recursive;
|
||||
|
||||
public Recursive getRecursive() {
|
||||
public @Nullable Recursive getRecursive() {
|
||||
return this.recursive;
|
||||
}
|
||||
|
||||
public void setRecursive(Recursive recursive) {
|
||||
public void setRecursive(@Nullable Recursive recursive) {
|
||||
this.recursive = recursive;
|
||||
}
|
||||
|
||||
@@ -466,9 +467,9 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
public static class ImmutableWithRecursive {
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private final ImmutableRecursive recursive;
|
||||
private final @Nullable ImmutableRecursive recursive;
|
||||
|
||||
ImmutableWithRecursive(ImmutableRecursive recursive) {
|
||||
ImmutableWithRecursive(@Nullable ImmutableRecursive recursive) {
|
||||
this.recursive = recursive;
|
||||
}
|
||||
|
||||
@@ -476,8 +477,10 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public static class WithWellKnownTypes implements ApplicationContextAware, EnvironmentAware {
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Environment environment;
|
||||
|
||||
public ApplicationContext getApplicationContext() {
|
||||
@@ -516,23 +519,23 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public static class PackagePrivateGettersAndSetters {
|
||||
|
||||
private String alpha;
|
||||
private @Nullable String alpha;
|
||||
|
||||
private Map<String, String> bravo;
|
||||
private @Nullable Map<String, String> bravo;
|
||||
|
||||
String getAlpha() {
|
||||
@Nullable String getAlpha() {
|
||||
return this.alpha;
|
||||
}
|
||||
|
||||
void setAlpha(String alpha) {
|
||||
void setAlpha(@Nullable String alpha) {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
Map<String, String> getBravo() {
|
||||
@Nullable Map<String, String> getBravo() {
|
||||
return this.bravo;
|
||||
}
|
||||
|
||||
void setBravo(Map<String, String> bravo) {
|
||||
void setBravo(@Nullable Map<String, String> bravo) {
|
||||
this.bravo = bravo;
|
||||
}
|
||||
|
||||
@@ -563,13 +566,13 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public static class Recursive {
|
||||
|
||||
private Recursive recursive;
|
||||
private @Nullable Recursive recursive;
|
||||
|
||||
public Recursive getRecursive() {
|
||||
public @Nullable Recursive getRecursive() {
|
||||
return this.recursive;
|
||||
}
|
||||
|
||||
public void setRecursive(Recursive recursive) {
|
||||
public void setRecursive(@Nullable Recursive recursive) {
|
||||
this.recursive = recursive;
|
||||
}
|
||||
|
||||
@@ -578,9 +581,9 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
public static class ImmutableRecursive {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final ImmutableRecursive recursive;
|
||||
private final @Nullable ImmutableRecursive recursive;
|
||||
|
||||
ImmutableRecursive(ImmutableRecursive recursive) {
|
||||
ImmutableRecursive(@Nullable ImmutableRecursive recursive) {
|
||||
this.recursive = recursive;
|
||||
}
|
||||
|
||||
@@ -589,13 +592,13 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
public static class WithCrossReference {
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private CrossReferenceA crossReferenceA;
|
||||
private @Nullable CrossReferenceA crossReferenceA;
|
||||
|
||||
public void setCrossReferenceA(CrossReferenceA crossReferenceA) {
|
||||
public void setCrossReferenceA(@Nullable CrossReferenceA crossReferenceA) {
|
||||
this.crossReferenceA = crossReferenceA;
|
||||
}
|
||||
|
||||
public CrossReferenceA getCrossReferenceA() {
|
||||
public @Nullable CrossReferenceA getCrossReferenceA() {
|
||||
return this.crossReferenceA;
|
||||
}
|
||||
|
||||
@@ -604,13 +607,13 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
public static class CrossReferenceA {
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private CrossReferenceB crossReferenceB;
|
||||
private @Nullable CrossReferenceB crossReferenceB;
|
||||
|
||||
public void setCrossReferenceB(CrossReferenceB crossReferenceB) {
|
||||
public void setCrossReferenceB(@Nullable CrossReferenceB crossReferenceB) {
|
||||
this.crossReferenceB = crossReferenceB;
|
||||
}
|
||||
|
||||
public CrossReferenceB getCrossReferenceB() {
|
||||
public @Nullable CrossReferenceB getCrossReferenceB() {
|
||||
return this.crossReferenceB;
|
||||
}
|
||||
|
||||
@@ -618,13 +621,13 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public static class CrossReferenceB {
|
||||
|
||||
private CrossReferenceA crossReferenceA;
|
||||
private @Nullable CrossReferenceA crossReferenceA;
|
||||
|
||||
public void setCrossReferenceA(CrossReferenceA crossReferenceA) {
|
||||
public void setCrossReferenceA(@Nullable CrossReferenceA crossReferenceA) {
|
||||
this.crossReferenceA = crossReferenceA;
|
||||
}
|
||||
|
||||
public CrossReferenceA getCrossReferenceA() {
|
||||
public @Nullable CrossReferenceA getCrossReferenceA() {
|
||||
return this.crossReferenceA;
|
||||
}
|
||||
|
||||
@@ -633,9 +636,9 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
public static class WithGeneric {
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private GenericObject<?> generic;
|
||||
private @Nullable GenericObject<?> generic;
|
||||
|
||||
public GenericObject<?> getGeneric() {
|
||||
public @Nullable GenericObject<?> getGeneric() {
|
||||
return this.generic;
|
||||
}
|
||||
|
||||
@@ -665,13 +668,13 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public static class Nested {
|
||||
|
||||
private String field;
|
||||
private @Nullable String field;
|
||||
|
||||
public String getField() {
|
||||
public @Nullable String getField() {
|
||||
return this.field;
|
||||
}
|
||||
|
||||
public void setField(String field) {
|
||||
public void setField(@Nullable String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@@ -697,13 +700,13 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public static class Nested {
|
||||
|
||||
private String field;
|
||||
private @Nullable String field;
|
||||
|
||||
public String getField() {
|
||||
public @Nullable String getField() {
|
||||
return this.field;
|
||||
}
|
||||
|
||||
public void setField(String field) {
|
||||
public void setField(@Nullable String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@@ -715,25 +718,25 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public abstract static class BaseProperties {
|
||||
|
||||
private InheritedNested inheritedNested;
|
||||
private @Nullable InheritedNested inheritedNested;
|
||||
|
||||
public InheritedNested getInheritedNested() {
|
||||
public @Nullable InheritedNested getInheritedNested() {
|
||||
return this.inheritedNested;
|
||||
}
|
||||
|
||||
public void setInheritedNested(InheritedNested inheritedNested) {
|
||||
public void setInheritedNested(@Nullable InheritedNested inheritedNested) {
|
||||
this.inheritedNested = inheritedNested;
|
||||
}
|
||||
|
||||
public static class InheritedNested {
|
||||
|
||||
private String alpha;
|
||||
private @Nullable String alpha;
|
||||
|
||||
public String getAlpha() {
|
||||
public @Nullable String getAlpha() {
|
||||
return this.alpha;
|
||||
}
|
||||
|
||||
public void setAlpha(String alpha) {
|
||||
public void setAlpha(@Nullable String alpha) {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
@@ -743,13 +746,13 @@ class BindableRuntimeHintsRegistrarTests {
|
||||
|
||||
public static class ExtendingProperties extends BaseProperties {
|
||||
|
||||
private String bravo;
|
||||
private @Nullable String bravo;
|
||||
|
||||
public String getBravo() {
|
||||
public @Nullable String getBravo() {
|
||||
return this.bravo;
|
||||
}
|
||||
|
||||
public void setBravo(String bravo) {
|
||||
public void setBravo(@Nullable String bravo) {
|
||||
this.bravo = bravo;
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -19,6 +19,7 @@ package org.springframework.boot.context.properties.bind;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -41,12 +42,14 @@ import static org.mockito.Mockito.mock;
|
||||
class BindableTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void ofClassWhenTypeIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Bindable.of((Class<?>) null))
|
||||
.withMessageContaining("'type' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void ofTypeWhenTypeIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Bindable.of((ResolvableType) null))
|
||||
.withMessageContaining("'type' must not be null");
|
||||
@@ -68,18 +71,23 @@ class BindableTests {
|
||||
String instance = "foo";
|
||||
ResolvableType type = ResolvableType.forClass(String.class);
|
||||
assertThat(Bindable.ofInstance(instance).getType()).isEqualTo(type);
|
||||
assertThat(Bindable.ofInstance(instance).getValue().get()).isEqualTo("foo");
|
||||
Supplier<String> value = Bindable.ofInstance(instance).getValue();
|
||||
assertThat(value).isNotNull();
|
||||
assertThat(value.get()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofClassWithExistingValueShouldSetTypeAndExistingValue() {
|
||||
assertThat(Bindable.of(String.class).withExistingValue("foo").getValue().get()).isEqualTo("foo");
|
||||
Supplier<String> value = Bindable.of(String.class).withExistingValue("foo").getValue();
|
||||
assertThat(value).isNotNull();
|
||||
assertThat(value.get()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofTypeWithExistingValueShouldSetTypeAndExistingValue() {
|
||||
assertThat(Bindable.of(ResolvableType.forClass(String.class)).withExistingValue("foo").getValue().get())
|
||||
.isEqualTo("foo");
|
||||
Supplier<Object> value = Bindable.of(ResolvableType.forClass(String.class)).withExistingValue("foo").getValue();
|
||||
assertThat(value).isNotNull();
|
||||
assertThat(value.get()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,7 +101,9 @@ class BindableTests {
|
||||
void ofTypeWhenPrimitiveWithExistingValueWrapperShouldNotThrowException() {
|
||||
Bindable<Integer> bindable = Bindable.<Integer>of(ResolvableType.forClass(int.class)).withExistingValue(123);
|
||||
assertThat(bindable.getType().resolve()).isEqualTo(int.class);
|
||||
assertThat(bindable.getValue().get()).isEqualTo(123);
|
||||
Supplier<Integer> value = bindable.getValue();
|
||||
assertThat(value).isNotNull();
|
||||
assertThat(value.get()).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+24
-18
@@ -25,6 +25,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.validation.Validation;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
@@ -71,12 +72,14 @@ class BinderTests {
|
||||
private Binder binder = new Binder(this.sources);
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenSourcesIsNullArrayShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new Binder((ConfigurationPropertySource[]) null))
|
||||
.withMessageContaining("'sources' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenSourcesIsNullIterableShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new Binder((Iterable<ConfigurationPropertySource>) null))
|
||||
.withMessageContaining("'sources' must not be null");
|
||||
@@ -95,6 +98,7 @@ class BinderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void bindWhenNameIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.binder.bind((ConfigurationPropertyName) null, Bindable.of(String.class),
|
||||
@@ -103,6 +107,7 @@ class BinderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void bindWhenTargetIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.binder.bind(ConfigurationPropertyName.of("foo"), null, BindHandler.DEFAULT))
|
||||
@@ -268,7 +273,7 @@ class BinderTests {
|
||||
ConfigurationPropertySources.from(new PropertySource<String>("test") {
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
public @Nullable Object getProperty(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -301,7 +306,7 @@ class BinderTests {
|
||||
Map<String, Object> source = new HashMap<>();
|
||||
source.put("value", "hello");
|
||||
source.put("", "bar");
|
||||
Iterable<ConfigurationPropertySource> propertySources = ConfigurationPropertySources
|
||||
Iterable<@Nullable ConfigurationPropertySource> propertySources = ConfigurationPropertySources
|
||||
.from(new MapPropertySource("test", source));
|
||||
propertySources.forEach(this.sources::add);
|
||||
Bindable<JavaBean> target = Bindable.of(JavaBean.class);
|
||||
@@ -330,7 +335,8 @@ class BinderTests {
|
||||
BindResult<JavaBean> result = this.binder.bind("foo", Bindable.of(JavaBean.class), new BindHandler() {
|
||||
|
||||
@Override
|
||||
public <T> Bindable<T> onStart(ConfigurationPropertyName name, Bindable<T> target, BindContext context) {
|
||||
public <T> @Nullable Bindable<T> onStart(ConfigurationPropertyName name, Bindable<T> target,
|
||||
BindContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -372,15 +378,15 @@ class BinderTests {
|
||||
|
||||
static class JavaBean {
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
private final List<String> items = Collections.emptyList();
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(String value) {
|
||||
void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -433,13 +439,13 @@ class BinderTests {
|
||||
@Validated
|
||||
static class ResourceBean {
|
||||
|
||||
private Resource resource;
|
||||
private @Nullable Resource resource;
|
||||
|
||||
Resource getResource() {
|
||||
@Nullable Resource getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
void setResource(Resource resource) {
|
||||
void setResource(@Nullable Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
@@ -447,13 +453,13 @@ class BinderTests {
|
||||
|
||||
static class CycleBean1 {
|
||||
|
||||
private CycleBean2 two;
|
||||
private @Nullable CycleBean2 two;
|
||||
|
||||
CycleBean2 getTwo() {
|
||||
@Nullable CycleBean2 getTwo() {
|
||||
return this.two;
|
||||
}
|
||||
|
||||
void setTwo(CycleBean2 two) {
|
||||
void setTwo(@Nullable CycleBean2 two) {
|
||||
this.two = two;
|
||||
}
|
||||
|
||||
@@ -461,13 +467,13 @@ class BinderTests {
|
||||
|
||||
static class CycleBean2 {
|
||||
|
||||
private CycleBean1 one;
|
||||
private @Nullable CycleBean1 one;
|
||||
|
||||
CycleBean1 getOne() {
|
||||
@Nullable CycleBean1 getOne() {
|
||||
return this.one;
|
||||
}
|
||||
|
||||
void setOne(CycleBean1 one) {
|
||||
void setOne(@Nullable CycleBean1 one) {
|
||||
this.one = one;
|
||||
}
|
||||
|
||||
@@ -475,13 +481,13 @@ class BinderTests {
|
||||
|
||||
static class GenericBean<T> {
|
||||
|
||||
private T bar;
|
||||
private @Nullable T bar;
|
||||
|
||||
T getBar() {
|
||||
@Nullable T getBar() {
|
||||
return this.bar;
|
||||
}
|
||||
|
||||
void setBar(T bar) {
|
||||
void setBar(@Nullable T bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -49,6 +49,7 @@ class BoundPropertiesTrackingBindHandlerTests {
|
||||
private Binder binder;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Consumer<ConfigurationProperty> consumer;
|
||||
|
||||
@BeforeEach
|
||||
|
||||
+36
-25
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.BinderTests.ExampleEnum;
|
||||
@@ -117,7 +118,9 @@ class CollectionBinderTests {
|
||||
this.sources.add(source);
|
||||
assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.binder.bind("foo", INTEGER_LIST))
|
||||
.satisfies((ex) -> {
|
||||
Set<ConfigurationProperty> unbound = ((UnboundConfigurationPropertiesException) ex.getCause())
|
||||
Throwable cause = ex.getCause();
|
||||
assertThat(cause).isNotNull();
|
||||
Set<ConfigurationProperty> unbound = ((UnboundConfigurationPropertiesException) cause)
|
||||
.getUnboundProperties();
|
||||
assertThat(unbound).singleElement().satisfies((property) -> {
|
||||
assertThat(property.getName()).hasToString("foo[3]");
|
||||
@@ -137,7 +140,9 @@ class CollectionBinderTests {
|
||||
assertThatExceptionOfType(BindException.class)
|
||||
.isThrownBy(() -> this.binder.bind("foo", Bindable.listOf(Name.class)))
|
||||
.satisfies((ex) -> {
|
||||
Set<ConfigurationProperty> unbound = ((UnboundConfigurationPropertiesException) ex.getCause())
|
||||
Throwable cause = ex.getCause();
|
||||
assertThat(cause).isNotNull();
|
||||
Set<ConfigurationProperty> unbound = ((UnboundConfigurationPropertiesException) cause)
|
||||
.getUnboundProperties();
|
||||
assertThat(unbound).singleElement().satisfies((property) -> {
|
||||
assertThat(property.getName()).hasToString("foo[1].missing");
|
||||
@@ -171,7 +176,9 @@ class CollectionBinderTests {
|
||||
Bindable<List<JavaBean>> target = Bindable.listOf(JavaBean.class);
|
||||
assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.binder.bind("foo", target))
|
||||
.satisfies((ex) -> {
|
||||
Set<ConfigurationProperty> unbound = ((UnboundConfigurationPropertiesException) ex.getCause())
|
||||
Throwable cause = ex.getCause();
|
||||
assertThat(cause).isNotNull();
|
||||
Set<ConfigurationProperty> unbound = ((UnboundConfigurationPropertiesException) cause)
|
||||
.getUnboundProperties();
|
||||
assertThat(unbound).singleElement().satisfies((property) -> {
|
||||
assertThat(property.getName()).hasToString("foo[4].value");
|
||||
@@ -394,8 +401,10 @@ class CollectionBinderTests {
|
||||
Bindable<BeanWithNestedCollection> target = Bindable.of(BeanWithNestedCollection.class);
|
||||
BeanWithNestedCollection foo = this.binder.bind("foo", target).get();
|
||||
assertThat(foo.getValue()).isEqualTo("one");
|
||||
assertThat(foo.getFoos().get(0).getValue()).isEqualTo("two");
|
||||
assertThat(foo.getFoos().get(1).getValue()).isEqualTo("three");
|
||||
List<BeanWithNestedCollection> foos = foo.getFoos();
|
||||
assertThat(foos).isNotNull();
|
||||
assertThat(foos.get(0).getValue()).isEqualTo("two");
|
||||
assertThat(foos.get(1).getValue()).isEqualTo("three");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -465,7 +474,9 @@ class CollectionBinderTests {
|
||||
source.put("foo.values[0]", "foo-bar,bar-baz");
|
||||
this.sources.add(source);
|
||||
BeanWithEnumSetCollection result = this.binder.bind("foo", Bindable.of(BeanWithEnumSetCollection.class)).get();
|
||||
assertThat(result.getValues().get(0)).containsExactly(ExampleEnum.FOO_BAR, ExampleEnum.BAR_BAZ);
|
||||
List<EnumSet<ExampleEnum>> values = result.getValues();
|
||||
assertThat(values).isNotNull();
|
||||
assertThat(values.get(0)).containsExactly(ExampleEnum.FOO_BAR, ExampleEnum.BAR_BAZ);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -504,7 +515,7 @@ class CollectionBinderTests {
|
||||
|
||||
private Set<String> itemsSet = new LinkedHashSet<>();
|
||||
|
||||
private String string;
|
||||
private @Nullable String string;
|
||||
|
||||
List<String> getItems() {
|
||||
return this.items;
|
||||
@@ -522,11 +533,11 @@ class CollectionBinderTests {
|
||||
this.itemsSet = itemsSet;
|
||||
}
|
||||
|
||||
String getString() {
|
||||
@Nullable String getString() {
|
||||
return this.string;
|
||||
}
|
||||
|
||||
void setString(String string) {
|
||||
void setString(@Nullable String string) {
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
@@ -576,23 +587,23 @@ class CollectionBinderTests {
|
||||
|
||||
static class BeanWithNestedCollection {
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
private List<BeanWithNestedCollection> foos;
|
||||
private @Nullable List<BeanWithNestedCollection> foos;
|
||||
|
||||
List<BeanWithNestedCollection> getFoos() {
|
||||
@Nullable List<BeanWithNestedCollection> getFoos() {
|
||||
return this.foos;
|
||||
}
|
||||
|
||||
void setFoos(List<BeanWithNestedCollection> foos) {
|
||||
void setFoos(@Nullable List<BeanWithNestedCollection> foos) {
|
||||
this.foos = foos;
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(String value) {
|
||||
void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -600,13 +611,13 @@ class CollectionBinderTests {
|
||||
|
||||
static class ClonedArrayBean {
|
||||
|
||||
private String[] bar;
|
||||
private String @Nullable [] bar;
|
||||
|
||||
String[] getBar() {
|
||||
return this.bar.clone();
|
||||
String @Nullable [] getBar() {
|
||||
return (this.bar != null) ? this.bar.clone() : null;
|
||||
}
|
||||
|
||||
void setBar(String[] bar) {
|
||||
void setBar(String @Nullable [] bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
@@ -614,13 +625,13 @@ class CollectionBinderTests {
|
||||
|
||||
static class BeanWithGetterException {
|
||||
|
||||
private List<String> values;
|
||||
private @Nullable List<String> values;
|
||||
|
||||
void setValues(List<String> values) {
|
||||
void setValues(@Nullable List<String> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
List<String> getValues() {
|
||||
@Nullable List<String> getValues() {
|
||||
return Collections.unmodifiableList(this.values);
|
||||
}
|
||||
|
||||
@@ -628,13 +639,13 @@ class CollectionBinderTests {
|
||||
|
||||
static class BeanWithEnumSetCollection {
|
||||
|
||||
private List<EnumSet<ExampleEnum>> values;
|
||||
private @Nullable List<EnumSet<ExampleEnum>> values;
|
||||
|
||||
void setValues(List<EnumSet<ExampleEnum>> values) {
|
||||
void setValues(@Nullable List<EnumSet<ExampleEnum>> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
List<EnumSet<ExampleEnum>> getValues() {
|
||||
@Nullable List<EnumSet<ExampleEnum>> getValues() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
|
||||
+77
-67
@@ -28,6 +28,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.JavaBeanBinder.Bean;
|
||||
@@ -271,8 +272,10 @@ class JavaBeanBinderTests {
|
||||
source.put("foo.value-bean.string-value", "foo");
|
||||
this.sources.add(source);
|
||||
ExampleNestedBean bean = this.binder.bind("foo", Bindable.of(ExampleNestedBean.class)).get();
|
||||
assertThat(bean.getValueBean().getIntValue()).isEqualTo(123);
|
||||
assertThat(bean.getValueBean().getStringValue()).isEqualTo("foo");
|
||||
ExampleValueBean valueBean = bean.getValueBean();
|
||||
assertThat(valueBean).isNotNull();
|
||||
assertThat(valueBean.getIntValue()).isEqualTo(123);
|
||||
assertThat(valueBean.getStringValue()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -505,8 +508,12 @@ class JavaBeanBinderTests {
|
||||
source.put("foo.booleans[b].value", "true");
|
||||
this.sources.add(source);
|
||||
ExampleWithGenericMap bean = this.binder.bind("foo", Bindable.of(ExampleWithGenericMap.class)).get();
|
||||
assertThat(bean.getIntegers().get("a").getValue()).isOne();
|
||||
assertThat(bean.getBooleans().get("b").getValue()).isTrue();
|
||||
GenericValue<Integer> a = bean.getIntegers().get("a");
|
||||
assertThat(a).isNotNull();
|
||||
assertThat(a.getValue()).isOne();
|
||||
GenericValue<Boolean> b = bean.getBooleans().get("b");
|
||||
assertThat(b).isNotNull();
|
||||
assertThat(b.getValue()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -524,7 +531,9 @@ class JavaBeanBinderTests {
|
||||
void beanPropertiesPreferMatchingType() {
|
||||
// gh-16206
|
||||
ResolvableType type = ResolvableType.forClass(PropertyWithOverloadedSetter.class);
|
||||
Bean<PropertyWithOverloadedSetter> bean = new Bean<>(type, type.resolve()) {
|
||||
Class<?> resolvedType = type.resolve();
|
||||
assertThat(resolvedType).isNotNull();
|
||||
Bean<PropertyWithOverloadedSetter> bean = new Bean<>(type, resolvedType) {
|
||||
|
||||
@Override
|
||||
protected void addProperties(Method[] declaredMethods, Field[] declaredFields) {
|
||||
@@ -553,6 +562,7 @@ class JavaBeanBinderTests {
|
||||
|
||||
};
|
||||
BeanProperty property = bean.getProperties().get("property");
|
||||
assertThat(property).isNotNull();
|
||||
PropertyWithOverloadedSetter target = new PropertyWithOverloadedSetter();
|
||||
property.setValue(() -> target, "some string");
|
||||
}
|
||||
@@ -621,9 +631,9 @@ class JavaBeanBinderTests {
|
||||
|
||||
private long longValue;
|
||||
|
||||
private String stringValue;
|
||||
private @Nullable String stringValue;
|
||||
|
||||
private ExampleEnum enumValue;
|
||||
private @Nullable ExampleEnum enumValue;
|
||||
|
||||
int getIntValue() {
|
||||
return this.intValue;
|
||||
@@ -641,19 +651,19 @@ class JavaBeanBinderTests {
|
||||
this.longValue = longValue;
|
||||
}
|
||||
|
||||
String getStringValue() {
|
||||
@Nullable String getStringValue() {
|
||||
return this.stringValue;
|
||||
}
|
||||
|
||||
void setStringValue(String stringValue) {
|
||||
void setStringValue(@Nullable String stringValue) {
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
ExampleEnum getEnumValue() {
|
||||
@Nullable ExampleEnum getEnumValue() {
|
||||
return this.enumValue;
|
||||
}
|
||||
|
||||
void setEnumValue(ExampleEnum enumValue) {
|
||||
void setEnumValue(@Nullable ExampleEnum enumValue) {
|
||||
this.enumValue = enumValue;
|
||||
}
|
||||
|
||||
@@ -662,13 +672,13 @@ class JavaBeanBinderTests {
|
||||
static class ExampleRenamedPropertyBean {
|
||||
|
||||
@Name("public")
|
||||
private String exampleProperty;
|
||||
private @Nullable String exampleProperty;
|
||||
|
||||
String getExampleProperty() {
|
||||
@Nullable String getExampleProperty() {
|
||||
return this.exampleProperty;
|
||||
}
|
||||
|
||||
void setExampleProperty(String exampleProperty) {
|
||||
void setExampleProperty(@Nullable String exampleProperty) {
|
||||
this.exampleProperty = exampleProperty;
|
||||
}
|
||||
|
||||
@@ -700,13 +710,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleMapBean {
|
||||
|
||||
private Map<ExampleEnum, Integer> map;
|
||||
private @Nullable Map<ExampleEnum, Integer> map;
|
||||
|
||||
Map<ExampleEnum, Integer> getMap() {
|
||||
@Nullable Map<ExampleEnum, Integer> getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
void setMap(Map<ExampleEnum, Integer> map) {
|
||||
void setMap(@Nullable Map<ExampleEnum, Integer> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@@ -714,13 +724,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleListBean {
|
||||
|
||||
private List<ExampleEnum> list;
|
||||
private @Nullable List<ExampleEnum> list;
|
||||
|
||||
List<ExampleEnum> getList() {
|
||||
@Nullable List<ExampleEnum> getList() {
|
||||
return this.list;
|
||||
}
|
||||
|
||||
void setList(List<ExampleEnum> list) {
|
||||
void setList(@Nullable List<ExampleEnum> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@@ -728,13 +738,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleSetBean {
|
||||
|
||||
private Set<ExampleEnum> set;
|
||||
private @Nullable Set<ExampleEnum> set;
|
||||
|
||||
Set<ExampleEnum> getSet() {
|
||||
@Nullable Set<ExampleEnum> getSet() {
|
||||
return this.set;
|
||||
}
|
||||
|
||||
void setSet(Set<ExampleEnum> set) {
|
||||
void setSet(@Nullable Set<ExampleEnum> set) {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
@@ -742,13 +752,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleCollectionBean {
|
||||
|
||||
private Collection<ExampleEnum> collection;
|
||||
private @Nullable Collection<ExampleEnum> collection;
|
||||
|
||||
Collection<ExampleEnum> getCollection() {
|
||||
@Nullable Collection<ExampleEnum> getCollection() {
|
||||
return this.collection;
|
||||
}
|
||||
|
||||
void setCollection(Collection<ExampleEnum> collection) {
|
||||
void setCollection(@Nullable Collection<ExampleEnum> collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
@@ -797,13 +807,13 @@ class JavaBeanBinderTests {
|
||||
static class ExampleCollectionBeanWithDelimiter {
|
||||
|
||||
@Delimiter("|")
|
||||
private Collection<ExampleEnum> collection;
|
||||
private @Nullable Collection<ExampleEnum> collection;
|
||||
|
||||
Collection<ExampleEnum> getCollection() {
|
||||
@Nullable Collection<ExampleEnum> getCollection() {
|
||||
return this.collection;
|
||||
}
|
||||
|
||||
void setCollection(Collection<ExampleEnum> collection) {
|
||||
void setCollection(@Nullable Collection<ExampleEnum> collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
@@ -811,13 +821,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleNestedBean {
|
||||
|
||||
private ExampleValueBean valueBean;
|
||||
private @Nullable ExampleValueBean valueBean;
|
||||
|
||||
ExampleValueBean getValueBean() {
|
||||
@Nullable ExampleValueBean getValueBean() {
|
||||
return this.valueBean;
|
||||
}
|
||||
|
||||
void setValueBean(ExampleValueBean valueBean) {
|
||||
void setValueBean(@Nullable ExampleValueBean valueBean) {
|
||||
this.valueBean = valueBean;
|
||||
}
|
||||
|
||||
@@ -863,14 +873,14 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleNestedSubclassBean extends ExampleNestedBean {
|
||||
|
||||
private ExampleValueSubclassBean valueBean;
|
||||
private @Nullable ExampleValueSubclassBean valueBean;
|
||||
|
||||
@Override
|
||||
ExampleValueSubclassBean getValueBean() {
|
||||
@Nullable ExampleValueSubclassBean getValueBean() {
|
||||
return this.valueBean;
|
||||
}
|
||||
|
||||
void setValueBean(ExampleValueSubclassBean valueBean) {
|
||||
void setValueBean(@Nullable ExampleValueSubclassBean valueBean) {
|
||||
this.valueBean = valueBean;
|
||||
}
|
||||
|
||||
@@ -892,17 +902,17 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleWithNonDefaultConstructor {
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
ExampleWithNonDefaultConstructor(String value) {
|
||||
ExampleWithNonDefaultConstructor(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(String value) {
|
||||
void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -976,7 +986,7 @@ class JavaBeanBinderTests {
|
||||
|
||||
private int value;
|
||||
|
||||
private ExampleWithSelfReference self;
|
||||
private @Nullable ExampleWithSelfReference self;
|
||||
|
||||
int getValue() {
|
||||
return this.value;
|
||||
@@ -986,11 +996,11 @@ class JavaBeanBinderTests {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
ExampleWithSelfReference getSelf() {
|
||||
@Nullable ExampleWithSelfReference getSelf() {
|
||||
return this.self;
|
||||
}
|
||||
|
||||
void setSelf(ExampleWithSelfReference self) {
|
||||
void setSelf(@Nullable ExampleWithSelfReference self) {
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
@@ -998,13 +1008,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleWithInvalidAccessors {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
String getName() {
|
||||
@Nullable String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -1020,15 +1030,15 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleWithStaticAccessors {
|
||||
|
||||
private static String name;
|
||||
private static @Nullable String name;
|
||||
|
||||
private int counter;
|
||||
|
||||
static String getName() {
|
||||
static @Nullable String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
static void setName(String name) {
|
||||
static void setName(@Nullable String name) {
|
||||
ExampleWithStaticAccessors.name = name;
|
||||
}
|
||||
|
||||
@@ -1053,13 +1063,13 @@ class JavaBeanBinderTests {
|
||||
static class ConverterAnnotatedExampleBean {
|
||||
|
||||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
|
||||
private LocalDate date;
|
||||
private @Nullable LocalDate date;
|
||||
|
||||
LocalDate getDate() {
|
||||
@Nullable LocalDate getDate() {
|
||||
return this.date;
|
||||
}
|
||||
|
||||
void setDate(LocalDate date) {
|
||||
void setDate(@Nullable LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
@@ -1067,13 +1077,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class ExampleWithPropertyEditorType {
|
||||
|
||||
private Class<? extends Throwable> value;
|
||||
private @Nullable Class<? extends Throwable> value;
|
||||
|
||||
Class<? extends Throwable> getValue() {
|
||||
@Nullable Class<? extends Throwable> getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(Class<? extends Throwable> value) {
|
||||
void setValue(@Nullable Class<? extends Throwable> value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -1097,13 +1107,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class GenericValue<T> {
|
||||
|
||||
private T value;
|
||||
private @Nullable T value;
|
||||
|
||||
T getValue() {
|
||||
@Nullable T getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(T value) {
|
||||
void setValue(@Nullable T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -1111,17 +1121,17 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class PropertyWithOverloadedSetter {
|
||||
|
||||
private String property;
|
||||
private @Nullable String property;
|
||||
|
||||
void setProperty(int property) {
|
||||
this.property = String.valueOf(property);
|
||||
}
|
||||
|
||||
void setProperty(String property) {
|
||||
void setProperty(@Nullable String property) {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
String getProperty() {
|
||||
@Nullable String getProperty() {
|
||||
return this.property;
|
||||
}
|
||||
|
||||
@@ -1143,13 +1153,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class PackagePrivateSetterBean {
|
||||
|
||||
private String property;
|
||||
private @Nullable String property;
|
||||
|
||||
String getProperty() {
|
||||
@Nullable String getProperty() {
|
||||
return this.property;
|
||||
}
|
||||
|
||||
void setProperty(String property) {
|
||||
void setProperty(@Nullable String property) {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
@@ -1225,13 +1235,13 @@ class JavaBeanBinderTests {
|
||||
|
||||
static class BridgeMethodsBase<T extends BridgeBaseType> {
|
||||
|
||||
private T value;
|
||||
private @Nullable T value;
|
||||
|
||||
T getValue() {
|
||||
@Nullable T getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(T value) {
|
||||
void setValue(@Nullable T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -1240,7 +1250,7 @@ class JavaBeanBinderTests {
|
||||
static class BridgeMethods extends BridgeMethodsBase<BridgeType> {
|
||||
|
||||
@Override
|
||||
BridgeType getValue() {
|
||||
@Nullable BridgeType getValue() {
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.context.properties.bind;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Java bean with an additional public single-arg constructor.
|
||||
*
|
||||
@@ -23,7 +25,7 @@ package org.springframework.boot.context.properties.bind;
|
||||
*/
|
||||
public class JavaBeanWithPublicConstructor {
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
public JavaBeanWithPublicConstructor() {
|
||||
}
|
||||
@@ -32,11 +34,11 @@ public class JavaBeanWithPublicConstructor {
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
public @Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
public void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
+34
-20
@@ -29,6 +29,7 @@ import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
@@ -369,7 +370,9 @@ class MapBinderTests {
|
||||
source.put("foo.bar[2].value", "c");
|
||||
this.sources.add(source);
|
||||
Map<String, List<JavaBean>> map = this.binder.bind("foo", target).get();
|
||||
List<String> values = map.get("bar").stream().map(JavaBean::getValue).toList();
|
||||
List<JavaBean> bar = map.get("bar");
|
||||
assertThat(bar).isNotNull();
|
||||
List<String> values = bar.stream().map(JavaBean::getValue).toList();
|
||||
assertThat(values).containsExactly("a", "b", "c");
|
||||
|
||||
}
|
||||
@@ -387,7 +390,9 @@ class MapBinderTests {
|
||||
this.sources.add(new MockConfigurationPropertySource("foo.bar.pattern", "1", "line1"));
|
||||
Bindable<Map<String, Foo>> target = Bindable.mapOf(String.class, Foo.class);
|
||||
Map<String, Foo> map = this.binder.bind("foo", target).get();
|
||||
assertThat(map.get("bar").getPattern()).isEqualTo("1");
|
||||
Foo bar = map.get("bar");
|
||||
assertThat(bar).isNotNull();
|
||||
assertThat(bar.getPattern()).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -434,7 +439,9 @@ class MapBinderTests {
|
||||
mockSource.put("foo.bar.baz[2].value", "c");
|
||||
this.sources.add(mockSource);
|
||||
Map<String, List<JavaBean>> map = this.binder.bind("foo", target).get();
|
||||
List<String> values = map.get("bar.baz").stream().map(JavaBean::getValue).toList();
|
||||
List<JavaBean> barBaz = map.get("bar.baz");
|
||||
assertThat(barBaz).isNotNull();
|
||||
List<String> values = barBaz.stream().map(JavaBean::getValue).toList();
|
||||
assertThat(values).containsExactly("a", "b", "c");
|
||||
}
|
||||
|
||||
@@ -495,8 +502,12 @@ class MapBinderTests {
|
||||
this.sources.add(source);
|
||||
BindResult<NestableFoo> foo = this.binder.bind("foo", NestableFoo.class);
|
||||
assertThat(foo.get().getValue()).isNotNull();
|
||||
assertThat(foo.get().getFoos().get("foo1").getValue()).isEqualTo("two");
|
||||
assertThat(foo.get().getFoos().get("foo2").getValue()).isEqualTo("three");
|
||||
NestableFoo foo1 = foo.get().getFoos().get("foo1");
|
||||
assertThat(foo1).isNotNull();
|
||||
assertThat(foo1.getValue()).isEqualTo("two");
|
||||
NestableFoo foo2 = foo.get().getFoos().get("foo2");
|
||||
assertThat(foo2).isNotNull();
|
||||
assertThat(foo2.getValue()).isEqualTo("three");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -611,8 +622,11 @@ class MapBinderTests {
|
||||
source.put("foo.addresses.localhost[1]", "127.0.0.2");
|
||||
this.sources.add(source);
|
||||
MapWithWildcardProperties result = this.binder.bind("foo", Bindable.of(MapWithWildcardProperties.class)).get();
|
||||
assertThat(result.getAddresses().get("localhost").stream().map(InetAddress::getHostAddress))
|
||||
.containsExactly("127.0.0.1", "127.0.0.2");
|
||||
Map<String, ? extends List<? extends InetAddress>> addresses = result.getAddresses();
|
||||
assertThat(addresses).isNotNull();
|
||||
List<? extends InetAddress> localhost = addresses.get("localhost");
|
||||
assertThat(localhost).isNotNull();
|
||||
assertThat(localhost.stream().map(InetAddress::getHostAddress)).containsExactly("127.0.0.1", "127.0.0.2");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -670,20 +684,20 @@ class MapBinderTests {
|
||||
|
||||
static class Foo {
|
||||
|
||||
private String pattern;
|
||||
private @Nullable String pattern;
|
||||
|
||||
Foo() {
|
||||
}
|
||||
|
||||
Foo(String pattern) {
|
||||
Foo(@Nullable String pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
String getPattern() {
|
||||
@Nullable String getPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
void setPattern(String pattern) {
|
||||
void setPattern(@Nullable String pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@@ -693,17 +707,17 @@ class MapBinderTests {
|
||||
|
||||
private final Map<String, NestableFoo> foos = new LinkedHashMap<>();
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
Map<String, NestableFoo> getFoos() {
|
||||
return this.foos;
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(String value) {
|
||||
void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -762,13 +776,13 @@ class MapBinderTests {
|
||||
|
||||
static class BeanWithGetterException {
|
||||
|
||||
private Map<String, String> values;
|
||||
private @Nullable Map<String, String> values;
|
||||
|
||||
void setValues(Map<String, String> values) {
|
||||
void setValues(@Nullable Map<String, String> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
Map<String, String> getValues() {
|
||||
@Nullable Map<String, String> getValues() {
|
||||
return Collections.unmodifiableMap(this.values);
|
||||
}
|
||||
|
||||
@@ -776,13 +790,13 @@ class MapBinderTests {
|
||||
|
||||
static class MapWithWildcardProperties {
|
||||
|
||||
private Map<String, ? extends List<? extends InetAddress>> addresses;
|
||||
private @Nullable Map<String, ? extends List<? extends InetAddress>> addresses;
|
||||
|
||||
Map<String, ? extends List<? extends InetAddress>> getAddresses() {
|
||||
@Nullable Map<String, ? extends List<? extends InetAddress>> getAddresses() {
|
||||
return this.addresses;
|
||||
}
|
||||
|
||||
void setAddresses(Map<String, ? extends List<? extends InetAddress>> addresses) {
|
||||
void setAddresses(@Nullable Map<String, ? extends List<? extends InetAddress>> addresses) {
|
||||
this.addresses = addresses;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -19,6 +19,7 @@ package org.springframework.boot.context.properties.bind;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.env.Environment;
|
||||
@@ -38,9 +39,10 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
*/
|
||||
class PropertySourcesPlaceholdersResolverTests {
|
||||
|
||||
private PropertySourcesPlaceholdersResolver resolver;
|
||||
private @Nullable PropertySourcesPlaceholdersResolver resolver;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void placeholderResolverIfEnvironmentNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new PropertySourcesPlaceholdersResolver((Environment) null))
|
||||
|
||||
+9
-8
@@ -28,6 +28,7 @@ import java.util.Optional;
|
||||
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import com.jayway.jsonpath.internal.CharacterIndex;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||
@@ -733,9 +734,9 @@ class ValueObjectBinderTests {
|
||||
|
||||
static class NestedJavaBean {
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@@ -903,23 +904,23 @@ class ValueObjectBinderTests {
|
||||
|
||||
static class NonExtractableParameterName {
|
||||
|
||||
private String value;
|
||||
private @Nullable String value;
|
||||
|
||||
private JsonPath jsonPath;
|
||||
private @Nullable JsonPath jsonPath;
|
||||
|
||||
String getValue() {
|
||||
@Nullable String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
void setValue(String value) {
|
||||
void setValue(@Nullable String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
JsonPath getJsonPath() {
|
||||
@Nullable JsonPath getJsonPath() {
|
||||
return this.jsonPath;
|
||||
}
|
||||
|
||||
void setJsonPath(JsonPath jsonPath) {
|
||||
void setJsonPath(@Nullable JsonPath jsonPath) {
|
||||
this.jsonPath = jsonPath;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -89,7 +90,7 @@ class IgnoreTopLevelConverterNotFoundBindHandlerTests {
|
||||
|
||||
private int foo;
|
||||
|
||||
private Map<String, String> map;
|
||||
private @Nullable Map<String, String> map;
|
||||
|
||||
int getFoo() {
|
||||
return this.foo;
|
||||
@@ -99,11 +100,11 @@ class IgnoreTopLevelConverterNotFoundBindHandlerTests {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
Map<String, String> getMap() {
|
||||
@Nullable Map<String, String> getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
void setMap(Map<String, String> map) {
|
||||
void setMap(@Nullable Map<String, String> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
|
||||
+50
-38
@@ -19,6 +19,7 @@ package org.springframework.boot.context.properties.bind.handler;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.BindException;
|
||||
@@ -42,7 +43,7 @@ class NoUnboundElementsBindHandlerTests {
|
||||
|
||||
private final List<ConfigurationPropertySource> sources = new ArrayList<>();
|
||||
|
||||
private Binder binder;
|
||||
private @Nullable Binder binder;
|
||||
|
||||
@Test
|
||||
void bindWhenNotUsingNoUnboundElementsHandlerShouldBind() {
|
||||
@@ -73,11 +74,14 @@ class NoUnboundElementsBindHandlerTests {
|
||||
source.put("example.baz", "bar");
|
||||
this.sources.add(source);
|
||||
this.binder = new Binder(this.sources);
|
||||
assertThatExceptionOfType(BindException.class)
|
||||
.isThrownBy(
|
||||
() -> this.binder.bind("example", Bindable.of(Example.class), new NoUnboundElementsBindHandler()))
|
||||
.satisfies((ex) -> assertThat(ex.getCause().getMessage())
|
||||
.contains("The elements [example.baz] were left unbound"));
|
||||
assertThatExceptionOfType(BindException.class).isThrownBy(() -> {
|
||||
assertThat(this.binder).isNotNull();
|
||||
this.binder.bind("example", Bindable.of(Example.class), new NoUnboundElementsBindHandler());
|
||||
}).satisfies((ex) -> {
|
||||
Throwable cause = ex.getCause();
|
||||
assertThat(cause).isNotNull();
|
||||
assertThat(cause.getMessage()).contains("The elements [example.baz] were left unbound");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,11 +130,14 @@ class NoUnboundElementsBindHandlerTests {
|
||||
source.put("example.foo[0]", "bar");
|
||||
this.sources.add(source);
|
||||
this.binder = new Binder(this.sources);
|
||||
assertThatExceptionOfType(BindException.class)
|
||||
.isThrownBy(
|
||||
() -> this.binder.bind("example", Bindable.of(Example.class), new NoUnboundElementsBindHandler()))
|
||||
.satisfies((ex) -> assertThat(ex.getCause().getMessage())
|
||||
.contains("The elements [example.foo[0]] were left unbound"));
|
||||
assertThatExceptionOfType(BindException.class).isThrownBy(() -> {
|
||||
assertThat(this.binder).isNotNull();
|
||||
this.binder.bind("example", Bindable.of(Example.class), new NoUnboundElementsBindHandler());
|
||||
}).satisfies((ex) -> {
|
||||
Throwable cause = ex.getCause();
|
||||
assertThat(cause).isNotNull();
|
||||
assertThat(cause.getMessage()).contains("The elements [example.foo[0]] were left unbound");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,7 +155,9 @@ class NoUnboundElementsBindHandlerTests {
|
||||
NoUnboundElementsBindHandler handler = new NoUnboundElementsBindHandler();
|
||||
ExampleWithNestedList bound = this.binder.bind("example", Bindable.of(ExampleWithNestedList.class), handler)
|
||||
.get();
|
||||
assertThat(bound.getNested().get(0).getStringValue()).isEqualTo("bar");
|
||||
List<Nested> nested = bound.getNested();
|
||||
assertThat(nested).isNotNull();
|
||||
assertThat(nested.get(0).getStringValue()).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -162,22 +171,25 @@ class NoUnboundElementsBindHandlerTests {
|
||||
this.sources.add(source1);
|
||||
this.sources.add(source2);
|
||||
this.binder = new Binder(this.sources);
|
||||
assertThatExceptionOfType(BindException.class)
|
||||
.isThrownBy(() -> this.binder.bind("example", Bindable.of(ExampleWithNestedList.class),
|
||||
new NoUnboundElementsBindHandler()))
|
||||
.satisfies((ex) -> assertThat(ex.getCause().getMessage())
|
||||
.contains("The elements [example.nested[1].invalid] were left unbound"));
|
||||
assertThatExceptionOfType(BindException.class).isThrownBy(() -> {
|
||||
assertThat(this.binder).isNotNull();
|
||||
this.binder.bind("example", Bindable.of(ExampleWithNestedList.class), new NoUnboundElementsBindHandler());
|
||||
}).satisfies((ex) -> {
|
||||
Throwable cause = ex.getCause();
|
||||
assertThat(cause).isNotNull();
|
||||
assertThat(cause.getMessage()).contains("The elements [example.nested[1].invalid] were left unbound");
|
||||
});
|
||||
}
|
||||
|
||||
static class Example {
|
||||
|
||||
private String foo;
|
||||
private @Nullable String foo;
|
||||
|
||||
String getFoo() {
|
||||
@Nullable String getFoo() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
void setFoo(String foo) {
|
||||
void setFoo(@Nullable String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
@@ -185,13 +197,13 @@ class NoUnboundElementsBindHandlerTests {
|
||||
|
||||
static class ExampleWithList {
|
||||
|
||||
private List<String> foo;
|
||||
private @Nullable List<String> foo;
|
||||
|
||||
List<String> getFoo() {
|
||||
@Nullable List<String> getFoo() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
void setFoo(List<String> foo) {
|
||||
void setFoo(@Nullable List<String> foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
@@ -199,13 +211,13 @@ class NoUnboundElementsBindHandlerTests {
|
||||
|
||||
static class ExampleWithNestedList {
|
||||
|
||||
private List<Nested> nested;
|
||||
private @Nullable List<Nested> nested;
|
||||
|
||||
List<Nested> getNested() {
|
||||
@Nullable List<Nested> getNested() {
|
||||
return this.nested;
|
||||
}
|
||||
|
||||
void setNested(List<Nested> nested) {
|
||||
void setNested(@Nullable List<Nested> nested) {
|
||||
this.nested = nested;
|
||||
}
|
||||
|
||||
@@ -213,33 +225,33 @@ class NoUnboundElementsBindHandlerTests {
|
||||
|
||||
static class Nested {
|
||||
|
||||
private String stringValue;
|
||||
private @Nullable String stringValue;
|
||||
|
||||
private Integer intValue;
|
||||
private @Nullable Integer intValue;
|
||||
|
||||
private OtherNested otherNested;
|
||||
private @Nullable OtherNested otherNested;
|
||||
|
||||
String getStringValue() {
|
||||
@Nullable String getStringValue() {
|
||||
return this.stringValue;
|
||||
}
|
||||
|
||||
void setStringValue(String value) {
|
||||
void setStringValue(@Nullable String value) {
|
||||
this.stringValue = value;
|
||||
}
|
||||
|
||||
Integer getIntValue() {
|
||||
@Nullable Integer getIntValue() {
|
||||
return this.intValue;
|
||||
}
|
||||
|
||||
void setIntValue(Integer intValue) {
|
||||
void setIntValue(@Nullable Integer intValue) {
|
||||
this.intValue = intValue;
|
||||
}
|
||||
|
||||
OtherNested getOtherNested() {
|
||||
@Nullable OtherNested getOtherNested() {
|
||||
return this.otherNested;
|
||||
}
|
||||
|
||||
void setOtherNested(OtherNested otherNested) {
|
||||
void setOtherNested(@Nullable OtherNested otherNested) {
|
||||
this.otherNested = otherNested;
|
||||
}
|
||||
|
||||
@@ -247,13 +259,13 @@ class NoUnboundElementsBindHandlerTests {
|
||||
|
||||
static class OtherNested {
|
||||
|
||||
private String baz;
|
||||
private @Nullable String baz;
|
||||
|
||||
String getBaz() {
|
||||
@Nullable String getBaz() {
|
||||
return this.baz;
|
||||
}
|
||||
|
||||
void setBaz(String baz) {
|
||||
void setBaz(@Nullable String baz) {
|
||||
this.baz = baz;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.mock;
|
||||
class BindValidationExceptionTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenValidationErrorsIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new BindValidationException(null))
|
||||
.withMessageContaining("'validationErrors' must not be null");
|
||||
|
||||
+14
-10
@@ -25,6 +25,7 @@ import java.util.Set;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -268,7 +269,9 @@ class ValidationBindHandlerTests {
|
||||
action.run();
|
||||
}
|
||||
catch (BindException ex) {
|
||||
return (BindValidationException) ex.getCause();
|
||||
Throwable cause = ex.getCause();
|
||||
assertThat(cause).isNotNull();
|
||||
return (BindValidationException) cause;
|
||||
}
|
||||
throw new IllegalStateException("Did not throw");
|
||||
}
|
||||
@@ -341,19 +344,20 @@ class ValidationBindHandlerTests {
|
||||
|
||||
static class ExampleNested {
|
||||
|
||||
private String name;
|
||||
private @Nullable String name;
|
||||
|
||||
@Min(5)
|
||||
private int age;
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private String address;
|
||||
|
||||
String getName() {
|
||||
@Nullable String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -423,13 +427,13 @@ class ValidationBindHandlerTests {
|
||||
|
||||
static class ExampleMapValue {
|
||||
|
||||
private String number;
|
||||
private @Nullable String number;
|
||||
|
||||
String getNumber() {
|
||||
@Nullable String getNumber() {
|
||||
return this.number;
|
||||
}
|
||||
|
||||
void setNumber(String number) {
|
||||
void setNumber(@Nullable String number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
@@ -437,14 +441,14 @@ class ValidationBindHandlerTests {
|
||||
|
||||
static class TestHandler extends AbstractBindHandler {
|
||||
|
||||
private final Object result;
|
||||
private final @Nullable Object result;
|
||||
|
||||
TestHandler(Object result) {
|
||||
TestHandler(@Nullable Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target, BindContext context,
|
||||
public @Nullable Object onFailure(ConfigurationPropertyName name, Bindable<?> target, BindContext context,
|
||||
Exception error) throws Exception {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
+3
@@ -45,6 +45,7 @@ class ValidationErrorsTests {
|
||||
private static final ConfigurationPropertyName NAME = ConfigurationPropertyName.of("foo");
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenNameIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ValidationErrors(null, Collections.emptySet(), Collections.emptyList()))
|
||||
@@ -52,12 +53,14 @@ class ValidationErrorsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenBoundPropertiesIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ValidationErrors(NAME, null, Collections.emptyList()))
|
||||
.withMessageContaining("'boundProperties' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenErrorsIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ValidationErrors(NAME, Collections.emptySet(), null))
|
||||
.withMessageContaining("'errors' must not be null");
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package org.springframework.boot.context.properties.source;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -98,7 +99,7 @@ class AliasedConfigurationPropertySourceTests {
|
||||
.isEqualTo(ConfigurationPropertyState.PRESENT);
|
||||
}
|
||||
|
||||
private Object getValue(ConfigurationPropertySource source, String name) {
|
||||
private @Nullable Object getValue(ConfigurationPropertySource source, String name) {
|
||||
ConfigurationProperty property = source.getConfigurationProperty(ConfigurationPropertyName.of(name));
|
||||
return (property != null) ? property.getValue() : null;
|
||||
}
|
||||
|
||||
+1
@@ -61,6 +61,7 @@ class ConfigurationPropertyCachingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void getFromSourcesWhenSourcesIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> ConfigurationPropertyCaching.get((Iterable<ConfigurationPropertySource>) null))
|
||||
|
||||
+1
@@ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class ConfigurationPropertyNameAliasesTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWithStringWhenNullNameShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigurationPropertyNameAliases((String) null))
|
||||
.withMessageContaining("'name' must not be null");
|
||||
|
||||
+2
@@ -40,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class ConfigurationPropertyNameTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void ofNameShouldNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ConfigurationPropertyName.of(null))
|
||||
.withMessageContaining("'name' must not be null");
|
||||
@@ -231,6 +232,7 @@ class ConfigurationPropertyNameTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void adaptWhenNameIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ConfigurationPropertyName.adapt(null, '.'))
|
||||
.withMessageContaining("Name must not be null");
|
||||
|
||||
+4
-2
@@ -35,8 +35,10 @@ class ConfigurationPropertySourceTests {
|
||||
MockPropertySource source = new MockPropertySource();
|
||||
source.setProperty("spring", "boot");
|
||||
ConfigurationPropertySource adapted = ConfigurationPropertySource.from(source);
|
||||
assertThat(adapted.getConfigurationProperty(ConfigurationPropertyName.of("spring")).getValue())
|
||||
.isEqualTo("boot");
|
||||
assertThat(adapted).isNotNull();
|
||||
ConfigurationProperty spring = adapted.getConfigurationProperty(ConfigurationPropertyName.of("spring"));
|
||||
assertThat(spring).isNotNull();
|
||||
assertThat(spring.getValue()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -108,7 +109,7 @@ class ConfigurationPropertySourcesCachingTests {
|
||||
new ConfigurationPropertySourcesCaching(null).enable();
|
||||
}
|
||||
|
||||
private ConfigurationPropertyCaching getCaching(int index) {
|
||||
private @Nullable ConfigurationPropertyCaching getCaching(int index) {
|
||||
return CachingConfigurationPropertySource.find(this.sources.get(index));
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
@@ -165,7 +166,7 @@ class ConfigurationPropertySourcesPropertyResolverTests {
|
||||
private final Map<String, AtomicInteger> counts = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
public @Nullable Object getProperty(String name) {
|
||||
incrementCount(name);
|
||||
return super.getProperty(name);
|
||||
}
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -129,7 +130,7 @@ class ConfigurationPropertySourcesTests {
|
||||
sources.addFirst(new PropertySource<Environment>("env", environment) {
|
||||
|
||||
@Override
|
||||
public String getProperty(String key) {
|
||||
public @Nullable String getProperty(String key) {
|
||||
return this.source.getProperty(key);
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -33,12 +33,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class ConfigurationPropertyStateTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void searchWhenIterableIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ConfigurationPropertyState.search(null, (e) -> true))
|
||||
.withMessageContaining("'source' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void searchWhenPredicateIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> ConfigurationPropertyState.search(Collections.emptyList(), null))
|
||||
|
||||
+6
-1
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.context.properties.source;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.origin.Origin;
|
||||
@@ -36,15 +38,18 @@ class ConfigurationPropertyTests {
|
||||
|
||||
private static final ConfigurationPropertyName NAME = ConfigurationPropertyName.of("foo");
|
||||
|
||||
private final ConfigurationPropertySource source = ConfigurationPropertySource.from(mock(PropertySource.class));
|
||||
private final ConfigurationPropertySource source = Objects
|
||||
.requireNonNull(ConfigurationPropertySource.from(mock(PropertySource.class)));
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenNameIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigurationProperty(null, "bar", null))
|
||||
.withMessageContaining("'name' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenValueIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigurationProperty(NAME, null, null))
|
||||
.withMessageContaining("'value' must not be null");
|
||||
|
||||
+11
-3
@@ -32,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class FilteredConfigurationPropertiesSourceTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenSourceIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new FilteredConfigurationPropertiesSource(null, Objects::nonNull))
|
||||
@@ -39,6 +40,7 @@ class FilteredConfigurationPropertiesSourceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenFilterIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new FilteredConfigurationPropertiesSource(new MockConfigurationPropertySource(), null))
|
||||
@@ -50,10 +52,16 @@ class FilteredConfigurationPropertiesSourceTests {
|
||||
ConfigurationPropertySource source = createTestSource();
|
||||
ConfigurationPropertySource filtered = source.filter(this::noBrackets);
|
||||
ConfigurationPropertyName name = ConfigurationPropertyName.of("a");
|
||||
assertThat(source.getConfigurationProperty(name).getValue()).isEqualTo("1");
|
||||
assertThat(filtered.getConfigurationProperty(name).getValue()).isEqualTo("1");
|
||||
ConfigurationProperty configurationProperty = source.getConfigurationProperty(name);
|
||||
assertThat(configurationProperty).isNotNull();
|
||||
assertThat(configurationProperty.getValue()).isEqualTo("1");
|
||||
ConfigurationProperty configurationProperty2 = filtered.getConfigurationProperty(name);
|
||||
assertThat(configurationProperty2).isNotNull();
|
||||
assertThat(configurationProperty2.getValue()).isEqualTo("1");
|
||||
ConfigurationPropertyName bracketName = ConfigurationPropertyName.of("a[1]");
|
||||
assertThat(source.getConfigurationProperty(bracketName).getValue()).isEqualTo("2");
|
||||
ConfigurationProperty configurationProperty3 = source.getConfigurationProperty(bracketName);
|
||||
assertThat(configurationProperty3).isNotNull();
|
||||
assertThat(configurationProperty3.getValue()).isEqualTo("2");
|
||||
assertThat(filtered.getConfigurationProperty(bracketName)).isNull();
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -62,7 +62,9 @@ class FilteredIterableConfigurationPropertiesSourceTests extends FilteredConfigu
|
||||
IterableConfigurationPropertySource testSource = (IterableConfigurationPropertySource) createTestSource();
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
for (ConfigurationPropertyName name : testSource) {
|
||||
map.put(name.toString(), testSource.getConfigurationProperty(name).getValue());
|
||||
ConfigurationProperty configurationProperty = testSource.getConfigurationProperty(name);
|
||||
assertThat(configurationProperty).isNotNull();
|
||||
map.put(name.toString(), configurationProperty.getValue());
|
||||
}
|
||||
PropertySource<?> propertySource = new OriginTrackedMapPropertySource("test", map, true);
|
||||
SpringConfigurationPropertySource source = SpringConfigurationPropertySource.from(propertySource);
|
||||
@@ -79,7 +81,9 @@ class FilteredIterableConfigurationPropertiesSourceTests extends FilteredConfigu
|
||||
IterableConfigurationPropertySource testSource = (IterableConfigurationPropertySource) createTestSource();
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
for (ConfigurationPropertyName name : testSource) {
|
||||
map.put(name.toString(), testSource.getConfigurationProperty(name).getValue());
|
||||
ConfigurationProperty configurationProperty = testSource.getConfigurationProperty(name);
|
||||
assertThat(configurationProperty).isNotNull();
|
||||
map.put(name.toString(), configurationProperty.getValue());
|
||||
}
|
||||
PropertySource<?> propertySource = new OriginTrackedMapPropertySource("test", map, true);
|
||||
SpringConfigurationPropertySource source = SpringConfigurationPropertySource.from(propertySource);
|
||||
|
||||
+3
-1
@@ -19,6 +19,8 @@ package org.springframework.boot.context.properties.source;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class KnownAncestorsConfigurationPropertySource implements ConfigurationPropertySource {
|
||||
@@ -26,7 +28,7 @@ class KnownAncestorsConfigurationPropertySource implements ConfigurationProperty
|
||||
private final Map<ConfigurationPropertyName, ConfigurationPropertyState> ancestors = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) {
|
||||
public @Nullable ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -19,6 +19,7 @@ package org.springframework.boot.context.properties.source;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -33,6 +34,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class MapConfigurationPropertySourceTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenMapIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new MapConfigurationPropertySource(null))
|
||||
.withMessageContaining("'map' must not be null");
|
||||
@@ -49,6 +51,7 @@ class MapConfigurationPropertySourceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void putAllWhenMapIsNullShouldThrowException() {
|
||||
MapConfigurationPropertySource source = new MapConfigurationPropertySource();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> source.putAll(null))
|
||||
@@ -101,7 +104,7 @@ class MapConfigurationPropertySourceTests {
|
||||
|
||||
}
|
||||
|
||||
private Object getValue(ConfigurationPropertySource source, String name) {
|
||||
private @Nullable Object getValue(ConfigurationPropertySource source, String name) {
|
||||
ConfigurationProperty property = source.getConfigurationProperty(ConfigurationPropertyName.of(name));
|
||||
return (property != null) ? property.getValue() : null;
|
||||
}
|
||||
|
||||
+6
-4
@@ -21,6 +21,8 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.boot.origin.MockOrigin;
|
||||
import org.springframework.boot.origin.OriginTrackedValue;
|
||||
|
||||
@@ -41,7 +43,7 @@ public class MockConfigurationPropertySource implements IterableConfigurationPro
|
||||
this(configurationPropertyName, value, null);
|
||||
}
|
||||
|
||||
public MockConfigurationPropertySource(String configurationPropertyName, Object value, String origin) {
|
||||
public MockConfigurationPropertySource(String configurationPropertyName, Object value, @Nullable String origin) {
|
||||
put(ConfigurationPropertyName.of(configurationPropertyName),
|
||||
OriginTrackedValue.of(value, MockOrigin.of(origin)));
|
||||
}
|
||||
@@ -82,7 +84,7 @@ public class MockConfigurationPropertySource implements IterableConfigurationPro
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) {
|
||||
public @Nullable ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) {
|
||||
OriginTrackedValue result = this.map.get(name);
|
||||
if (result == null) {
|
||||
result = findValue(name);
|
||||
@@ -90,7 +92,7 @@ public class MockConfigurationPropertySource implements IterableConfigurationPro
|
||||
return ConfigurationProperty.of(name, result);
|
||||
}
|
||||
|
||||
private OriginTrackedValue findValue(ConfigurationPropertyName name) {
|
||||
private @Nullable OriginTrackedValue findValue(ConfigurationPropertyName name) {
|
||||
return this.map.get(name);
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ public class MockConfigurationPropertySource implements IterableConfigurationPro
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) {
|
||||
public @Nullable ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) {
|
||||
return MockConfigurationPropertySource.this.getConfigurationProperty(name);
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||
class MutuallyExclusiveConfigurationPropertiesExceptionTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenConfiguredNamesIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new MutuallyExclusiveConfigurationPropertiesException(null, Arrays.asList("a", "b")))
|
||||
@@ -50,6 +51,7 @@ class MutuallyExclusiveConfigurationPropertiesExceptionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenMutuallyExclusiveNamesIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new MutuallyExclusiveConfigurationPropertiesException(Arrays.asList("a", "b"), null))
|
||||
|
||||
+3
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot.context.properties.source;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -82,12 +83,12 @@ class PrefixedConfigurationPropertySourceTests {
|
||||
assertThat(prefixed).isSameAs(source);
|
||||
}
|
||||
|
||||
private ConfigurationPropertyName getName(ConfigurationPropertySource source, String name) {
|
||||
private @Nullable ConfigurationPropertyName getName(ConfigurationPropertySource source, String name) {
|
||||
ConfigurationProperty property = source.getConfigurationProperty(ConfigurationPropertyName.of(name));
|
||||
return (property != null) ? property.getName() : null;
|
||||
}
|
||||
|
||||
private Object getValue(ConfigurationPropertySource source, String name) {
|
||||
private @Nullable Object getValue(ConfigurationPropertySource source, String name) {
|
||||
ConfigurationProperty property = source.getConfigurationProperty(ConfigurationPropertyName.of(name));
|
||||
return (property != null) ? property.getValue() : null;
|
||||
}
|
||||
|
||||
+3
-2
@@ -22,6 +22,7 @@ import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyCaching.CacheOverride;
|
||||
@@ -186,14 +187,14 @@ class SoftReferenceConfigurationPropertyCacheTests {
|
||||
*/
|
||||
class TestSoftReferenceConfigurationPropertyCache extends SoftReferenceConfigurationPropertyCache<Value> {
|
||||
|
||||
private Value value;
|
||||
private @Nullable Value value;
|
||||
|
||||
TestSoftReferenceConfigurationPropertyCache(boolean neverExpire) {
|
||||
super(neverExpire);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValue() {
|
||||
protected @Nullable Value getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
|
||||
+13
-5
@@ -20,6 +20,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.env.RandomValuePropertySource;
|
||||
@@ -41,6 +42,7 @@ import static org.mockito.Mockito.mock;
|
||||
class SpringConfigurationPropertySourceTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void createWhenPropertySourceIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new SpringConfigurationPropertySource(null, false, mock(PropertyMapper.class)))
|
||||
@@ -59,7 +61,9 @@ class SpringConfigurationPropertySourceTests {
|
||||
mapper.addFromConfigurationProperty(name, "key2");
|
||||
SpringConfigurationPropertySource adapter = new SpringConfigurationPropertySource(propertySource, false,
|
||||
mapper);
|
||||
assertThat(adapter.getConfigurationProperty(name).getValue()).isEqualTo("value2");
|
||||
ConfigurationProperty configurationProperty = adapter.getConfigurationProperty(name);
|
||||
assertThat(configurationProperty).isNotNull();
|
||||
assertThat(configurationProperty.getValue()).isEqualTo("value2");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,6 +77,7 @@ class SpringConfigurationPropertySourceTests {
|
||||
SpringConfigurationPropertySource adapter = new SpringConfigurationPropertySource(propertySource, false,
|
||||
mapper);
|
||||
ConfigurationProperty configurationProperty = adapter.getConfigurationProperty(name);
|
||||
assertThat(configurationProperty).isNotNull();
|
||||
assertThat(configurationProperty.getOrigin()).hasToString("\"key\" from property source \"test\"");
|
||||
assertThat(configurationProperty.getSource()).isEqualTo(adapter);
|
||||
}
|
||||
@@ -87,7 +92,9 @@ class SpringConfigurationPropertySourceTests {
|
||||
mapper.addFromConfigurationProperty(name, "key");
|
||||
SpringConfigurationPropertySource adapter = new SpringConfigurationPropertySource(propertySource, false,
|
||||
mapper);
|
||||
assertThat(adapter.getConfigurationProperty(name).getOrigin()).hasToString("TestOrigin key");
|
||||
ConfigurationProperty configurationProperty = adapter.getConfigurationProperty(name);
|
||||
assertThat(configurationProperty).isNotNull();
|
||||
assertThat(configurationProperty.getOrigin()).hasToString("TestOrigin key");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,6 +109,7 @@ class SpringConfigurationPropertySourceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void fromWhenPropertySourceIsNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> SpringConfigurationPropertySource.from(null))
|
||||
.withMessageContaining("'source' must not be null");
|
||||
@@ -112,7 +120,7 @@ class SpringConfigurationPropertySourceTests {
|
||||
PropertySource<?> propertySource = new PropertySource<>("test", new Object()) {
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
public @Nullable Object getProperty(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -242,7 +250,7 @@ class SpringConfigurationPropertySourceTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
public @Nullable Object getProperty(String name) {
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
if (!name.startsWith(this.prefix)) {
|
||||
return null;
|
||||
@@ -267,7 +275,7 @@ class SpringConfigurationPropertySourceTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) {
|
||||
public @Nullable Object getProperty(String name) {
|
||||
return this.propertySource.getProperty(name);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user