diff --git a/gradle/plugins/common/src/main/kotlin/junitbuild.java-nullability-conventions.gradle.kts b/gradle/plugins/common/src/main/kotlin/junitbuild.java-nullability-conventions.gradle.kts index 75f0c6e70ab5..e07c8ca8297c 100644 --- a/gradle/plugins/common/src/main/kotlin/junitbuild.java-nullability-conventions.gradle.kts +++ b/gradle/plugins/common/src/main/kotlin/junitbuild.java-nullability-conventions.gradle.kts @@ -22,6 +22,7 @@ tasks.withType().configureEach { disableAllChecks = true nullaway { enable() + isJSpecifyMode = true } } } diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/InvocationInterceptor.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/InvocationInterceptor.java index 89ee85a7735d..013ed0668b0b 100644 --- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/InvocationInterceptor.java +++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/InvocationInterceptor.java @@ -78,7 +78,7 @@ public interface InvocationInterceptor extends TestInstantiationAwareExtension { * @return the result of the invocation; never {@code null} * @throws Throwable in case of failure */ - default T interceptTestClassConstructor(Invocation invocation, + default @Nullable T interceptTestClassConstructor(Invocation invocation, ReflectiveInvocationContext> invocationContext, ExtensionContext extensionContext) throws Throwable { return invocation.proceed(); @@ -94,7 +94,7 @@ default T interceptTestClassConstructor(Invocation invocation, * @param extensionContext the current extension context; never {@code null} * @throws Throwable in case of failures */ - default void interceptBeforeAllMethod(Invocation<@Nullable Void> invocation, + default void interceptBeforeAllMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { invocation.proceed(); } @@ -109,7 +109,7 @@ default void interceptBeforeAllMethod(Invocation<@Nullable Void> invocation, * @param extensionContext the current extension context; never {@code null} * @throws Throwable in case of failures */ - default void interceptBeforeEachMethod(Invocation<@Nullable Void> invocation, + default void interceptBeforeEachMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { invocation.proceed(); } @@ -124,8 +124,8 @@ default void interceptBeforeEachMethod(Invocation<@Nullable Void> invocation, * @param extensionContext the current extension context; never {@code null} * @throws Throwable in case of failures */ - default void interceptTestMethod(Invocation<@Nullable Void> invocation, - ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { + default void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, + ExtensionContext extensionContext) throws Throwable { invocation.proceed(); } @@ -143,7 +143,7 @@ default void interceptTestMethod(Invocation<@Nullable Void> invocation, * @return the result of the invocation; potentially {@code null} * @throws Throwable in case of failures */ - default T interceptTestFactoryMethod(Invocation invocation, + default @Nullable T interceptTestFactoryMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { return invocation.proceed(); } @@ -158,7 +158,7 @@ default void interceptTestMethod(Invocation<@Nullable Void> invocation, * @param extensionContext the current extension context; never {@code null} * @throws Throwable in case of failures */ - default void interceptTestTemplateMethod(Invocation<@Nullable Void> invocation, + default void interceptTestTemplateMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { invocation.proceed(); } @@ -174,8 +174,8 @@ default void interceptTestTemplateMethod(Invocation<@Nullable Void> invocation, * @throws Throwable in case of failures */ @API(status = STABLE, since = "5.11") - default void interceptDynamicTest(Invocation<@Nullable Void> invocation, - DynamicTestInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { + default void interceptDynamicTest(Invocation invocation, DynamicTestInvocationContext invocationContext, + ExtensionContext extensionContext) throws Throwable { invocation.proceed(); } @@ -189,7 +189,7 @@ default void interceptDynamicTest(Invocation<@Nullable Void> invocation, * @param extensionContext the current extension context; never {@code null} * @throws Throwable in case of failures */ - default void interceptAfterEachMethod(Invocation<@Nullable Void> invocation, + default void interceptAfterEachMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { invocation.proceed(); } @@ -204,7 +204,7 @@ default void interceptAfterEachMethod(Invocation<@Nullable Void> invocation, * @param extensionContext the current extension context; never {@code null} * @throws Throwable in case of failures */ - default void interceptAfterAllMethod(Invocation<@Nullable Void> invocation, + default void interceptAfterAllMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { invocation.proceed(); } @@ -218,7 +218,7 @@ default void interceptAfterAllMethod(Invocation<@Nullable Void> invocation, * @since 5.5 */ @API(status = STABLE, since = "5.10") - interface Invocation { + interface Invocation { /** * Proceed with this invocation. @@ -226,6 +226,7 @@ interface Invocation { * @return the result of this invocation; potentially {@code null}. * @throws Throwable in case the invocation failed */ + @Nullable T proceed() throws Throwable; /** diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java index 5151d5c686a7..92923e39b3bb 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java @@ -409,8 +409,8 @@ private Object invokeTestClassConstructor(Optional outerInstance, Extens ExtensionContextSupplier extensionContext) { Constructor constructor = ReflectionUtils.getDeclaredConstructor(getTestClass()); - return executableInvoker.invoke(constructor, outerInstance, extensionContext, registry, - InvocationInterceptor::interceptTestClassConstructor); + return requireNonNull(executableInvoker.invoke(constructor, outerInstance, extensionContext, registry, + InvocationInterceptor::interceptTestClassConstructor)); } private void invokeTestInstancePreConstructCallbacks(TestInstanceFactoryContext factoryContext, diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/DynamicTestTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/DynamicTestTestDescriptor.java index b45aefc619fd..5d97737adec8 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/DynamicTestTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/DynamicTestTestDescriptor.java @@ -71,7 +71,6 @@ public JupiterEngineExecutionContext execute(JupiterEngineExecutionContext conte return context; } - @SuppressWarnings("NullAway") private InvocationInterceptor.Invocation toInvocation() { return () -> { requiredDynamicTest().getExecutable().execute(); diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java index 7b50ac238292..49ca1b2ead22 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/TestFactoryTestDescriptor.java @@ -60,7 +60,7 @@ public class TestFactoryTestDescriptor extends TestMethodTestDescriptor implemen public static final String DYNAMIC_TEST_SEGMENT_TYPE = "dynamic-test"; @SuppressWarnings("NullAway") - private static final ReflectiveInterceptorCall interceptorCall = InvocationInterceptor::interceptTestFactoryMethod; + private static final ReflectiveInterceptorCall interceptorCall = InvocationInterceptor::interceptTestFactoryMethod; private static final InterceptingExecutableInvoker executableInvoker = new InterceptingExecutableInvoker(); private final DynamicDescendantFilter dynamicDescendantFilter; diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/InterceptingExecutableInvoker.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/InterceptingExecutableInvoker.java index 8a9a25968973..a93e4ffb8c4a 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/InterceptingExecutableInvoker.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/InterceptingExecutableInvoker.java @@ -54,14 +54,14 @@ public class InterceptingExecutableInvoker { * invocation via all registered {@linkplain InvocationInterceptor * interceptors} */ - public T invoke(Constructor constructor, Optional outerInstance, + public @Nullable T invoke(Constructor constructor, Optional outerInstance, ExtensionContextSupplier extensionContext, ExtensionRegistry extensionRegistry, ReflectiveInterceptorCall, T> interceptorCall) { @Nullable Object[] arguments = resolveParameters(constructor, Optional.empty(), outerInstance, extensionContext, extensionRegistry); - ConstructorInvocation invocation = new ConstructorInvocation<>(constructor, arguments); + ConstructorInvocation invocation = newConstructorInvocation(constructor, arguments); return invoke(invocation, invocation, extensionContext, extensionRegistry, interceptorCall); } @@ -78,7 +78,7 @@ public T invoke(Constructor constructor, Optional outerInstance, * @param interceptorCall the call for intercepting this method invocation * via all registered {@linkplain InvocationInterceptor interceptors} */ - public T invoke(Method method, @Nullable Object target, ExtensionContext extensionContext, + public @Nullable T invoke(Method method, @Nullable Object target, ExtensionContext extensionContext, ExtensionRegistry extensionRegistry, ReflectiveInterceptorCall interceptorCall) { @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -86,18 +86,18 @@ public T invoke(Method method, @Nullable Object target, ExtensionContext ext : Optional.ofNullable(target)); @Nullable Object[] arguments = resolveParameters(method, optionalTarget, extensionContext, extensionRegistry); - MethodInvocation invocation = new MethodInvocation<>(method, optionalTarget, arguments); + MethodInvocation invocation = newMethodInvocation(method, optionalTarget, arguments); return invoke(invocation, invocation, extensionContext, extensionRegistry, interceptorCall); } - private T invoke(Invocation originalInvocation, + private @Nullable T invoke(Invocation originalInvocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext, ExtensionRegistry extensionRegistry, ReflectiveInterceptorCall call) { return interceptorChain.invoke(originalInvocation, extensionRegistry, (interceptor, wrappedInvocation) -> call.apply(interceptor, wrappedInvocation, invocationContext, extensionContext)); } - private T invoke(Invocation originalInvocation, + private @Nullable T invoke(Invocation originalInvocation, ReflectiveInvocationContext invocationContext, ExtensionContextSupplier extensionContext, ExtensionRegistry extensionRegistry, ReflectiveInterceptorCall call) { return interceptorChain.invoke(originalInvocation, extensionRegistry, @@ -105,13 +105,26 @@ private T invoke(Invocation originalInvocation, extensionContext.get(interceptor))); } - public interface ReflectiveInterceptorCall { + @SuppressWarnings("NullAway") + private static ConstructorInvocation newConstructorInvocation(Constructor constructor, + @Nullable Object[] arguments) { + return new ConstructorInvocation<>(constructor, arguments); + } + + @SuppressWarnings("NullAway") + private static MethodInvocation newMethodInvocation(Method method, Optional optionalTarget, + @Nullable Object[] arguments) { + return new MethodInvocation<>(method, optionalTarget, arguments); + } + public interface ReflectiveInterceptorCall { + + @Nullable T apply(InvocationInterceptor interceptor, Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable; @SuppressWarnings("NullAway") - static ReflectiveInterceptorCall ofVoidMethod(VoidMethodInterceptorCall call) { + static ReflectiveInterceptorCall ofVoidMethod(VoidMethodInterceptorCall call) { return ((interceptorChain, invocation, invocationContext, extensionContext) -> { call.apply(interceptorChain, invocation, invocationContext, extensionContext); return null; diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/InvocationInterceptorChain.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/InvocationInterceptorChain.java index f066298ade98..412e14e3d7a2 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/InvocationInterceptorChain.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/InvocationInterceptorChain.java @@ -30,7 +30,8 @@ @API(status = INTERNAL, since = "5.5") public class InvocationInterceptorChain { - public T invoke(Invocation invocation, ExtensionRegistry extensionRegistry, InterceptorCall call) { + public @Nullable T invoke(Invocation invocation, ExtensionRegistry extensionRegistry, + InterceptorCall call) { List interceptors = extensionRegistry.getExtensions(InvocationInterceptor.class); if (interceptors.isEmpty()) { return proceed(invocation); @@ -38,7 +39,7 @@ public T invoke(Invocation invocation, ExtensionRegistry extensionRegistr return chainAndInvoke(invocation, call, interceptors); } - private T chainAndInvoke(Invocation invocation, InterceptorCall call, + private @Nullable T chainAndInvoke(Invocation invocation, InterceptorCall call, List interceptors) { ValidatingInvocation validatingInvocation = new ValidatingInvocation<>(invocation, interceptors); @@ -60,7 +61,7 @@ private Invocation chainInterceptors(Invocation invocation, Intercepto return result; } - private T proceed(Invocation invocation) { + private @Nullable T proceed(Invocation invocation) { try { return invocation.proceed(); } @@ -70,12 +71,13 @@ private T proceed(Invocation invocation) { } @FunctionalInterface - public interface InterceptorCall { + public interface InterceptorCall { + @Nullable T apply(InvocationInterceptor interceptor, Invocation invocation) throws Throwable; @SuppressWarnings("NullAway") - static InterceptorCall<@Nullable Void> ofVoid(VoidInterceptorCall call) { + static InterceptorCall ofVoid(VoidInterceptorCall call) { return ((interceptorChain, invocation) -> { call.apply(interceptorChain, invocation); return null; @@ -87,7 +89,7 @@ public interface InterceptorCall { @FunctionalInterface public interface VoidInterceptorCall { - void apply(InvocationInterceptor interceptor, Invocation<@Nullable Void> invocation) throws Throwable; + void apply(InvocationInterceptor interceptor, Invocation invocation) throws Throwable; } @@ -95,7 +97,7 @@ private record InterceptedInvocation(Invocation invocation, InterceptorCal InvocationInterceptor interceptor) implements Invocation { @Override - public T proceed() throws Throwable { + public @Nullable T proceed() throws Throwable { return call.apply(interceptor, invocation); } @@ -119,7 +121,7 @@ private static class ValidatingInvocation implements } @Override - public T proceed() throws Throwable { + public @Nullable T proceed() throws Throwable { markInvokedOrSkipped(); return delegate.proceed(); } diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/NamespaceAwareStore.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/NamespaceAwareStore.java index 59897452d19d..bce79a32c13a 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/NamespaceAwareStore.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/NamespaceAwareStore.java @@ -39,12 +39,14 @@ public NamespaceAwareStore(NamespacedHierarchicalStore valuesStore, N } @Override + @SuppressWarnings("NullAway") public @Nullable Object get(Object key) { Preconditions.notNull(key, "key must not be null"); return accessStore(() -> this.valuesStore.get(this.namespace, key)); } @Override + @SuppressWarnings("NullAway") public @Nullable T get(Object key, Class requiredType) { Preconditions.notNull(key, "key must not be null"); Preconditions.notNull(requiredType, "requiredType must not be null"); @@ -52,6 +54,7 @@ public NamespaceAwareStore(NamespacedHierarchicalStore valuesStore, N } @Override + @SuppressWarnings("NullAway") public @Nullable Object getOrComputeIfAbsent(K key, Function defaultCreator) { Preconditions.notNull(key, "key must not be null"); Preconditions.notNull(defaultCreator, "defaultCreator function must not be null"); @@ -59,6 +62,7 @@ public NamespaceAwareStore(NamespacedHierarchicalStore valuesStore, N } @Override + @SuppressWarnings("NullAway") public @Nullable V getOrComputeIfAbsent(K key, Function defaultCreator, Class requiredType) { Preconditions.notNull(key, "key must not be null"); Preconditions.notNull(defaultCreator, "defaultCreator function must not be null"); @@ -68,18 +72,21 @@ public NamespaceAwareStore(NamespacedHierarchicalStore valuesStore, N } @Override + @SuppressWarnings("NullAway") public void put(Object key, @Nullable Object value) { Preconditions.notNull(key, "key must not be null"); accessStore(() -> this.valuesStore.put(this.namespace, key, value)); } @Override + @SuppressWarnings("NullAway") public @Nullable Object remove(Object key) { Preconditions.notNull(key, "key must not be null"); return accessStore(() -> this.valuesStore.remove(this.namespace, key)); } @Override + @SuppressWarnings("NullAway") public @Nullable T remove(Object key, Class requiredType) { Preconditions.notNull(key, "key must not be null"); Preconditions.notNull(requiredType, "requiredType must not be null"); diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/SeparateThreadTimeoutInvocation.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/SeparateThreadTimeoutInvocation.java index d9783d1b7942..35df0e57dbdf 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/SeparateThreadTimeoutInvocation.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/SeparateThreadTimeoutInvocation.java @@ -37,6 +37,7 @@ class SeparateThreadTimeoutInvocation implements Inv } @Override + @SuppressWarnings("NullAway") public T proceed() throws Throwable { return assertTimeoutPreemptively(timeout.toDuration(), delegate::proceed, descriptionSupplier, (__, messageSupplier, cause, testThread) -> { diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutExtension.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutExtension.java index c0b32bf4303d..e78e15e61dc4 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutExtension.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutExtension.java @@ -103,7 +103,7 @@ public void interceptTestTemplateMethod(Invocation invocation, } @Override - public T interceptTestFactoryMethod(Invocation invocation, + public @Nullable T interceptTestFactoryMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { return interceptTestableMethod(invocation, invocationContext, extensionContext, @@ -145,7 +145,7 @@ private Optional readTimeoutThreadModeFromAnnotation(Optional T interceptTestableMethod(Invocation invocation, + private @Nullable T interceptTestableMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext, TimeoutProvider defaultTimeoutProvider) throws Throwable { @@ -154,7 +154,7 @@ private T interceptTestableMethod(Invocation invocation, return intercept(invocation, invocationContext, extensionContext, timeout, defaultTimeoutProvider); } - private T intercept(Invocation invocation, ReflectiveInvocationContext invocationContext, + private @Nullable T intercept(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext, @Nullable TimeoutDuration explicitTimeout, TimeoutProvider defaultTimeoutProvider) throws Throwable { diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/support/MethodReflectionUtils.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/support/MethodReflectionUtils.java index a72d013134f4..3493981e9a36 100644 --- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/support/MethodReflectionUtils.java +++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/support/MethodReflectionUtils.java @@ -38,6 +38,7 @@ public static Type getGenericReturnType(Method method) { : method.getGenericReturnType(); } + @SuppressWarnings("NullAway") public static @Nullable Object invoke(Method method, @Nullable Object target, @Nullable Object[] arguments) { if (isKotlinSuspendingFunction(method)) { return invokeKotlinSuspendingFunction(method, target, arguments); diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolutionCache.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolutionCache.java index b692cb5a0e5d..4bd2321faac2 100644 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolutionCache.java +++ b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolutionCache.java @@ -36,7 +36,7 @@ class Concurrent implements ResolutionCache { private final Map cache = new ConcurrentHashMap<>(); @Override - public Object resolve(ParameterDeclaration declaration, Supplier resolver) { + public @Nullable Object resolve(ParameterDeclaration declaration, Supplier<@Nullable Object> resolver) { return cache.computeIfAbsent(declaration, __ -> resolver.get()); } } diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessor.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessor.java index f33ac3dbdf0e..2d02fccb87ef 100644 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessor.java +++ b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessor.java @@ -54,9 +54,11 @@ public static DefaultArgumentsAccessor create(ExtensionContext context, int invo private DefaultArgumentsAccessor(BiFunction<@Nullable Object, Class, @Nullable Object> converter, int invocationIndex, @Nullable Object... arguments) { Preconditions.condition(invocationIndex >= 1, () -> "Invocation index must be >= 1"); - this.converter = Preconditions.notNull(converter, "Converter must not be null"); + Preconditions.notNull(converter, "Converter must not be null"); + Preconditions.notNull(arguments, "Arguments array must not be null"); + this.converter = converter; this.invocationIndex = invocationIndex; - this.arguments = Preconditions.notNull(arguments, "Arguments array must not be null"); + this.arguments = arguments; } @Override @@ -140,7 +142,7 @@ public int size() { @Override public List<@Nullable Object> toList() { - return Collections.unmodifiableList(Arrays.asList(this.arguments)); + return Collections.<@Nullable Object> unmodifiableList(Arrays.asList(this.arguments)); } @Override diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvArgumentsProvider.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvArgumentsProvider.java index 9ec3aa038417..b30f59c74956 100644 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvArgumentsProvider.java +++ b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/CsvArgumentsProvider.java @@ -13,6 +13,7 @@ import static java.util.Objects.requireNonNull; import static org.junit.jupiter.params.provider.CsvParserFactory.createParserFor; +import java.io.Reader; import java.io.StringReader; import java.lang.annotation.Annotation; import java.util.ArrayList; @@ -58,7 +59,7 @@ private Stream parseTextBlock(CsvSource csvSource, CsvParser csvParse List argumentsList = new ArrayList<>(); try { - List<@Nullable String[]> csvRecords = csvParser.parseAll(new StringReader(textBlock)); + List<@Nullable String[]> csvRecords = parseAll(csvParser, new StringReader(textBlock)); String[] headers = useHeadersInDisplayName ? getHeaders(csvParser) : null; AtomicInteger index = new AtomicInteger(0); @@ -76,6 +77,11 @@ private Stream parseTextBlock(CsvSource csvSource, CsvParser csvParse return argumentsList.stream(); } + @SuppressWarnings("NullAway") + private static List<@Nullable String[]> parseAll(CsvParser csvParser, Reader reader) { + return csvParser.parseAll(reader); + } + private Stream parseValueArray(CsvSource csvSource, CsvParser csvParser, Set nullValues) { boolean useHeadersInDisplayName = csvSource.useHeadersInDisplayName(); List argumentsList = new ArrayList<>(); diff --git a/junit-jupiter-params/src/testFixtures/java/org/junit/jupiter/params/provider/RecordArguments.java b/junit-jupiter-params/src/testFixtures/java/org/junit/jupiter/params/provider/RecordArguments.java index 1ecc810c460c..472df2174008 100644 --- a/junit-jupiter-params/src/testFixtures/java/org/junit/jupiter/params/provider/RecordArguments.java +++ b/junit-jupiter-params/src/testFixtures/java/org/junit/jupiter/params/provider/RecordArguments.java @@ -18,6 +18,7 @@ public interface RecordArguments extends Arguments { @Override + @SuppressWarnings("NullAway") default @Nullable Object[] get() { return Arrays.stream(getClass().getRecordComponents()) // .map(component -> ReflectionSupport.invokeMethod(component.getAccessor(), this)) // diff --git a/junit-platform-commons/src/main/java/org/junit/platform/commons/function/Try.java b/junit-platform-commons/src/main/java/org/junit/platform/commons/function/Try.java index 31f8f172efc3..7635e4403427 100644 --- a/junit-platform-commons/src/main/java/org/junit/platform/commons/function/Try.java +++ b/junit-platform-commons/src/main/java/org/junit/platform/commons/function/Try.java @@ -55,7 +55,7 @@ public abstract class Try { * @see #success(Object) * @see #failure(Exception) */ - public static Try call(Callable action) { + public static Try call(Callable action) { checkNotNull(action, "action"); return Try.of(() -> success(action.call())); } @@ -164,8 +164,7 @@ private Try() { */ @API(status = EXPERIMENTAL, since = "6.0") public final @NonNull V getNonNull() throws Exception { - var value = get(); - return checkNotNull(value, "value"); + return checkNotNull(get(), "value"); } /** @@ -193,7 +192,7 @@ private Try() { */ @API(status = EXPERIMENTAL, since = "6.0") public final @NonNull V getNonNullOrThrow( - Function exceptionTransformer) throws E { + Function<@Nullable Exception, E> exceptionTransformer) throws E { var value = getOrThrow(exceptionTransformer); if (value == null) { throw exceptionTransformer.apply(null); diff --git a/junit-platform-commons/src/main/java/org/junit/platform/commons/logging/LoggerFactory.java b/junit-platform-commons/src/main/java/org/junit/platform/commons/logging/LoggerFactory.java index ee37d83db1c9..711b42d6c658 100644 --- a/junit-platform-commons/src/main/java/org/junit/platform/commons/logging/LoggerFactory.java +++ b/junit-platform-commons/src/main/java/org/junit/platform/commons/logging/LoggerFactory.java @@ -145,7 +145,7 @@ public void trace(@Nullable Throwable throwable, Supplier messageSupplie private void log(Level level, @Nullable Throwable throwable, Supplier messageSupplier) { boolean loggable = this.julLogger.isLoggable(level); if (loggable || !listeners.isEmpty()) { - LogRecord logRecord = createLogRecord(level, throwable, nullSafeGet(messageSupplier)); + LogRecord logRecord = createLogRecord(level, throwable, messageSupplier.get()); if (loggable) { this.julLogger.log(logRecord); } @@ -153,7 +153,7 @@ private void log(Level level, @Nullable Throwable throwable, Supplier me } } - private LogRecord createLogRecord(Level level, @Nullable Throwable throwable, @Nullable String message) { + private LogRecord createLogRecord(Level level, @Nullable Throwable throwable, String message) { String sourceClassName = null; String sourceMethodName = null; boolean found = false; @@ -180,10 +180,6 @@ else if (found) { return logRecord; } - private static @Nullable String nullSafeGet(@Nullable Supplier<@Nullable String> messageSupplier) { - return (messageSupplier != null ? messageSupplier.get() : null); - } - } } diff --git a/junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java b/junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java index 2d7c11e3eace..5728e11c6d50 100644 --- a/junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java +++ b/junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java @@ -637,6 +637,7 @@ public static Try tryToReadFieldValue(Class clazz, String fieldNa * @see #tryToReadFieldValue(Class, String, Object) */ @API(status = INTERNAL, since = "1.4") + @SuppressWarnings("NullAway") public static Try<@Nullable Object> tryToReadFieldValue(Field field, @Nullable Object instance) { Preconditions.notNull(field, "Field must not be null"); Preconditions.condition((instance != null || isStatic(field)), @@ -681,7 +682,7 @@ public static Try tryToReadFieldValue(Class clazz, String fieldNa // @formatter:off return fields.stream() .filter(predicate) - .map(field -> + .<@Nullable Object>map(field -> tryToReadFieldValue(field, instance).getOrThrow(ExceptionUtils::throwAsUncheckedException)) .toList(); // @formatter:on diff --git a/junit-platform-commons/src/testFixtures/java/org/junit/platform/commons/test/ConcurrencyTestingUtils.java b/junit-platform-commons/src/testFixtures/java/org/junit/platform/commons/test/ConcurrencyTestingUtils.java index ca1474c2e372..4a4e88a3d605 100644 --- a/junit-platform-commons/src/testFixtures/java/org/junit/platform/commons/test/ConcurrencyTestingUtils.java +++ b/junit-platform-commons/src/testFixtures/java/org/junit/platform/commons/test/ConcurrencyTestingUtils.java @@ -26,10 +26,11 @@ public class ConcurrencyTestingUtils { public static void executeConcurrently(int threads, Runnable action) throws Exception { - executeConcurrently(threads, () -> { + Callable<@Nullable Object> callable = () -> { action.run(); return null; - }); + }; + executeConcurrently(threads, callable); } public static List executeConcurrently(int threads, Callable<@Nullable T> action) throws Exception { diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/ConfigurationParameters.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/ConfigurationParameters.java index d721066ce792..63a9b6e16b4d 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/ConfigurationParameters.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/ConfigurationParameters.java @@ -117,7 +117,7 @@ public interface ConfigurationParameters { * @see #CONFIG_FILE_NAME */ @API(status = STABLE, since = "1.3") - default Optional get(String key, Function transformer) { + default Optional get(String key, Function transformer) { Preconditions.notNull(transformer, "transformer must not be null"); return get(key).map(input -> { try { diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/config/PrefixedConfigurationParameters.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/config/PrefixedConfigurationParameters.java index d78dc800219d..0673d1c003ef 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/config/PrefixedConfigurationParameters.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/config/PrefixedConfigurationParameters.java @@ -17,6 +17,7 @@ import java.util.function.Function; import org.apiguardian.api.API; +import org.jspecify.annotations.Nullable; import org.junit.platform.commons.util.Preconditions; import org.junit.platform.engine.ConfigurationParameters; @@ -57,7 +58,7 @@ public Optional getBoolean(String key) { } @Override - public Optional get(String key, Function transformer) { + public Optional get(String key, Function transformer) { return delegate.get(prefixed(key), transformer); } diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/DefaultParallelExecutionConfigurationStrategy.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/DefaultParallelExecutionConfigurationStrategy.java index 91bc18a23589..0ef596c61227 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/DefaultParallelExecutionConfigurationStrategy.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/DefaultParallelExecutionConfigurationStrategy.java @@ -16,6 +16,8 @@ import java.math.BigDecimal; import java.util.Locale; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Predicate; import org.apiguardian.api.API; import org.junit.platform.commons.JUnitException; @@ -47,11 +49,11 @@ public ParallelExecutionConfiguration createConfiguration(ConfigurationParameter int maxPoolSize = configurationParameters.get(CONFIG_FIXED_MAX_POOL_SIZE_PROPERTY_NAME, Integer::valueOf).orElse(parallelism + 256); - boolean saturate = configurationParameters.get(CONFIG_FIXED_SATURATE_PROPERTY_NAME, - Boolean::valueOf).orElse(true); + boolean saturate = configurationParameters.getBoolean(CONFIG_FIXED_SATURATE_PROPERTY_NAME).orElse(true); + Predicate forkJoinPoolPredicate = __ -> saturate; return new DefaultParallelExecutionConfiguration(parallelism, parallelism, maxPoolSize, parallelism, - KEEP_ALIVE_SECONDS, __ -> saturate); + KEEP_ALIVE_SECONDS, forkJoinPoolPredicate); } }, diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java index 3f64d3cd4493..60677dea7bac 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/ForkJoinPoolHierarchicalTestExecutorService.java @@ -127,6 +127,7 @@ private static Callable sinceJava7ConstructorInvocation(ParallelEx } @Override + @SuppressWarnings("NullAway") public Future<@Nullable Void> submit(TestTask testTask) { ExclusiveTask exclusiveTask = new ExclusiveTask(testTask); if (!isAlreadyRunningInForkJoinPool()) { diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/HierarchicalTestExecutor.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/HierarchicalTestExecutor.java index 3ce7e541cf43..c983a3d2258a 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/HierarchicalTestExecutor.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/HierarchicalTestExecutor.java @@ -12,6 +12,7 @@ import java.util.concurrent.Future; +import org.jspecify.annotations.Nullable; import org.junit.platform.engine.EngineExecutionListener; import org.junit.platform.engine.ExecutionRequest; import org.junit.platform.engine.TestDescriptor; @@ -46,7 +47,7 @@ class HierarchicalTestExecutor { this.throwableCollectorFactory = throwableCollectorFactory; } - Future execute() { + Future<@Nullable Void> execute() { TestDescriptor rootTestDescriptor = this.request.getRootTestDescriptor(); EngineExecutionListener executionListener = this.request.getEngineExecutionListener(); NodeExecutionAdvisor executionAdvisor = new NodeTreeWalker().walk(rootTestDescriptor); @@ -54,7 +55,8 @@ Future execute() { this.throwableCollectorFactory, executionAdvisor); NodeTestTask rootTestTask = new NodeTestTask<>(taskContext, rootTestDescriptor); rootTestTask.setParentContext(this.rootContext); - return this.executorService.submit(rootTestTask); + //noinspection RedundantCast + return (Future<@Nullable Void>) this.executorService.submit(rootTestTask); } } diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/NodeTestTask.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/NodeTestTask.java index 95af64b24296..2b5082e74ae4 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/NodeTestTask.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/NodeTestTask.java @@ -257,7 +257,7 @@ public Future execute(TestDescriptor testDescriptor, EngineExecutionListener testDescriptor, () -> unfinishedTasks.remove(uniqueId)); nodeTestTask.setParentContext(context); unfinishedTasks.put(uniqueId, DynamicTaskState.unscheduled()); - Future future = taskContext.executorService().submit(nodeTestTask); + Future<@Nullable Void> future = taskContext.executorService().submit(nodeTestTask); unfinishedTasks.computeIfPresent(uniqueId, (__, state) -> DynamicTaskState.scheduled(future)); return future; } @@ -289,7 +289,7 @@ static DynamicTaskState unscheduled() { return UNSCHEDULED; } - static DynamicTaskState scheduled(Future future) { + static DynamicTaskState scheduled(Future<@Nullable Void> future) { return future::get; } diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/SameThreadHierarchicalTestExecutorService.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/SameThreadHierarchicalTestExecutorService.java index 9255e9df16e7..aa05f4330ebb 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/SameThreadHierarchicalTestExecutorService.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/SameThreadHierarchicalTestExecutorService.java @@ -32,6 +32,7 @@ public SameThreadHierarchicalTestExecutorService() { } @Override + @SuppressWarnings("NullAway") public Future<@Nullable Void> submit(TestTask testTask) { testTask.execute(); return completedFuture(null); diff --git a/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/LauncherPhase.java b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/LauncherPhase.java index 5536e8c7227d..6a1a72055186 100644 --- a/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/LauncherPhase.java +++ b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/LauncherPhase.java @@ -30,6 +30,7 @@ enum LauncherPhase { private static final Logger logger = LoggerFactory.getLogger(LauncherPhase.class); + @SuppressWarnings("NullAway") static Optional getDiscoveryIssueFailurePhase(ConfigurationParameters configurationParameters) { return configurationParameters.get(DISCOVERY_ISSUE_FAILURE_PHASE_PROPERTY_NAME, value -> { try { diff --git a/junit-platform-launcher/src/main/java/org/junit/platform/launcher/listeners/LoggingListener.java b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/listeners/LoggingListener.java index a17b48147a40..14ded1f6b141 100644 --- a/junit-platform-launcher/src/main/java/org/junit/platform/launcher/listeners/LoggingListener.java +++ b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/listeners/LoggingListener.java @@ -79,14 +79,15 @@ public static LoggingListener forJavaUtilLogging(Level logLevel) { * @see #forJavaUtilLogging() * @see #forJavaUtilLogging(Level) */ - public static LoggingListener forBiConsumer(BiConsumer> logger) { + public static LoggingListener forBiConsumer(BiConsumer<@Nullable Throwable, Supplier> logger) { return new LoggingListener(logger); } private final BiConsumer<@Nullable Throwable, Supplier> logger; - private LoggingListener(BiConsumer> logger) { - this.logger = Preconditions.notNull(logger, "logger must not be null"); + private LoggingListener(BiConsumer<@Nullable Throwable, Supplier> logger) { + Preconditions.notNull(logger, "logger must not be null"); + this.logger = logger; } @Override diff --git a/junit-platform-testkit/src/main/java/org/junit/platform/testkit/engine/TestExecutionResultConditions.java b/junit-platform-testkit/src/main/java/org/junit/platform/testkit/engine/TestExecutionResultConditions.java index ad3da44665fa..315b983da06b 100644 --- a/junit-platform-testkit/src/main/java/org/junit/platform/testkit/engine/TestExecutionResultConditions.java +++ b/junit-platform-testkit/src/main/java/org/junit/platform/testkit/engine/TestExecutionResultConditions.java @@ -46,6 +46,7 @@ private TestExecutionResultConditions() { * {@link TestExecutionResult}'s {@linkplain TestExecutionResult#getStatus() * status} is equal to the supplied {@link Status Status}. */ + @SuppressWarnings("NullAway") public static Condition status(Status expectedStatus) { return new Condition<>(where(TestExecutionResult::getStatus, isEqual(expectedStatus)), "status is %s", expectedStatus); @@ -137,6 +138,7 @@ public static Condition instanceOf(Class expecte * {@link Throwable}'s {@linkplain Throwable#getMessage() message} is equal * to the supplied {@link String}. */ + @SuppressWarnings("NullAway") public static Condition message(String expectedMessage) { return new Condition<>(where(Throwable::getMessage, isEqual(expectedMessage)), "message is '%s'", expectedMessage); @@ -147,10 +149,12 @@ public static Condition message(String expectedMessage) { * {@link Throwable}'s {@linkplain Throwable#getMessage() message} matches * the supplied {@link Predicate}. */ + @SuppressWarnings("NullAway") public static Condition message(Predicate expectedMessagePredicate) { return new Condition<>(where(Throwable::getMessage, expectedMessagePredicate), "message matches predicate"); } + @SuppressWarnings("NullAway") private static Condition throwable(Condition condition) { return new Condition<>( where(TestExecutionResult::getThrowable, diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java index c39bc60b5fb7..de6ddc5c6613 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/engine/ClassTemplateInvocationTests.java @@ -1493,7 +1493,7 @@ static class ClassTemplateInvocationCallbacks implements BeforeClassTemplateInvocationCallback, AfterClassTemplateInvocationCallback { private final String prefix; - private final Function exceptionFactory; + private final Function exceptionFactory; @SuppressWarnings("unused") ClassTemplateInvocationCallbacks() { @@ -1504,7 +1504,7 @@ static class ClassTemplateInvocationCallbacks this(prefix, __ -> null); } - ClassTemplateInvocationCallbacks(String prefix, Function exceptionFactory) { + ClassTemplateInvocationCallbacks(String prefix, Function exceptionFactory) { this.prefix = prefix; this.exceptionFactory = exceptionFactory; } diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/AbstractExecutableInvokerTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/AbstractExecutableInvokerTests.java index 683c5c212f9a..daaaacc6a430 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/AbstractExecutableInvokerTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/AbstractExecutableInvokerTests.java @@ -98,6 +98,6 @@ private void register(ParameterResolver... resolvers) { abstract void invokeMethod(); - abstract T invokeConstructor(Constructor constructor, @Nullable Object outerInstance); + abstract @Nullable T invokeConstructor(Constructor constructor, @Nullable Object outerInstance); } diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/InterceptingExecutableInvokerTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/InterceptingExecutableInvokerTests.java index a3abef9708e2..19039ace35cd 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/InterceptingExecutableInvokerTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/InterceptingExecutableInvokerTests.java @@ -33,7 +33,7 @@ void invokeMethod() { } @Override - T invokeConstructor(Constructor constructor, @Nullable Object outerInstance) { + @Nullable T invokeConstructor(Constructor constructor, @Nullable Object outerInstance) { return newInvoker().invoke(constructor, Optional.ofNullable(outerInstance), __ -> extensionContext, extensionRegistry, passthroughInterceptor()); } diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/ParameterResolutionUtilsTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/ParameterResolutionUtilsTests.java index 6612530bb977..6fb711398daf 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/ParameterResolutionUtilsTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/engine/execution/ParameterResolutionUtilsTests.java @@ -63,6 +63,7 @@ void resolveConstructorArguments() { register(new StringParameterResolver()); Class topLevelClass = ConstructorInjectionTestCase.class; + @Nullable Object[] arguments = resolveConstructorParameters(topLevelClass, null); assertThat(arguments).containsExactly(ENIGMA); @@ -76,6 +77,7 @@ void resolveNestedConstructorArguments() { ConstructorInjectionTestCase outer = ReflectionSupport.newInstance(outerClass, "str"); Class innerClass = ConstructorInjectionTestCase.NestedTestCase.class; + @Nullable Object[] arguments = resolveConstructorParameters(innerClass, outer); assertThat(arguments).containsExactly(outer, 42); @@ -101,7 +103,7 @@ void resolvingArgumentsForMethodsWithoutParameterDoesNotDependOnParameterResolve testMethodWithNoParameters(); throwDuringParameterResolution(new RuntimeException("boom!")); - Object[] arguments = resolveMethodParameters(); + var arguments = resolveMethodParameters(); assertThat(arguments).isEmpty(); } @@ -111,7 +113,7 @@ void resolveArgumentsViaParameterResolver() { testMethodWithASingleStringParameter(); thereIsAParameterResolverThatResolvesTheParameterTo("argument"); - Object[] arguments = resolveMethodParameters(); + var arguments = resolveMethodParameters(); assertThat(arguments).containsExactly("argument"); } @@ -127,7 +129,7 @@ void resolveMultipleArguments() { }; })); - Object[] arguments = resolveMethodParameters(); + var arguments = resolveMethodParameters(); assertThat(arguments).containsExactly("0", 1, 2.0); } @@ -138,7 +140,7 @@ void onlyConsiderParameterResolversThatSupportAParticularParameter() { thereIsAParameterResolverThatDoesNotSupportThisParameter(); thereIsAParameterResolverThatResolvesTheParameterTo("something"); - Object[] arguments = resolveMethodParameters(); + var arguments = resolveMethodParameters(); assertThat(arguments).containsExactly("something"); } @@ -167,7 +169,7 @@ void resolvingArgumentsForMethodsWithPrimitiveTypesIsSupported() { testMethodWithASinglePrimitiveIntParameter(); thereIsAParameterResolverThatResolvesTheParameterTo(42); - Object[] arguments = resolveMethodParameters(); + var arguments = resolveMethodParameters(); assertThat(arguments).containsExactly(42); } @@ -177,7 +179,7 @@ void nullIsAViableArgumentIfAReferenceTypeParameterIsExpected() { testMethodWithASingleStringParameter(); thereIsAParameterResolverThatResolvesTheParameterTo(null); - Object[] arguments = resolveMethodParameters(); + var arguments = resolveMethodParameters(); assertThat(arguments).hasSize(1); assertNull(arguments[0]); diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/engine/extension/InvocationInterceptorTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/engine/extension/InvocationInterceptorTests.java index b9b39cecff58..3515a122e616 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/engine/extension/InvocationInterceptorTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/engine/extension/InvocationInterceptorTests.java @@ -10,6 +10,7 @@ package org.junit.jupiter.engine.extension; +import static java.util.Objects.requireNonNull; import static java.util.function.Function.identity; import static java.util.function.Predicate.isEqual; import static org.assertj.core.api.Assertions.assertThat; @@ -30,6 +31,7 @@ import java.util.function.UnaryOperator; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -305,7 +307,7 @@ public T interceptTestClassConstructor(Invocation invocation, assertEquals(testClass, invocationContext.getTargetClass()); assertEquals(testClass.getDeclaredConstructor(TestReporter.class), invocationContext.getExecutable()); assertThat(invocationContext.getArguments()).hasSize(1).hasOnlyElementsOfType(TestReporter.class); - return reportAndProceed(invocation, extensionContext, InvocationType.CONSTRUCTOR); + return requireNonNull(reportAndProceed(invocation, extensionContext, InvocationType.CONSTRUCTOR)); } @Override @@ -352,7 +354,7 @@ public T interceptTestFactoryMethod(Invocation invocation, assertEquals(testClass.getDeclaredMethod("testFactory", TestReporter.class), invocationContext.getExecutable()); assertThat(invocationContext.getArguments()).hasSize(1).hasOnlyElementsOfType(TestReporter.class); - return reportAndProceed(invocation, extensionContext, InvocationType.TEST_FACTORY_METHOD); + return requireNonNull(reportAndProceed(invocation, extensionContext, InvocationType.TEST_FACTORY_METHOD)); } @Override @@ -390,8 +392,8 @@ public void interceptAfterAllMethod(Invocation invocation, reportAndProceed(invocation, extensionContext, InvocationType.AFTER_ALL); } - private T reportAndProceed(Invocation invocation, ExtensionContext extensionContext, InvocationType type) - throws Throwable { + private @Nullable T reportAndProceed(Invocation invocation, ExtensionContext extensionContext, + InvocationType type) throws Throwable { extensionContext.publishReportEntry(type.name(), "before:" + name); try { return invocation.proceed(); diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessorTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessorTests.java index 8bad1f29d436..102086900fdf 100644 --- a/jupiter-tests/src/test/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessorTests.java +++ b/jupiter-tests/src/test/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessorTests.java @@ -167,6 +167,7 @@ void size() { assertEquals(5, defaultArgumentsAccessor(1, 'a', 'b', 'c', 'd', 'e').size()); } + @SuppressWarnings("NullAway") private static DefaultArgumentsAccessor defaultArgumentsAccessor(int invocationIndex, @Nullable Object... arguments) { var context = mock(ExtensionContext.class); diff --git a/platform-tests/src/test/java/org/junit/platform/engine/support/descriptor/TestDescriptorOrderChildrenTests.java b/platform-tests/src/test/java/org/junit/platform/engine/support/descriptor/TestDescriptorOrderChildrenTests.java index 55e0d80a20b9..8d0e8e239dc1 100644 --- a/platform-tests/src/test/java/org/junit/platform/engine/support/descriptor/TestDescriptorOrderChildrenTests.java +++ b/platform-tests/src/test/java/org/junit/platform/engine/support/descriptor/TestDescriptorOrderChildrenTests.java @@ -116,6 +116,7 @@ default void orderChildrenDuplicatesDescriptor() { assertThat(exception).hasMessage("orderer may not add or remove test descriptors"); } + @SuppressWarnings({ "DataFlowIssue", "NullAway" }) @Test default void orderChildrenOrdererReturnsNull() { var testDescriptor = createTestDescriptorWithChildren();