Skip to content

Commit afacf3b

Browse files
committed
Enable NullAway in junit-vintage-engine
1 parent 58f135c commit afacf3b

File tree

12 files changed

+43
-7
lines changed

12 files changed

+43
-7
lines changed

junit-vintage-engine/junit-vintage-engine.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
id("junitbuild.java-library-conventions")
3+
id("junitbuild.java-nullability-conventions")
34
id("junitbuild.junit4-compatibility")
45
id("junitbuild.testing-conventions")
56
`java-test-fixtures`
@@ -14,6 +15,7 @@ dependencies {
1415
api(libs.junit4)
1516

1617
compileOnlyApi(libs.apiguardian)
18+
compileOnly(libs.jspecify)
1719

1820
testFixturesApi(platform(libs.groovy2.bom))
1921
testFixturesApi(libs.spock1)

junit-vintage-engine/src/main/java/module-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
* https://www.eclipse.org/legal/epl-v20.html
99
*/
1010

11+
import org.jspecify.annotations.NullMarked;
12+
1113
/**
1214
* Provides a {@link org.junit.platform.engine.TestEngine} for running JUnit 3
1315
* and 4 based tests on the platform.
@@ -16,6 +18,7 @@
1618
* @provides org.junit.platform.engine.TestEngine The {@code VintageTestEngine}
1719
* runs JUnit 3 and 4 based tests on the platform.
1820
*/
21+
@NullMarked
1922
module org.junit.vintage.engine {
2023
requires junit; // 4
2124
requires static org.apiguardian.api;

junit-vintage-engine/src/main/java/org/junit/vintage/engine/descriptor/DescriptionUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
package org.junit.vintage.engine.descriptor;
1212

1313
import org.apiguardian.api.API;
14+
import org.jspecify.annotations.Nullable;
1415
import org.junit.runner.Description;
1516

1617
@API(status = API.Status.INTERNAL, since = "5.8")
@@ -19,6 +20,7 @@ public class DescriptionUtils {
1920
private DescriptionUtils() {
2021
}
2122

23+
@Nullable
2224
public static String getMethodName(Description description) {
2325
String displayName = description.getDisplayName();
2426
int i = displayName.indexOf('(');

junit-vintage-engine/src/main/java/org/junit/vintage/engine/descriptor/RunnerTestDescriptor.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.function.Consumer;
2727

2828
import org.apiguardian.api.API;
29+
import org.jspecify.annotations.Nullable;
2930
import org.junit.platform.commons.JUnitException;
3031
import org.junit.platform.commons.logging.Logger;
3132
import org.junit.platform.commons.logging.LoggerFactory;
@@ -54,6 +55,8 @@ public class RunnerTestDescriptor extends VintageTestDescriptor {
5455
private Runner runner;
5556
private final boolean ignored;
5657
private boolean wasFiltered;
58+
59+
@Nullable
5760
private List<Filter> filters = new ArrayList<>();
5861

5962
public RunnerTestDescriptor(UniqueId uniqueId, Class<?> testClass, Runner runner, boolean ignored) {

junit-vintage-engine/src/main/java/org/junit/vintage/engine/descriptor/TestSourceProvider.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.concurrent.ConcurrentHashMap;
2525

2626
import org.apiguardian.api.API;
27+
import org.jspecify.annotations.Nullable;
2728
import org.junit.platform.commons.support.ModifierSupport;
2829
import org.junit.platform.commons.util.LruCache;
2930
import org.junit.platform.engine.TestSource;
@@ -44,6 +45,7 @@ public class TestSourceProvider {
4445
private final Map<Description, TestSource> testSourceCache = new ConcurrentHashMap<>();
4546
private final Map<Class<?>, List<Method>> methodsCache = synchronizedMap(new LruCache<>(31));
4647

48+
@Nullable
4749
public TestSource findTestSource(Description description) {
4850
TestSource testSource = testSourceCache.computeIfAbsent(description, this::computeTestSource);
4951
return testSource == NULL_SOURCE ? null : testSource;
@@ -72,6 +74,7 @@ private String sanitizeMethodName(String methodName) {
7274
return methodName;
7375
}
7476

77+
@Nullable
7578
private Method findMethod(Class<?> testClass, String methodName) {
7679
List<Method> methods = methodsCache.computeIfAbsent(testClass,
7780
clazz -> findMethods(clazz, m -> true, TOP_DOWN)).stream() //

junit-vintage-engine/src/main/java/org/junit/vintage/engine/descriptor/VintageTestDescriptor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Set;
2424

2525
import org.apiguardian.api.API;
26+
import org.jspecify.annotations.Nullable;
2627
import org.junit.experimental.categories.Category;
2728
import org.junit.platform.commons.util.ReflectionUtils;
2829
import org.junit.platform.engine.TestDescriptor;
@@ -45,15 +46,16 @@ public class VintageTestDescriptor extends AbstractTestDescriptor {
4546

4647
protected Description description;
4748

48-
public VintageTestDescriptor(UniqueId uniqueId, Description description, TestSource source) {
49+
public VintageTestDescriptor(UniqueId uniqueId, Description description, @Nullable TestSource source) {
4950
this(uniqueId, description, generateDisplayName(description), source);
5051
}
5152

52-
VintageTestDescriptor(UniqueId uniqueId, Description description, String displayName, TestSource source) {
53+
VintageTestDescriptor(UniqueId uniqueId, Description description, String displayName, @Nullable TestSource source) {
5354
super(uniqueId, displayName, source);
5455
this.description = description;
5556
}
5657

58+
@SuppressWarnings("NullAway")
5759
private static String generateDisplayName(Description description) {
5860
String methodName = DescriptionUtils.getMethodName(description);
5961
return isNotBlank(methodName) ? methodName : description.getDisplayName();

junit-vintage-engine/src/main/java/org/junit/vintage/engine/discovery/DefensiveAllDefaultPossibilitiesBuilder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.lang.reflect.Method;
1414
import java.util.function.Predicate;
1515

16+
import org.jspecify.annotations.Nullable;
1617
import org.junit.Ignore;
1718
import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
1819
import org.junit.internal.builders.AnnotatedBuilder;
@@ -108,6 +109,7 @@ private static class DefensiveAnnotatedBuilder extends AnnotatedBuilder {
108109
super(suiteBuilder);
109110
}
110111

112+
@Nullable
111113
@Override
112114
public Runner buildRunner(Class<? extends Runner> runnerClass, Class<?> testClass) throws Exception {
113115
// Referenced by name because it might not be available at runtime.
@@ -127,6 +129,7 @@ private static class DefensiveJUnit4Builder extends JUnit4Builder {
127129

128130
private static final Predicate<Method> isPotentialJUnit4TestMethod = new IsPotentialJUnit4TestMethod();
129131

132+
@Nullable
130133
@Override
131134
public Runner runnerForClass(Class<?> testClass) throws Throwable {
132135
if (containsTestMethods(testClass)) {
@@ -146,6 +149,7 @@ private boolean containsTestMethods(Class<?> testClass) {
146149
* @since 5.1
147150
*/
148151
private static class NullIgnoredBuilder extends IgnoredBuilder {
152+
@Nullable
149153
@Override
150154
public Runner runnerForClass(Class<?> testClass) {
151155
// don't ignore entire test classes just yet

junit-vintage-engine/src/main/java/org/junit/vintage/engine/discovery/MethodSelectorResolver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public boolean shouldRun(Description description) {
107107

108108
private boolean isParameterizedMethod(Description description) {
109109
String methodName = DescriptionUtils.getMethodName(description);
110-
return methodName.startsWith(desiredMethodName + "[");
110+
return methodName != null && methodName.startsWith(desiredMethodName + "[");
111111
}
112112

113113
@Override

junit-vintage-engine/src/main/java/org/junit/vintage/engine/discovery/UniqueIdFilter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Optional;
1919
import java.util.Set;
2020

21+
import org.jspecify.annotations.Nullable;
2122
import org.junit.platform.engine.TestDescriptor;
2223
import org.junit.platform.engine.UniqueId;
2324
import org.junit.runner.Description;
@@ -33,7 +34,10 @@ class UniqueIdFilter extends Filter {
3334
private final RunnerTestDescriptor runnerTestDescriptor;
3435
private final UniqueId uniqueId;
3536

37+
@Nullable
3638
private Deque<Description> path;
39+
40+
@Nullable
3741
private Set<Description> descendants;
3842

3943
UniqueIdFilter(RunnerTestDescriptor runnerTestDescriptor, UniqueId uniqueId) {
@@ -74,6 +78,7 @@ private Set<Description> determineDescendants(Optional<? extends TestDescriptor>
7478
}
7579

7680
@Override
81+
@SuppressWarnings({ "NullAway", "DataFlowIssue" })
7782
public boolean shouldRun(Description description) {
7883
ensureInitialized();
7984
return path.contains(description) || descendants.contains(description);

junit-vintage-engine/src/main/java/org/junit/vintage/engine/execution/TestRun.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
package org.junit.vintage.engine.execution;
1212

1313
import static java.util.Collections.emptyList;
14+
import static java.util.Objects.requireNonNull;
1415
import static java.util.stream.Collectors.toCollection;
1516
import static java.util.stream.Collectors.toList;
1617
import static java.util.stream.Collectors.toMap;
@@ -123,7 +124,7 @@ private Optional<VintageTestDescriptor> lookupUnambiguouslyOrApplyFallback(Descr
123124
void markSkipped(TestDescriptor testDescriptor) {
124125
skippedDescriptors.add(testDescriptor);
125126
if (testDescriptor instanceof VintageTestDescriptor vintageDescriptor) {
126-
descriptionToDescriptors.get(vintageDescriptor.getDescription()).incrementSkippedOrStarted();
127+
getVintageDescriptors(vintageDescriptor).incrementSkippedOrStarted();
127128
}
128129
}
129130

@@ -140,10 +141,15 @@ void markStarted(TestDescriptor testDescriptor, EventType eventType) {
140141
startedDescriptors.add(testDescriptor);
141142
if (testDescriptor instanceof VintageTestDescriptor vintageDescriptor) {
142143
inProgressDescriptorsByStartingThread.get().addLast(vintageDescriptor);
143-
descriptionToDescriptors.get(vintageDescriptor.getDescription()).incrementSkippedOrStarted();
144+
getVintageDescriptors(vintageDescriptor).incrementSkippedOrStarted();
144145
}
145146
}
146147

148+
private VintageDescriptors getVintageDescriptors(VintageTestDescriptor vintageDescriptor) {
149+
return requireNonNull(descriptionToDescriptors.get(vintageDescriptor.getDescription()),
150+
() -> "No descriptors for " + vintageDescriptor);
151+
}
152+
147153
boolean isNotStarted(TestDescriptor testDescriptor) {
148154
return !startedDescriptors.contains(testDescriptor);
149155
}
@@ -191,7 +197,7 @@ TestExecutionResult getStoredResultOrSuccessful(TestDescriptor testDescriptor) {
191197
List<Throwable> failures = testExecutionResults
192198
.stream()
193199
.map(TestExecutionResult::getThrowable)
194-
.map(Optional::get)
200+
.map(Optional::orElseThrow)
195201
.collect(toList());
196202
// @formatter:on
197203
MultipleFailuresError multipleFailuresError = new MultipleFailuresError("", failures);

0 commit comments

Comments
 (0)