mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-10-09 02:49:02 +00:00
Add nullability annotations to tests in module/spring-boot-devtools
See gh-47263
This commit is contained in:
+8
-3
@@ -25,6 +25,7 @@ import java.util.function.Supplier;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
@@ -35,6 +36,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.BDDMockito.willReturn;
|
||||
@@ -99,18 +101,21 @@ abstract class AbstractDevToolsDataSourceAutoConfigurationTests {
|
||||
});
|
||||
thread.start();
|
||||
thread.join();
|
||||
return atomicReference.get();
|
||||
ConfigurableApplicationContext context = atomicReference.get();
|
||||
assertThat(context).isNotNull();
|
||||
return context;
|
||||
}
|
||||
|
||||
protected final ConfigurableApplicationContext createContext(Class<?>... classes) {
|
||||
return createContext(null, classes);
|
||||
}
|
||||
|
||||
protected final ConfigurableApplicationContext createContext(String driverClassName, Class<?>... classes) {
|
||||
protected final ConfigurableApplicationContext createContext(@Nullable String driverClassName,
|
||||
Class<?>... classes) {
|
||||
return createContext(driverClassName, null, classes);
|
||||
}
|
||||
|
||||
protected final ConfigurableApplicationContext createContext(String driverClassName, String url,
|
||||
protected final ConfigurableApplicationContext createContext(@Nullable String driverClassName, @Nullable String url,
|
||||
Class<?>... classes) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(classes);
|
||||
|
||||
+5
-2
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.r2dbc.spi.ConnectionFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -125,14 +126,16 @@ class DevToolsR2dbcAutoConfigurationTests {
|
||||
});
|
||||
thread.start();
|
||||
thread.join();
|
||||
return atomicReference.get();
|
||||
ConfigurableApplicationContext context = atomicReference.get();
|
||||
assertThat(context).isNotNull();
|
||||
return context;
|
||||
}
|
||||
|
||||
protected final ConfigurableApplicationContext createContext(Class<?>... classes) {
|
||||
return createContext(null, classes);
|
||||
}
|
||||
|
||||
protected final ConfigurableApplicationContext createContext(String url, Class<?>... classes) {
|
||||
protected final ConfigurableApplicationContext createContext(@Nullable String url, Class<?>... classes) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
if (!ObjectUtils.isEmpty(classes)) {
|
||||
context.register(classes);
|
||||
|
||||
+18
-6
@@ -26,6 +26,7 @@ import java.util.function.Supplier;
|
||||
import org.apache.catalina.Container;
|
||||
import org.apache.catalina.core.StandardWrapper;
|
||||
import org.apache.jasper.EmbeddedServletOptions;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -74,7 +75,7 @@ import static org.mockito.Mockito.reset;
|
||||
@ExtendWith(MockRestarter.class)
|
||||
class LocalDevToolsAutoConfigurationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
private @Nullable ConfigurableApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
@@ -152,8 +153,10 @@ class LocalDevToolsAutoConfigurationTests {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("spring.devtools.livereload.enabled", false);
|
||||
this.context = getContext(() -> initializeAndRun(Config.class, properties));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean(OptionalLiveReloadServer.class));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() -> {
|
||||
assertThat(this.context).isNotNull();
|
||||
this.context.getBean(OptionalLiveReloadServer.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -184,8 +187,10 @@ class LocalDevToolsAutoConfigurationTests {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("spring.devtools.restart.enabled", false);
|
||||
this.context = getContext(() -> initializeAndRun(Config.class, properties));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean(ClassPathFileSystemWatcher.class));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() -> {
|
||||
assertThat(this.context).isNotNull();
|
||||
this.context.getBean(ClassPathFileSystemWatcher.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -195,7 +200,9 @@ class LocalDevToolsAutoConfigurationTests {
|
||||
this.context = getContext(() -> initializeAndRun(Config.class, properties));
|
||||
ClassPathFileSystemWatcher classPathWatcher = this.context.getBean(ClassPathFileSystemWatcher.class);
|
||||
Object watcher = ReflectionTestUtils.getField(classPathWatcher, "fileSystemWatcher");
|
||||
assertThat(watcher).isNotNull();
|
||||
Object filter = ReflectionTestUtils.getField(watcher, "triggerFilter");
|
||||
assertThat(filter).isNotNull();
|
||||
assertThat(filter).isInstanceOf(TriggerFileFilter.class);
|
||||
}
|
||||
|
||||
@@ -206,6 +213,7 @@ class LocalDevToolsAutoConfigurationTests {
|
||||
this.context = getContext(() -> initializeAndRun(Config.class, properties));
|
||||
ClassPathFileSystemWatcher classPathWatcher = this.context.getBean(ClassPathFileSystemWatcher.class);
|
||||
Object watcher = ReflectionTestUtils.getField(classPathWatcher, "fileSystemWatcher");
|
||||
assertThat(watcher).isNotNull();
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<File, Object> directories = (Map<File, Object>) ReflectionTestUtils.getField(watcher, "directories");
|
||||
assertThat(directories).hasSize(2)
|
||||
@@ -218,10 +226,12 @@ class LocalDevToolsAutoConfigurationTests {
|
||||
this.context = getContext(() -> initializeAndRun(Config.class));
|
||||
TomcatWebServer tomcatContainer = (TomcatWebServer) ((ServletWebServerApplicationContext) this.context)
|
||||
.getWebServer();
|
||||
assertThat(tomcatContainer).isNotNull();
|
||||
Container context = tomcatContainer.getTomcat().getHost().findChildren()[0];
|
||||
StandardWrapper jspServletWrapper = (StandardWrapper) context.findChild("jsp");
|
||||
EmbeddedServletOptions options = (EmbeddedServletOptions) ReflectionTestUtils
|
||||
.getField(jspServletWrapper.getServlet(), "options");
|
||||
assertThat(options).isNotNull();
|
||||
assertThat(options.getDevelopment()).isTrue();
|
||||
}
|
||||
|
||||
@@ -234,7 +244,9 @@ class LocalDevToolsAutoConfigurationTests {
|
||||
});
|
||||
thread.start();
|
||||
thread.join();
|
||||
return atomicReference.get();
|
||||
ConfigurableApplicationContext context = atomicReference.get();
|
||||
assertThat(context).isNotNull();
|
||||
return context;
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext initializeAndRun(Class<?> config, String... args) {
|
||||
|
||||
+14
-6
@@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -65,7 +66,7 @@ class RemoteDevToolsAutoConfigurationTests {
|
||||
|
||||
private static final String DEFAULT_SECRET_HEADER_NAME = RemoteDevToolsProperties.DEFAULT_SECRET_HEADER_NAME;
|
||||
|
||||
private AnnotationConfigServletWebApplicationContext context;
|
||||
private @Nullable AnnotationConfigServletWebApplicationContext context;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
@@ -90,8 +91,10 @@ class RemoteDevToolsAutoConfigurationTests {
|
||||
@Test
|
||||
void disabledIfRemoteSecretIsMissing() throws Exception {
|
||||
this.context = getContext(() -> loadContext("a:b"));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean(DispatcherFilter.class));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() -> {
|
||||
assertThat(this.context).isNotNull();
|
||||
this.context.getBean(DispatcherFilter.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -182,8 +185,10 @@ class RemoteDevToolsAutoConfigurationTests {
|
||||
void disableRestart() throws Exception {
|
||||
this.context = getContext(() -> loadContext("spring.devtools.remote.secret:supersecret",
|
||||
"spring.devtools.remote.restart.enabled:false"));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean("remoteRestartHandlerMapper"));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() -> {
|
||||
assertThat(this.context).isNotNull();
|
||||
this.context.getBean("remoteRestartHandlerMapper");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -218,10 +223,13 @@ class RemoteDevToolsAutoConfigurationTests {
|
||||
});
|
||||
thread.start();
|
||||
thread.join();
|
||||
return atomicReference.get();
|
||||
AnnotationConfigServletWebApplicationContext context = atomicReference.get();
|
||||
assertThat(context).isNotNull();
|
||||
return context;
|
||||
}
|
||||
|
||||
private void assertRestartInvoked(boolean value) {
|
||||
assertThat(this.context).isNotNull();
|
||||
assertThat(this.context.getBean(MockHttpRestartServer.class).invoked).isEqualTo(value);
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -32,9 +32,11 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class TriggerFileFilterTests {
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void nameMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new TriggerFileFilter(null))
|
||||
.withMessageContaining("'name' must not be null");
|
||||
|
||||
+1
@@ -36,6 +36,7 @@ class ClassPathChangedEventTests {
|
||||
private final Object source = new Object();
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void changeSetMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ClassPathChangedEvent(this.source, null, false))
|
||||
.withMessageContaining("'changeSet' must not be null");
|
||||
|
||||
+5
@@ -47,15 +47,19 @@ import static org.mockito.Mockito.never;
|
||||
class ClassPathFileChangeListenerTests {
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ClassPathRestartStrategy restartStrategy;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private FileSystemWatcher fileSystemWatcher;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void eventPublisherMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ClassPathFileChangeListener(null, this.restartStrategy, this.fileSystemWatcher))
|
||||
@@ -63,6 +67,7 @@ class ClassPathFileChangeListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void restartStrategyMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ClassPathFileChangeListener(this.eventPublisher, null, this.fileSystemWatcher))
|
||||
|
||||
+2
@@ -51,6 +51,7 @@ import static org.mockito.Mockito.mock;
|
||||
class ClassPathFileSystemWatcherTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void urlsMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ClassPathFileSystemWatcher(mock(FileSystemWatcherFactory.class),
|
||||
@@ -100,6 +101,7 @@ class ClassPathFileSystemWatcherTests {
|
||||
ClassPathFileSystemWatcher watcher(ClassPathRestartStrategy restartStrategy) {
|
||||
FileSystemWatcher watcher = new FileSystemWatcher(false, Duration.ofMillis(100), Duration.ofMillis(10));
|
||||
URL[] urls = this.environment.getProperty("urls", URL[].class);
|
||||
assertThat(urls).isNotNull();
|
||||
return new ClassPathFileSystemWatcher(new MockFileSystemWatcherFactory(watcher), restartStrategy, urls);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package org.springframework.boot.devtools.classpath;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.devtools.filewatch.ChangedFile;
|
||||
@@ -82,7 +83,7 @@ class PatternClassPathRestartStrategyTests {
|
||||
assertRestartRequired(strategy, "com/example/Example.class", true);
|
||||
}
|
||||
|
||||
private ClassPathRestartStrategy createStrategy(String pattern) {
|
||||
private ClassPathRestartStrategy createStrategy(@Nullable String pattern) {
|
||||
return new PatternClassPathRestartStrategy(pattern);
|
||||
}
|
||||
|
||||
|
||||
+9
-4
@@ -22,6 +22,7 @@ import java.util.Locale;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -48,7 +49,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
*/
|
||||
class DevToolPropertiesIntegrationTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
private @Nullable ConfigurableApplicationContext context;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
@@ -86,8 +87,10 @@ class DevToolPropertiesIntegrationTests {
|
||||
SpringApplication application = new SpringApplication(BeanConditionConfiguration.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
this.context = getContext(application::run);
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean(MyBean.class));
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class).isThrownBy(() -> {
|
||||
assertThat(this.context).isNotNull();
|
||||
this.context.getBean(MyBean.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -124,7 +127,9 @@ class DevToolPropertiesIntegrationTests {
|
||||
});
|
||||
thread.start();
|
||||
thread.join();
|
||||
return atomicReference.get();
|
||||
ConfigurableApplicationContext context = atomicReference.get();
|
||||
assertThat(context).isNotNull();
|
||||
return context;
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
|
||||
+5
-3
@@ -25,10 +25,12 @@ import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
@@ -201,8 +203,8 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
return getPostProcessedEnvironment(env, null);
|
||||
}
|
||||
|
||||
private ConfigurableEnvironment getPostProcessedEnvironment(Map<String, String> env, Properties systemProperties)
|
||||
throws Exception {
|
||||
private ConfigurableEnvironment getPostProcessedEnvironment(@Nullable Map<String, String> env,
|
||||
@Nullable Properties systemProperties) throws Exception {
|
||||
if (systemProperties == null) {
|
||||
systemProperties = new Properties();
|
||||
systemProperties.setProperty("user.home", this.home.getAbsolutePath());
|
||||
@@ -210,7 +212,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
ConfigurableEnvironment environment = new MockEnvironment();
|
||||
DevToolsHomePropertiesPostProcessor postProcessor = new DevToolsHomePropertiesPostProcessor(
|
||||
(env != null) ? env : Collections.emptyMap(), systemProperties);
|
||||
runPostProcessor(() -> postProcessor.postProcessEnvironment(environment, null));
|
||||
runPostProcessor(() -> postProcessor.postProcessEnvironment(environment, new SpringApplication()));
|
||||
return environment;
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -34,9 +34,11 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class ChangedFileTests {
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void sourceDirectoryMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ChangedFile(null, new File(this.tempDir, "file"), Type.ADD))
|
||||
@@ -44,6 +46,7 @@ class ChangedFileTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void fileMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ChangedFile(new File(this.tempDir, "directory"), null, Type.ADD))
|
||||
@@ -51,6 +54,7 @@ class ChangedFileTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void typeMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(
|
||||
|
||||
+4
-1
@@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class DirectorySnapshotTests {
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File tempDir;
|
||||
|
||||
private File directory;
|
||||
@@ -51,6 +52,7 @@ class DirectorySnapshotTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void directoryMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DirectorySnapshot(null))
|
||||
.withMessageContaining("'directory' must not be null");
|
||||
@@ -101,6 +103,7 @@ class DirectorySnapshotTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void getChangedFilesSnapshotMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.initialSnapshot.getChangedFiles(null, null))
|
||||
.withMessageContaining("'snapshot' must not be null");
|
||||
@@ -142,7 +145,7 @@ class DirectorySnapshotTests {
|
||||
return changedFile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new AssertionError("File '%s' not found".formatted(file));
|
||||
}
|
||||
|
||||
private File createTestDirectoryStructure() throws IOException {
|
||||
|
||||
+2
@@ -42,9 +42,11 @@ class FileSnapshotTests {
|
||||
private static final long MODIFIED = new Date().getTime() - TimeUnit.DAYS.toMillis(10);
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void fileMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new FileSnapshot(null))
|
||||
.withMessageContaining("'file' must not be null");
|
||||
|
||||
+19
-13
@@ -28,6 +28,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -53,11 +54,12 @@ class FileSystemWatcherTests {
|
||||
private final List<Set<ChangedFiles>> changes = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File tempDir;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
setupWatcher(20, 10);
|
||||
this.watcher = setupWatcher(20, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,6 +84,7 @@ class FileSystemWatcherTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void listenerMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.watcher.addListener(null))
|
||||
.withMessageContaining("'fileChangeListener' must not be null");
|
||||
@@ -95,6 +98,7 @@ class FileSystemWatcherTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void sourceDirectoryMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.watcher.addSourceDirectory(null))
|
||||
.withMessageContaining("'directory' must not be null");
|
||||
@@ -149,7 +153,7 @@ class FileSystemWatcherTests {
|
||||
|
||||
@Test
|
||||
void waitsForPollingInterval() throws Exception {
|
||||
setupWatcher(10, 1);
|
||||
this.watcher = setupWatcher(10, 1);
|
||||
File directory = startWithNewDirectory();
|
||||
touch(new File(directory, "test1.txt"));
|
||||
while (this.changes.size() != 1) {
|
||||
@@ -162,7 +166,7 @@ class FileSystemWatcherTests {
|
||||
|
||||
@Test
|
||||
void waitsForQuietPeriod() throws Exception {
|
||||
setupWatcher(300, 200);
|
||||
this.watcher = setupWatcher(300, 200);
|
||||
File directory = startWithNewDirectory();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
touch(new File(directory, i + "test.txt"));
|
||||
@@ -270,7 +274,7 @@ class FileSystemWatcherTests {
|
||||
@Test
|
||||
void withSnapshotRepository() throws Exception {
|
||||
SnapshotStateRepository repository = new TestSnapshotStateRepository();
|
||||
setupWatcher(20, 10, repository);
|
||||
this.watcher = setupWatcher(20, 10, repository);
|
||||
File directory = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
directory.mkdir();
|
||||
File file = touch(new File(directory, "file.txt"));
|
||||
@@ -280,7 +284,7 @@ class FileSystemWatcherTests {
|
||||
this.watcher.stopAfter(1);
|
||||
this.changes.clear();
|
||||
File recreate = touch(new File(directory, "file.txt"));
|
||||
setupWatcher(20, 10, repository);
|
||||
this.watcher = setupWatcher(20, 10, repository);
|
||||
this.watcher.addSourceDirectory(directory);
|
||||
this.watcher.start();
|
||||
this.watcher.stopAfter(1);
|
||||
@@ -290,14 +294,16 @@ class FileSystemWatcherTests {
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
private void setupWatcher(long pollingInterval, long quietPeriod) {
|
||||
setupWatcher(pollingInterval, quietPeriod, null);
|
||||
private FileSystemWatcher setupWatcher(long pollingInterval, long quietPeriod) {
|
||||
return setupWatcher(pollingInterval, quietPeriod, null);
|
||||
}
|
||||
|
||||
private void setupWatcher(long pollingInterval, long quietPeriod, SnapshotStateRepository snapshotStateRepository) {
|
||||
this.watcher = new FileSystemWatcher(false, Duration.ofMillis(pollingInterval), Duration.ofMillis(quietPeriod),
|
||||
snapshotStateRepository);
|
||||
this.watcher.addListener(FileSystemWatcherTests.this.changes::add);
|
||||
private FileSystemWatcher setupWatcher(long pollingInterval, long quietPeriod,
|
||||
@Nullable SnapshotStateRepository snapshotStateRepository) {
|
||||
FileSystemWatcher watcher = new FileSystemWatcher(false, Duration.ofMillis(pollingInterval),
|
||||
Duration.ofMillis(quietPeriod), snapshotStateRepository);
|
||||
watcher.addListener(FileSystemWatcherTests.this.changes::add);
|
||||
return watcher;
|
||||
}
|
||||
|
||||
private File startWithNewDirectory() {
|
||||
@@ -328,7 +334,7 @@ class FileSystemWatcherTests {
|
||||
|
||||
private static final class TestSnapshotStateRepository implements SnapshotStateRepository {
|
||||
|
||||
private Object state;
|
||||
private @Nullable Object state;
|
||||
|
||||
@Override
|
||||
public void save(Object state) {
|
||||
@@ -336,7 +342,7 @@ class FileSystemWatcherTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object restore() {
|
||||
public @Nullable Object restore() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -34,12 +34,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
class FrameTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void payloadMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new Frame((String) null))
|
||||
.withMessageContaining("'payload' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void typeMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new Frame((Frame.Type) null))
|
||||
.withMessageContaining("'type' must not be null");
|
||||
|
||||
+14
-6
@@ -47,11 +47,13 @@ import jakarta.websocket.HandshakeResponse;
|
||||
import jakarta.websocket.WebSocketContainer;
|
||||
import org.apache.tomcat.websocket.WsWebSocketContainer;
|
||||
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.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
@@ -223,7 +225,7 @@ class LiveReloadServerTests {
|
||||
|
||||
class LiveReloadWebSocketHandler extends TextWebSocketHandler {
|
||||
|
||||
private volatile WebSocketSession session;
|
||||
private volatile @Nullable WebSocketSession session;
|
||||
|
||||
private final CountDownLatch helloLatch = new CountDownLatch(2);
|
||||
|
||||
@@ -231,7 +233,7 @@ class LiveReloadServerTests {
|
||||
|
||||
private final AtomicInteger pongCount = new AtomicInteger();
|
||||
|
||||
private volatile CloseStatus closeStatus;
|
||||
private volatile @Nullable CloseStatus closeStatus;
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
@@ -264,11 +266,15 @@ class LiveReloadServerTests {
|
||||
}
|
||||
|
||||
void sendMessage(WebSocketMessage<?> message) throws IOException {
|
||||
this.session.sendMessage(message);
|
||||
WebSocketSession session = this.session;
|
||||
assertThat(session).isNotNull();
|
||||
session.sendMessage(message);
|
||||
}
|
||||
|
||||
void close() throws IOException {
|
||||
this.session.close();
|
||||
WebSocketSession session = this.session;
|
||||
assertThat(session).isNotNull();
|
||||
session.close();
|
||||
}
|
||||
|
||||
List<String> getMessages() {
|
||||
@@ -279,7 +285,7 @@ class LiveReloadServerTests {
|
||||
return this.pongCount.get();
|
||||
}
|
||||
|
||||
CloseStatus getCloseStatus() {
|
||||
@Nullable CloseStatus getCloseStatus() {
|
||||
return this.closeStatus;
|
||||
}
|
||||
|
||||
@@ -314,7 +320,9 @@ class LiveReloadServerTests {
|
||||
this.webSocketContainer.connectToServer(endpoint, endpointConfig, uri);
|
||||
return session;
|
||||
};
|
||||
return getTaskExecutor().submitCompletable(connectTask);
|
||||
AsyncTaskExecutor taskExecutor = getTaskExecutor();
|
||||
assertThat(taskExecutor).isNotNull();
|
||||
return taskExecutor.submitCompletable(connectTask);
|
||||
}
|
||||
|
||||
private InetAddress getLocalHost() {
|
||||
|
||||
+4
-1
@@ -26,6 +26,7 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -65,6 +66,7 @@ class ClassPathChangeUploaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void urlMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ClassPathChangeUploader(null, this.requestFactory))
|
||||
.withMessageContaining("'url' must not be empty");
|
||||
@@ -77,6 +79,7 @@ class ClassPathChangeUploaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void requestFactoryMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ClassPathChangeUploader("http://localhost:8080", null))
|
||||
@@ -124,7 +127,7 @@ class ClassPathChangeUploaderTests {
|
||||
assertThat(classFiles.hasNext()).isFalse();
|
||||
}
|
||||
|
||||
private void assertClassFile(ClassLoaderFile file, String content, Kind kind) {
|
||||
private void assertClassFile(ClassLoaderFile file, @Nullable String content, Kind kind) {
|
||||
assertThat(file.getContents()).isEqualTo((content != null) ? content.getBytes() : null);
|
||||
assertThat(file.getKind()).isEqualTo(kind);
|
||||
}
|
||||
|
||||
+9
@@ -49,21 +49,27 @@ class DelayedLiveReloadTriggerTests {
|
||||
private static final String URL = "http://localhost:8080";
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private OptionalLiveReloadServer liveReloadServer;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ClientHttpRequestFactory requestFactory;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ClientHttpRequest errorRequest;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ClientHttpRequest okRequest;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ClientHttpResponse errorResponse;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ClientHttpResponse okResponse;
|
||||
|
||||
private DelayedLiveReloadTrigger trigger;
|
||||
@@ -74,6 +80,7 @@ class DelayedLiveReloadTriggerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void liveReloadServerMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new DelayedLiveReloadTrigger(null, this.requestFactory, URL))
|
||||
@@ -81,6 +88,7 @@ class DelayedLiveReloadTriggerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void requestFactoryMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new DelayedLiveReloadTrigger(this.liveReloadServer, null, URL))
|
||||
@@ -88,6 +96,7 @@ class DelayedLiveReloadTriggerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void urlMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new DelayedLiveReloadTrigger(this.liveReloadServer, this.requestFactory, null))
|
||||
|
||||
+4
@@ -54,9 +54,11 @@ class HttpHeaderInterceptorTests {
|
||||
private byte[] body;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ClientHttpRequestExecution execution;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private ClientHttpResponse response;
|
||||
|
||||
private MockHttpServletRequest httpRequest;
|
||||
@@ -72,6 +74,7 @@ class HttpHeaderInterceptorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void constructorNullHeaderName() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpHeaderInterceptor(null, this.value))
|
||||
.withMessageContaining("'name' must not be empty");
|
||||
@@ -84,6 +87,7 @@ class HttpHeaderInterceptorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void constructorNullHeaderValue() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpHeaderInterceptor(this.name, null))
|
||||
.withMessageContaining("'value' must not be empty");
|
||||
|
||||
+16
-5
@@ -22,6 +22,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -41,6 +42,7 @@ import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServer;
|
||||
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -63,9 +65,9 @@ import static org.mockito.Mockito.mock;
|
||||
@ExtendWith({ OutputCaptureExtension.class, MockRestarter.class })
|
||||
class RemoteClientConfigurationTests {
|
||||
|
||||
private AnnotationConfigServletWebServerApplicationContext context;
|
||||
private @Nullable AnnotationConfigServletWebServerApplicationContext context;
|
||||
|
||||
private AnnotationConfigApplicationContext clientContext;
|
||||
private @Nullable AnnotationConfigApplicationContext clientContext;
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
@@ -106,6 +108,7 @@ class RemoteClientConfigurationTests {
|
||||
configure();
|
||||
Set<ChangedFiles> changeSet = new HashSet<>();
|
||||
ClassPathChangedEvent event = new ClassPathChangedEvent(this, changeSet, false);
|
||||
assertThat(this.clientContext).isNotNull();
|
||||
this.clientContext.publishEvent(event);
|
||||
LiveReloadServer server = this.clientContext.getBean(LiveReloadServer.class);
|
||||
Awaitility.await().atMost(Duration.ofMinutes(1)).untilAsserted(() -> then(server).should().triggerReload());
|
||||
@@ -115,20 +118,26 @@ class RemoteClientConfigurationTests {
|
||||
void liveReloadDisabled() {
|
||||
configure("spring.devtools.livereload.enabled:false");
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean(OptionalLiveReloadServer.class));
|
||||
.isThrownBy(() -> getContext().getBean(OptionalLiveReloadServer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void remoteRestartDisabled() {
|
||||
configure("spring.devtools.remote.restart.enabled:false");
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.context.getBean(ClassPathFileSystemWatcher.class));
|
||||
.isThrownBy(() -> getContext().getBean(ClassPathFileSystemWatcher.class));
|
||||
}
|
||||
|
||||
private void configure(String... pairs) {
|
||||
configure("http://localhost", true, pairs);
|
||||
}
|
||||
|
||||
private AnnotationConfigServletWebServerApplicationContext getContext() {
|
||||
AnnotationConfigServletWebServerApplicationContext context = this.context;
|
||||
assertThat(context).isNotNull();
|
||||
return context;
|
||||
}
|
||||
|
||||
private void configure(String remoteUrl, boolean setSecret, String... pairs) {
|
||||
this.context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
this.context.register(Config.class);
|
||||
@@ -143,7 +152,9 @@ class RemoteClientConfigurationTests {
|
||||
if (setSecret) {
|
||||
TestPropertyValues.of("spring.devtools.remote.secret:secret").applyTo(this.clientContext);
|
||||
}
|
||||
String remoteUrlProperty = "remoteUrl:" + remoteUrl + ":" + this.context.getWebServer().getPort();
|
||||
WebServer webServer = this.context.getWebServer();
|
||||
assertThat(webServer).isNotNull();
|
||||
String remoteUrlProperty = "remoteUrl:" + remoteUrl + ":" + webServer.getPort();
|
||||
TestPropertyValues.of(remoteUrlProperty).applyTo(this.clientContext);
|
||||
this.clientContext.refresh();
|
||||
}
|
||||
|
||||
+3
@@ -51,9 +51,11 @@ import static org.mockito.Mockito.mock;
|
||||
class DispatcherFilterTests {
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private Dispatcher dispatcher;
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private FilterChain chain;
|
||||
|
||||
private DispatcherFilter filter;
|
||||
@@ -64,6 +66,7 @@ class DispatcherFilterTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void dispatcherMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DispatcherFilter(null))
|
||||
.withMessageContaining("'dispatcher' must not be null");
|
||||
|
||||
+3
@@ -52,6 +52,7 @@ import static org.mockito.Mockito.withSettings;
|
||||
class DispatcherTests {
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private AccessManager accessManager;
|
||||
|
||||
private final MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
@@ -61,12 +62,14 @@ class DispatcherTests {
|
||||
private final ServerHttpResponse serverResponse = new ServletServerHttpResponse(this.response);
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void accessManagerMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new Dispatcher(null, Collections.emptyList()))
|
||||
.withMessageContaining("'accessManager' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void mappersMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new Dispatcher(this.accessManager, null))
|
||||
.withMessageContaining("'mappers' must not be null");
|
||||
|
||||
+2
@@ -52,6 +52,7 @@ class HttpHeaderAccessManagerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void headerNameMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpHeaderAccessManager(null, SECRET))
|
||||
.withMessageContaining("'headerName' must not be empty");
|
||||
@@ -64,6 +65,7 @@ class HttpHeaderAccessManagerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void expectedSecretMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpHeaderAccessManager(HEADER, null))
|
||||
.withMessageContaining("'expectedSecret' must not be empty");
|
||||
|
||||
+1
@@ -54,6 +54,7 @@ class HttpStatusHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void statusMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpStatusHandler(null))
|
||||
.withMessageContaining("'status' must not be null");
|
||||
|
||||
+1
@@ -38,6 +38,7 @@ class UrlHandlerMapperTests {
|
||||
private final Handler handler = mock(Handler.class);
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void requestUriMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new UrlHandlerMapper(null, this.handler))
|
||||
.withMessageContaining("'url' must not be empty");
|
||||
|
||||
+1
@@ -43,6 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class ChangeableUrlsTests {
|
||||
|
||||
@TempDir
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
|
||||
+7
-3
@@ -18,6 +18,7 @@ package org.springframework.boot.devtools.restart;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -45,6 +46,7 @@ class MainMethodTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void threadMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new MainMethod(null))
|
||||
.withMessageContaining("'thread' must not be null");
|
||||
@@ -90,9 +92,9 @@ class MainMethodTests {
|
||||
|
||||
private final Runnable runnable;
|
||||
|
||||
private Exception exception;
|
||||
private @Nullable Exception exception;
|
||||
|
||||
private MainMethod mainMethod;
|
||||
private @Nullable MainMethod mainMethod;
|
||||
|
||||
TestThread(Runnable runnable) {
|
||||
this.runnable = runnable;
|
||||
@@ -104,7 +106,9 @@ class MainMethodTests {
|
||||
if (this.exception != null) {
|
||||
ReflectionUtils.rethrowRuntimeException(this.exception);
|
||||
}
|
||||
return this.mainMethod;
|
||||
MainMethod mainMethod = this.mainMethod;
|
||||
assertThat(mainMethod).isNotNull();
|
||||
return mainMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-2
@@ -18,6 +18,7 @@ package org.springframework.boot.devtools.restart;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
@@ -37,9 +38,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
class RestartScopeInitializerTests {
|
||||
|
||||
private static AtomicInteger createCount;
|
||||
private static @Nullable AtomicInteger createCount;
|
||||
|
||||
private static AtomicInteger refreshCount;
|
||||
private static @Nullable AtomicInteger refreshCount;
|
||||
|
||||
@Test
|
||||
void restartScope() {
|
||||
@@ -73,11 +74,13 @@ class RestartScopeInitializerTests {
|
||||
static class ScopeTestBean implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
ScopeTestBean() {
|
||||
assertThat(createCount).isNotNull();
|
||||
createCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
assertThat(refreshCount).isNotNull();
|
||||
refreshCount.incrementAndGet();
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
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;
|
||||
@@ -111,6 +112,7 @@ class RestarterTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void addUrlsMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Restarter.getInstance().addUrls(null))
|
||||
.withMessageContaining("'urls' must not be null");
|
||||
@@ -124,10 +126,12 @@ class RestarterTests {
|
||||
restarter.addUrls(urls);
|
||||
restarter.restart();
|
||||
ClassLoader classLoader = ((TestableRestarter) restarter).getRelaunchClassLoader();
|
||||
assertThat(classLoader).isNotNull();
|
||||
assertThat(((URLClassLoader) classLoader).getURLs()[0]).isEqualTo(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void addClassLoaderFilesMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Restarter.getInstance().addClassLoaderFiles(null))
|
||||
.withMessageContaining("'classLoaderFiles' must not be null");
|
||||
@@ -141,6 +145,7 @@ class RestarterTests {
|
||||
restarter.addClassLoaderFiles(classLoaderFiles);
|
||||
restarter.restart();
|
||||
ClassLoader classLoader = ((TestableRestarter) restarter).getRelaunchClassLoader();
|
||||
assertThat(classLoader).isNotNull();
|
||||
assertThat(classLoader.getResourceAsStream("f")).hasContent("abc");
|
||||
}
|
||||
|
||||
@@ -239,7 +244,7 @@ class RestarterTests {
|
||||
|
||||
static class TestableRestarter extends Restarter {
|
||||
|
||||
private ClassLoader relaunchClassLoader;
|
||||
private @Nullable ClassLoader relaunchClassLoader;
|
||||
|
||||
TestableRestarter() {
|
||||
this(Thread.currentThread(), new String[] {}, false, new MockRestartInitializer());
|
||||
@@ -262,7 +267,7 @@ class RestarterTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Throwable relaunch(ClassLoader classLoader) {
|
||||
protected @Nullable Throwable relaunch(ClassLoader classLoader) {
|
||||
this.relaunchClassLoader = classLoader;
|
||||
return null;
|
||||
}
|
||||
@@ -271,7 +276,7 @@ class RestarterTests {
|
||||
protected void stop() {
|
||||
}
|
||||
|
||||
ClassLoader getRelaunchClassLoader() {
|
||||
@Nullable ClassLoader getRelaunchClassLoader() {
|
||||
return this.relaunchClassLoader;
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -18,6 +18,7 @@ package org.springframework.boot.devtools.restart;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -55,7 +56,9 @@ class SilentExitExceptionHandlerTests {
|
||||
};
|
||||
SilentExitExceptionHandler.setup(testThread);
|
||||
testThread.startAndJoin();
|
||||
assertThat(testThread.getThrown().getMessage()).isEqualTo("Expected");
|
||||
Throwable thrown = testThread.getThrown();
|
||||
assertThat(thrown).isNotNull();
|
||||
assertThat(thrown.getMessage()).isEqualTo("Expected");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -78,13 +81,13 @@ class SilentExitExceptionHandlerTests {
|
||||
|
||||
static class TestThread extends Thread {
|
||||
|
||||
private Throwable thrown;
|
||||
private @Nullable Throwable thrown;
|
||||
|
||||
TestThread() {
|
||||
setUncaughtExceptionHandler((thread, exception) -> TestThread.this.thrown = exception);
|
||||
}
|
||||
|
||||
Throwable getThrown() {
|
||||
@Nullable Throwable getThrown() {
|
||||
return this.thrown;
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -33,24 +33,28 @@ class ClassLoaderFileTests {
|
||||
public static final byte[] BYTES = "ABC".getBytes();
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void kindMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ClassLoaderFile(null, null))
|
||||
.withMessageContaining("'kind' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void addedContentsMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ClassLoaderFile(Kind.ADDED, null))
|
||||
.withMessageContaining("'contents' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void modifiedContentsMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ClassLoaderFile(Kind.MODIFIED, null))
|
||||
.withMessageContaining("'contents' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void deletedContentsMustBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ClassLoaderFile(Kind.DELETED, new byte[10]))
|
||||
.withMessageContaining("'contents' must be null");
|
||||
|
||||
+3
@@ -41,12 +41,14 @@ class ClassLoaderFilesTests {
|
||||
private final ClassLoaderFiles files = new ClassLoaderFiles();
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void addFileNameMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.files.addFile(null, mock(ClassLoaderFile.class)))
|
||||
.withMessageContaining("'name' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void addFileFileMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.files.addFile("test", null))
|
||||
.withMessageContaining("'file' must not be null");
|
||||
@@ -151,6 +153,7 @@ class ClassLoaderFilesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void classLoaderFilesMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ClassLoaderFiles(null))
|
||||
.withMessageContaining("'classLoaderFiles' must not be null");
|
||||
|
||||
+3
@@ -102,12 +102,14 @@ class RestartClassLoaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void parentMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RestartClassLoader(null, new URL[] {}))
|
||||
.withMessageContaining("'parent' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void updatedFilesMustNotBeNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new RestartClassLoader(this.parentClassLoader, new URL[] {}, null))
|
||||
@@ -164,6 +166,7 @@ class RestartClassLoaderTests {
|
||||
byte[] bytes = "abc".getBytes();
|
||||
this.updatedFiles.addFile(name, new ClassLoaderFile(Kind.MODIFIED, bytes));
|
||||
URL resource = this.reloadClassLoader.getResource(name);
|
||||
assertThat(resource).isNotNull();
|
||||
assertThat(FileCopyUtils.copyToByteArray(resource.openStream())).isEqualTo(bytes);
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.mock;
|
||||
class HttpRestartServerHandlerTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void serverMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpRestartServerHandler(null))
|
||||
.withMessageContaining("'server' must not be null");
|
||||
|
||||
+3
@@ -48,6 +48,7 @@ import static org.mockito.BDDMockito.then;
|
||||
class HttpRestartServerTests {
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("NullAway.Init")
|
||||
private RestartServer delegate;
|
||||
|
||||
private HttpRestartServer server;
|
||||
@@ -58,12 +59,14 @@ class HttpRestartServerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void sourceDirectoryUrlFilterMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpRestartServer((SourceDirectoryUrlFilter) null))
|
||||
.withMessageContaining("'sourceDirectoryUrlFilter' must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void restartServerMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpRestartServer((RestartServer) null))
|
||||
.withMessageContaining("'restartServer' must not be null");
|
||||
|
||||
+4
-2
@@ -24,6 +24,7 @@ import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
@@ -43,6 +44,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class RestartServerTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("NullAway") // Test null check
|
||||
void sourceDirectoryUrlFilterMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RestartServer((SourceDirectoryUrlFilter) null))
|
||||
.withMessageContaining("'sourceDirectoryUrlFilter' must not be null");
|
||||
@@ -110,9 +112,9 @@ class RestartServerTests {
|
||||
super(sourceDirectoryUrlFilter, classLoader);
|
||||
}
|
||||
|
||||
private Set<URL> restartUrls;
|
||||
private @Nullable Set<URL> restartUrls;
|
||||
|
||||
private ClassLoaderFiles restartFiles;
|
||||
private @Nullable ClassLoaderFiles restartFiles;
|
||||
|
||||
@Override
|
||||
protected void restart(Set<URL> urls, ClassLoaderFiles files) {
|
||||
|
||||
Reference in New Issue
Block a user