mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Provide AOT support for @Nested classes in a @ParameterizedClass
This commit adds AOT support for discovering @Nested test classes within a @ClassTemplate test class, which includes @ParameterizedClass test classes. Closes gh-35744
This commit is contained in:
+54
-1
@@ -17,10 +17,12 @@
|
||||
package org.springframework.test.context.aot;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
@@ -82,8 +84,10 @@ import static org.springframework.core.annotation.MergedAnnotations.SearchStrate
|
||||
class TestClassScanner {
|
||||
|
||||
// JUnit Jupiter
|
||||
private static final String EXTEND_WITH_ANNOTATION_NAME = "org.junit.jupiter.api.extension.ExtendWith";
|
||||
private static final String SPRING_EXTENSION_NAME = "org.springframework.test.context.junit.jupiter.SpringExtension";
|
||||
private static final String EXTEND_WITH_ANNOTATION_NAME = "org.junit.jupiter.api.extension.ExtendWith";
|
||||
private static final String CLASS_TEMPLATE_ANNOTATION_NAME = "org.junit.jupiter.api.ClassTemplate";
|
||||
private static final String NESTED_ANNOTATION_NAME = "org.junit.jupiter.api.Nested";
|
||||
|
||||
// JUnit 4
|
||||
private static final String RUN_WITH_ANNOTATION_NAME = "org.junit.runner.RunWith";
|
||||
@@ -161,6 +165,7 @@ class TestClassScanner {
|
||||
.map(this::getJavaClass)
|
||||
.flatMap(Optional::stream)
|
||||
.filter(this::isSpringTestClass)
|
||||
.flatMap(this::expandJupiterClassTemplateIfNecessary)
|
||||
.distinct()
|
||||
.sorted(Comparator.comparing(Class::getName));
|
||||
}
|
||||
@@ -184,6 +189,45 @@ class TestClassScanner {
|
||||
return isSpringTestClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the supplied test class into a stream containing the supplied test
|
||||
* class. If the supplied class is a JUnit Jupiter {@code @ClassTemplate}
|
||||
* (such as a {@code @ParameterizedClass}), the returned stream will also
|
||||
* contain {@code @Nested} test classes associated with the supplied test
|
||||
* class.
|
||||
* @since 7.0
|
||||
*/
|
||||
private Stream<Class<?>> expandJupiterClassTemplateIfNecessary(Class<?> testClass) {
|
||||
if (isJupiterClassTemplate(testClass)) {
|
||||
Set<Class<?>> testClasses = new HashSet<>();
|
||||
collectNestedTestClasses(testClass, testClasses, new HashSet<>());
|
||||
testClasses.add(testClass);
|
||||
return testClasses.stream();
|
||||
}
|
||||
return Stream.of(testClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all {@code @Nested} test classes declared in the superclass hierarchy
|
||||
* of the supplied test class as well as {@code @Nested} test classes declared
|
||||
* in the supplied test class itself, recursively.
|
||||
* @since 7.0
|
||||
*/
|
||||
private static void collectNestedTestClasses(Class<?> testClass, Set<Class<?>> testClasses, Set<Class<?>> visited) {
|
||||
if (visited.add(testClass)) {
|
||||
Class<?> superclass = testClass.getSuperclass();
|
||||
if (superclass != null && superclass != Object.class) {
|
||||
collectNestedTestClasses(superclass, testClasses, visited);
|
||||
}
|
||||
for (Class<?> nestedClass : testClass.getDeclaredClasses()) {
|
||||
if (isJupiterNestedClass(nestedClass)) {
|
||||
testClasses.add(nestedClass);
|
||||
collectNestedTestClasses(nestedClass, testClasses, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isJupiterSpringTestClass(Class<?> clazz) {
|
||||
return MergedAnnotations.search(TYPE_HIERARCHY)
|
||||
.withEnclosingClasses(ClassUtils::isInnerClass)
|
||||
@@ -195,6 +239,15 @@ class TestClassScanner {
|
||||
.anyMatch(SPRING_EXTENSION_NAME::equals);
|
||||
}
|
||||
|
||||
private static boolean isJupiterClassTemplate(Class<?> clazz) {
|
||||
return MergedAnnotations.from(clazz, TYPE_HIERARCHY).isPresent(CLASS_TEMPLATE_ANNOTATION_NAME);
|
||||
}
|
||||
|
||||
private static boolean isJupiterNestedClass(Class<?> clazz) {
|
||||
return (!Modifier.isAbstract(clazz.getModifiers()) && ClassUtils.isInnerClass(clazz) &&
|
||||
MergedAnnotations.from(clazz, TYPE_HIERARCHY).isPresent(NESTED_ANNOTATION_NAME));
|
||||
}
|
||||
|
||||
private static boolean isJUnit4SpringTestClass(Class<?> clazz) {
|
||||
MergedAnnotation<Annotation> mergedAnnotation =
|
||||
MergedAnnotations.from(clazz, INHERITED_ANNOTATIONS).get(RUN_WITH_ANNOTATION_NAME);
|
||||
|
||||
Reference in New Issue
Block a user