[junit] static inner class is allowed without junit5: @Nested and junit4: @RunWith(Enclosed.class) IDEA-374796

GitOrigin-RevId: 9d5dac09d13bbd1ea8f68a6437ef87b43936b9e8
This commit is contained in:
Aleksey Dobrynin
2025-07-04 21:34:42 +00:00
committed by intellij-monorepo-bot
parent d73ad00791
commit 34591b74c7
3 changed files with 44 additions and 11 deletions
@@ -118,6 +118,11 @@ class JavaJUnitMalformedDeclarationInspectionTest {
@org.junit.jupiter.api.Nested
private static class <error descr="Tests in nested class will not be executed">D</error> { }
public static class E {
@org.junit.jupiter.api.Test
public void testFoo() { }
}
}
""".trimIndent())
}
@@ -169,6 +174,16 @@ class JavaJUnitMalformedDeclarationInspectionTest {
}
""".trimIndent())
}
fun `test highlighting executable JUnit 4 static inner class`() {
myFixture.testHighlighting(JvmLanguage.JAVA, """
class A {
public static class B {
@org.junit.Test
public void testFoo() { }
}
}
""".trimIndent())
}
fun `test quickfix no nested annotation in JUnit 4`() {
myFixture.testQuickFix(JvmLanguage.JAVA, """
class A {
@@ -417,6 +432,16 @@ class JavaJUnitMalformedDeclarationInspectionTest {
@org.junit.jupiter.api.Test
void test() { }
}
@org.junit.jupiter.params.ParameterizedClass
@org.junit.jupiter.params.provider.NullSource
static class ClassStaticTest {
@org.junit.jupiter.params.Parameter
Object o;
@org.junit.jupiter.api.Test
void test() { }
}
}
""".trimIndent()
)
@@ -116,11 +116,11 @@ abstract class KotlinJUnitMalformedDeclarationInspectionTestLatest : KotlinJUnit
}
""".trimIndent(), "Fix 'B' class signature", testPreview = true)
}
fun `test highlighting non executable JUnit 4 nested class`() {
fun `test highlighting executable JUnit 4 nested class`() {
myFixture.testHighlighting(
JvmLanguage.KOTLIN, """
class A {
class <error descr="Tests in nested class will not be executed">B</error> {
class B {
@org.junit.Test
fun testFoo() { }
}
@@ -138,24 +138,24 @@ abstract class KotlinJUnitMalformedDeclarationInspectionTestLatest : KotlinJUnit
}
""".trimIndent())
}
fun `test highlighting non executable JUnit 4 nested class top level abstract`() {
fun `test highlighting executable JUnit 4 nested class top level abstract`() {
myFixture.testHighlighting(
JvmLanguage.KOTLIN, """
abstract class A {
class B {
class <error descr="Tests in nested class will not be executed">C</error> {
class C {
@org.junit.Test
fun testFoo() { }
}
}
}
}
""".trimIndent())
}
fun `test quickfix no nested annotation in JUnit 4`() {
myFixture.testQuickFix(
JvmLanguage.KOTLIN, """
class A {
class <caret>B {
inner class <caret>B {
@org.junit.Test
fun testFoo() { }
}
@@ -177,7 +177,12 @@ abstract class KotlinJUnitMalformedDeclarationInspectionTestLatest : KotlinJUnit
myFixture.testHighlighting(
JvmLanguage.KOTLIN, """
class A {
class <error descr="Tests in nested class will not be executed">B</error> {
inner class <error descr="Tests in nested class will not be executed">B</error> {
@org.junit.jupiter.api.Test
fun testFoo() { }
}
class C {
@org.junit.jupiter.api.Test
fun testFoo() { }
}
@@ -1836,7 +1841,7 @@ abstract class KotlinJUnitMalformedDeclarationInspectionTestLatest : KotlinJUnit
@org.junit.Test public fun <error descr="Method 'testFour' annotated with '@Test' should not declare parameter 'i'">testFour</error>(i: Int) { }
@org.junit.Test public fun testFive() { }
@org.junit.Test public fun testMock(@mockit.Mocked s: String) { }
companion <error descr="Test class 'object' is not constructable because it should have exactly one 'public' no-arg constructor"><error descr="Tests in nested class will not be executed">object</error></error> {
companion <error descr="Test class 'object' is not constructable because it should have exactly one 'public' no-arg constructor">object</error> {
@JvmStatic
@org.junit.Test public fun <error descr="Method 'testThree' annotated with '@Test' should be non-static">testThree</error>() { }
}
@@ -350,6 +350,7 @@ private class JUnitMalformedSignatureVisitor(
if (aClass.isInterface || aClass.javaPsi.hasModifier(JvmModifier.ABSTRACT)) return
if (aClass.methods.none { it.javaPsi.hasAnnotation(ORG_JUNIT_TEST) }) return
if (outerClass.uAnnotations.firstOrNull { it.qualifiedName == ORG_JUNIT_RUNNER_RUN_WITH } != null) return
if (aClass.isStatic) return
val message = JUnitBundle.message("jvm.inspections.junit.malformed.missing.nested.annotation.descriptor")
holder.registerUProblem(aClass, message, MakeJUnit4InnerClassRunnableFix(aClass))
}
@@ -384,14 +385,16 @@ private class JUnitMalformedSignatureVisitor(
private fun checkMalformedJUnit5NestedClass(aClass: UClass) {
val javaClass = aClass.javaPsi
if (aClass.isInterface || aClass.javaPsi.hasModifier(JvmModifier.ABSTRACT)) return
if (!javaClass.hasAnnotation(ORG_JUNIT_JUPITER_API_NESTED) && !aClass.methods.any { it.javaPsi.hasAnnotation(ORG_JUNIT_JUPITER_API_TEST) }) return
if (javaClass.hasAnnotation(ORG_JUNIT_JUPITER_API_NESTED) && !aClass.isStatic && aClass.visibility != UastVisibility.PRIVATE) return
val hasNestedAnnotation = javaClass.hasAnnotation(ORG_JUNIT_JUPITER_API_NESTED)
if (!hasNestedAnnotation && !aClass.methods.any { it.javaPsi.hasAnnotation(ORG_JUNIT_JUPITER_API_TEST) }) return
if (!hasNestedAnnotation && aClass.isStatic) return
if (hasNestedAnnotation && !aClass.isStatic && aClass.visibility != UastVisibility.PRIVATE) return
val message = JUnitBundle.message("jvm.inspections.junit.malformed.missing.nested.annotation.descriptor")
val fix = ClassSignatureQuickFix(
aClass.javaPsi.name ?: return,
false,
aClass.visibility == UastVisibility.PRIVATE,
if (javaClass.hasAnnotation(ORG_JUNIT_JUPITER_API_NESTED)) null else ORG_JUNIT_JUPITER_API_NESTED
if (hasNestedAnnotation) null else ORG_JUNIT_JUPITER_API_NESTED
)
holder.registerUProblem(aClass, message, fix)
}