Skip to content

Commit 28a8384

Browse files
committed
Fix StackOverflowError
1 parent 1812df4 commit 28a8384

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/discovery/predicates/TestClassPredicates.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import static org.junit.platform.commons.util.ReflectionUtils.isNestedClassPresent;
2121

2222
import java.lang.reflect.Method;
23+
import java.util.HashSet;
24+
import java.util.Set;
2325
import java.util.function.Predicate;
2426

2527
import org.apiguardian.api.API;
@@ -65,9 +67,16 @@ public TestClassPredicates(DiscoveryIssueReporter issueReporter) {
6567
}
6668

6769
public boolean looksLikeIntendedTestClass(Class<?> candidate) {
68-
return this.isAnnotatedWithClassTemplate.test(candidate) //
69-
|| hasTestOrTestFactoryOrTestTemplateMethods(candidate) //
70-
|| hasNestedTests(candidate);
70+
return looksLikeIntendedTestClass(candidate, new HashSet<>());
71+
}
72+
73+
private boolean looksLikeIntendedTestClass(Class<?> candidate, Set<Class<?>> seen) {
74+
if (seen.add(candidate)) {
75+
return this.isAnnotatedWithClassTemplate.test(candidate) //
76+
|| hasTestOrTestFactoryOrTestTemplateMethods(candidate) //
77+
|| hasNestedTests(candidate, seen);
78+
}
79+
return false;
7180
}
7281

7382
public boolean isValidNestedTestClass(Class<?> candidate) {
@@ -84,11 +93,11 @@ private boolean hasTestOrTestFactoryOrTestTemplateMethods(Class<?> candidate) {
8493
return isMethodPresent(candidate, this.isTestOrTestFactoryOrTestTemplateMethod);
8594
}
8695

87-
private boolean hasNestedTests(Class<?> candidate) {
96+
private boolean hasNestedTests(Class<?> candidate, Set<Class<?>> seen) {
8897
return isNestedClassPresent( //
8998
candidate, //
9099
isNotSame(candidate).and(
91-
this.isAnnotatedWithNested.or(it -> isInnerClass(it) && looksLikeIntendedTestClass(it))));
100+
this.isAnnotatedWithNested.or(it -> isInnerClass(it) && looksLikeIntendedTestClass(it, seen))));
92101
}
93102

94103
private static Predicate<Class<?>> isNotSame(Class<?> candidate) {

jupiter-tests/src/test/java/org/junit/jupiter/engine/discovery/DiscoveryTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,13 @@ void reportsWarningForTestClassWithPotentialNestedTestClasses() {
288288
InvalidTestCases.InvalidTestClassTestCase.class.getName());
289289
}
290290

291+
@Test
292+
void ignoresUnrelatedClassDefinitionCycles() {
293+
var results = discoverTestsForClass(UnrelatedRecursiveHierarchyTestCase.class);
294+
295+
assertThat(results.getDiscoveryIssues()).isEmpty();
296+
}
297+
291298
@Test
292299
void reportsWarningsForInvalidTags() throws NoSuchMethodException {
293300

@@ -441,6 +448,20 @@ private class InvalidTestClassSubclassTestCase extends InvalidTestClassTestCase
441448

442449
}
443450

451+
@SuppressWarnings("JUnitMalformedDeclaration")
452+
static class UnrelatedRecursiveHierarchyTestCase {
453+
454+
@Test
455+
void test() {
456+
}
457+
458+
@SuppressWarnings({ "InnerClassMayBeStatic", "unused" })
459+
class Inner {
460+
class Recursive extends Inner {
461+
}
462+
}
463+
}
464+
444465
@SuppressWarnings("JUnitMalformedDeclaration")
445466
@Tag("")
446467
static class InvalidTagsTestCase {

0 commit comments

Comments
 (0)