mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[junit 5, inspection] fix @MethodSource factory method resolving IDEA-375007
GitOrigin-RevId: 584f4c4e534ec356131a86f7abd42aada18fddd0
This commit is contained in:
committed by
intellij-monorepo-bot
parent
10b68df268
commit
96da5ea3cf
+42
@@ -669,6 +669,10 @@ class JavaJUnitMalformedDeclarationInspectionTest {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("intStreamProvider")
|
||||
void injectTestReporter(int x, org.junit.jupiter.api.TestReporter testReporter) { System.out.println(x); }
|
||||
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("intStreamProvider")
|
||||
void intStreamProvider(int x, org.junit.jupiter.api.TestReporter testReporter) { System.out.println(x); }
|
||||
|
||||
static java.util.stream.Stream<org.junit.jupiter.params.provider.Arguments> stream() { return null; }
|
||||
static java.util.Iterator<org.junit.jupiter.params.provider.Arguments> iterator() { return null; }
|
||||
@@ -705,6 +709,44 @@ class JavaJUnitMalformedDeclarationInspectionTest {
|
||||
public java.util.stream.Stream getParameters() { return java.util.Arrays.asList( "Another execution", "Last execution").stream(); }
|
||||
}
|
||||
|
||||
@PerClass
|
||||
abstract class PerClassBase1 {
|
||||
public java.util.stream.Stream getParameters() { return java.util.Arrays.asList( "Another execution", "Last execution").stream(); }
|
||||
}
|
||||
|
||||
class PerClassTest1 extends PerClassBase1 {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("getParameters")
|
||||
public void shouldExecuteWithParameterizedMethodSource(String arguments) { }
|
||||
}
|
||||
|
||||
abstract class PerClassBase2 {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("getParameters")
|
||||
public void shouldExecuteWithParameterizedMethodSource(String arguments) { }
|
||||
}
|
||||
|
||||
@PerClass
|
||||
class PerClassTest2 extends PerClassBase2 {
|
||||
public java.util.stream.Stream getParameters() { return java.util.Arrays.asList( "Another execution", "Last execution").stream(); }
|
||||
}
|
||||
|
||||
abstract class PerClassBase3 {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("getParameters")
|
||||
public void shouldExecuteWithParameterizedMethodSource(String arguments) { }
|
||||
|
||||
public java.util.stream.Stream getParameters() { return java.util.Arrays.asList( "Another execution", "Last execution").stream(); }
|
||||
}
|
||||
|
||||
@PerClass
|
||||
class PerClassTest3 extends PerClassBase3 {
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@org.junit.jupiter.api.TestInstance(org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS)
|
||||
@interface PerClass { }
|
||||
|
||||
class EnumSource {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.EnumSource(names = "FIRST")
|
||||
|
||||
+41
@@ -609,6 +609,47 @@ abstract class KotlinJUnitMalformedDeclarationInspectionTestLatest : KotlinJUnit
|
||||
fun injectTestReporter(x: Int, testReporter: org.junit.jupiter.api.TestReporter) {
|
||||
System.out.println("${'$'}x, ${'$'}testReporter")
|
||||
}
|
||||
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("intStreamProvider")
|
||||
fun intStreamProvider(x: Int, testReporter: org.junit.jupiter.api.TestReporter) { System.out.println("${'$'}x, ${'$'}testReporter") }
|
||||
|
||||
@PerClass
|
||||
abstract class PerClassBase1 {
|
||||
fun getParameters() = java.util.stream.Stream.of("Another execution", "Last execution")
|
||||
}
|
||||
|
||||
class PerClassTest1 : PerClassBase1() {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("getParameters")
|
||||
fun shouldExecuteWithParameterizedMethodSource(arguments: String) = Unit
|
||||
}
|
||||
|
||||
abstract class PerClassBase2 {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("getParameters")
|
||||
fun shouldExecuteWithParameterizedMethodSource(arguments: String) = Unit
|
||||
}
|
||||
|
||||
@PerClass
|
||||
class PerClassTest2 : PerClassBase2() {
|
||||
fun getParameters() = java.util.stream.Stream.of("Another execution", "Last execution")
|
||||
}
|
||||
|
||||
abstract class PerClassBase3 {
|
||||
@org.junit.jupiter.params.ParameterizedTest
|
||||
@org.junit.jupiter.params.provider.MethodSource("getParameters")
|
||||
fun shouldExecuteWithParameterizedMethodSource(arguments: String) = Unit
|
||||
|
||||
fun getParameters() = java.util.stream.Stream.of("Another execution", "Last execution")
|
||||
}
|
||||
|
||||
@PerClass
|
||||
class PerClassTest3 : PerClassBase3()
|
||||
|
||||
@kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME)
|
||||
@org.junit.jupiter.api.TestInstance(org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS)
|
||||
annotation class PerClass
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
|
||||
+18
-12
@@ -46,6 +46,12 @@ abstract class BaseJunitAnnotationReference(
|
||||
return if (results.size == 1) results[0].element else null
|
||||
}
|
||||
|
||||
private fun filteredMethod(clazzMethods: Array<PsiMethod>, uClass: UClass, testMethod: UMethod?): List<PsiMethod> {
|
||||
val noStaticProblem = clazzMethods.filter { hasNoStaticProblem(it, uClass, testMethod) }
|
||||
if (noStaticProblem.isNotEmpty()) return noStaticProblem
|
||||
return clazzMethods.toList()
|
||||
}
|
||||
|
||||
override fun getVariants(): Array<Any> {
|
||||
val myLiteral = element.toUElement(UExpression::class.java) ?: return emptyArray()
|
||||
val topLevelClass = myLiteral.getParentOfType(UClass::class.java) ?: return emptyArray()
|
||||
@@ -76,24 +82,24 @@ abstract class BaseJunitAnnotationReference(
|
||||
* @param scope The class scope used to resolve the method reference.
|
||||
* @return The resolved `PsiMethod` if found, or `null` if the method cannot be resolved or the link is not direct.
|
||||
*/
|
||||
private fun directLink(literal: UExpression, scope: UClass): PsiMethod? {
|
||||
private fun directLink(literal: UExpression, scope: UClass, testMethod: UMethod?): PsiMethod? {
|
||||
val string = literal.evaluate() as String? ?: return null
|
||||
val className = StringUtil.getPackageName(string, '#')
|
||||
if (className.isEmpty()) return null
|
||||
val methodName = StringUtil.getShortName(string, '#')
|
||||
if (methodName.isEmpty()) return null
|
||||
val directClass = ClassUtil.findPsiClass(scope.javaPsi.manager, className, null, false, scope.javaPsi.resolveScope) ?: return null
|
||||
return directClass.findMethodsByName(methodName, false).firstOrNull()
|
||||
return filteredMethod(directClass.findMethodsByName(methodName, false), scope, testMethod).firstOrNull()
|
||||
}
|
||||
|
||||
private fun fastResolveFor(literal: UExpression, scope: UClass): Set<PsiMethod> {
|
||||
private fun fastResolveFor(literal: UExpression, scope: UClass, testMethod: UMethod?): Set<PsiMethod> {
|
||||
val methodName = literal.evaluate() as String? ?: return setOf()
|
||||
val psiClazz = scope.javaPsi
|
||||
val clazzMethods = psiClazz.findMethodsByName(methodName, true)
|
||||
val clazzMethods = filteredMethod(psiClazz.findMethodsByName(methodName, true), scope, testMethod)
|
||||
|
||||
val methods = ClassInheritorsSearch.search(psiClazz, psiClazz.resolveScope, true)
|
||||
.findAll()
|
||||
.flatMap { aClazz -> aClazz.findMethodsByName(methodName, true).toList() }
|
||||
.mapNotNull { aClazz -> aClazz.toUElement(UClass::class.java) }
|
||||
.flatMap { uClazz -> filteredMethod(uClazz.javaPsi.findMethodsByName(methodName, true), uClazz, testMethod) }
|
||||
.toMutableSet()
|
||||
methods.addAll(clazzMethods)
|
||||
return methods
|
||||
@@ -106,10 +112,10 @@ abstract class BaseJunitAnnotationReference(
|
||||
private fun fastResolveFor(testMethod: UMethod): Set<PsiMethod> {
|
||||
val literal = element.toUElement(UExpression::class.java) ?: return setOf()
|
||||
val scope = literal.getParentOfType(UClass::class.java) ?: return setOf()
|
||||
val directLink = directLink(literal, scope)
|
||||
val directLink = directLink(literal, scope, testMethod)
|
||||
if (directLink != null) return setOf(directLink)
|
||||
val currentClass = testMethod.getParentOfType(UClass::class.java) ?: return setOf()
|
||||
return fastResolveFor(literal, currentClass)
|
||||
return fastResolveFor(literal, currentClass, testMethod)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,10 +131,10 @@ abstract class BaseJunitAnnotationReference(
|
||||
override fun resolve(ref: BaseJunitAnnotationReference, incompleteCode: Boolean): Array<ResolveResult> {
|
||||
val literal = ref.element.toUElement(UExpression::class.java) ?: return ResolveResult.EMPTY_ARRAY
|
||||
val uClass = literal.getParentOfType(UClass::class.java) ?: return ResolveResult.EMPTY_ARRAY
|
||||
val directLink = ref.directLink(literal, uClass)
|
||||
val method = literal.getParentOfType(UMethod::class.java)
|
||||
val directLink = ref.directLink(literal, uClass, method)
|
||||
if (directLink != null) return arrayOf(PsiMethodSourceResolveResult(directLink, listOf()))
|
||||
|
||||
val method = literal.getParentOfType(UMethod::class.java)
|
||||
if (method != null) { // direct annotation
|
||||
val owners = method.javaPsi.containingClass?.let { listOf(it) } ?: emptyList()
|
||||
return ref.fastResolveFor(method).map { PsiMethodSourceResolveResult(it, owners) }.toTypedArray()
|
||||
@@ -154,7 +160,7 @@ abstract class BaseJunitAnnotationReference(
|
||||
.mapNotNull { method -> method.toUElement(UMethod::class.java) }
|
||||
.mapNotNull { method -> method.getParentOfType(UClass::class.java) }
|
||||
.distinct() // process only classes
|
||||
.map{ clazz -> clazz to ref.fastResolveFor(literal, clazz) }
|
||||
.map{ clazz -> clazz to ref.fastResolveFor(literal, clazz, method) }
|
||||
.flatMap { (clazz, methods) -> methods.map { method -> method to clazz } }
|
||||
.groupBy({ it.first }, { it.second })
|
||||
.map { (method, classes) -> PsiMethodSourceResolveResult(method, classes) }.toTypedArray()
|
||||
@@ -162,7 +168,7 @@ abstract class BaseJunitAnnotationReference(
|
||||
val clazz = literal.getParentOfType(UClass::class.java)
|
||||
if (clazz != null) {
|
||||
val owners = clazz.javaPsi.containingClass?.let { listOf(it) } ?: emptyList()
|
||||
return ref.fastResolveFor(literal, clazz).map { PsiMethodSourceResolveResult(it, owners) }.toTypedArray()
|
||||
return ref.fastResolveFor(literal, clazz, method).map { PsiMethodSourceResolveResult(it, owners) }.toTypedArray()
|
||||
} else {
|
||||
return ResolveResult.EMPTY_ARRAY
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user