From 40a5bf035532d2fe571baaf635477f249431e270 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 2 Aug 2018 19:12:39 +0300 Subject: [PATCH] Gradle: Support Gradle test runner for TestNG tests #KT-22732 Fixed --- idea/idea-gradle/build.gradle.kts | 1 + idea/idea-gradle/build.gradle.kts.173 | 1 + idea/idea-gradle/build.gradle.kts.as31 | 1 + idea/idea-gradle/build.gradle.kts.as32 | 1 + idea/idea-gradle/build.gradle.kts.as33 | 1 + ...otlinGradleTestRunConfigurationProducer.kt | 41 ++++++---- .../KotlinTestNgConfigurationProducer.java | 74 +++++++++++-------- 7 files changed, 75 insertions(+), 45 deletions(-) diff --git a/idea/idea-gradle/build.gradle.kts b/idea/idea-gradle/build.gradle.kts index 707dccf6d2b..ba81995be0c 100644 --- a/idea/idea-gradle/build.gradle.kts +++ b/idea/idea-gradle/build.gradle.kts @@ -20,6 +20,7 @@ dependencies { compileOnly(intellijPluginDep("gradle")) compileOnly(intellijPluginDep("Groovy")) compileOnly(intellijPluginDep("junit")) + compileOnly(intellijPluginDep("testng")) testCompile(projectTests(":idea")) testCompile(projectTests(":idea:idea-test-framework")) diff --git a/idea/idea-gradle/build.gradle.kts.173 b/idea/idea-gradle/build.gradle.kts.173 index 212fc8253f2..a059a6e6de3 100644 --- a/idea/idea-gradle/build.gradle.kts.173 +++ b/idea/idea-gradle/build.gradle.kts.173 @@ -20,6 +20,7 @@ dependencies { compileOnly(intellijPluginDep("gradle")) compileOnly(intellijPluginDep("Groovy")) compileOnly(intellijPluginDep("junit")) + compileOnly(intellijPluginDep("testng")) testCompile(projectTests(":idea")) testCompile(projectTests(":idea:idea-test-framework")) diff --git a/idea/idea-gradle/build.gradle.kts.as31 b/idea/idea-gradle/build.gradle.kts.as31 index a3ecc33d3eb..acf0a28b220 100644 --- a/idea/idea-gradle/build.gradle.kts.as31 +++ b/idea/idea-gradle/build.gradle.kts.as31 @@ -20,6 +20,7 @@ dependencies { compileOnly(intellijPluginDep("gradle")) compileOnly(intellijPluginDep("Groovy")) compileOnly(intellijPluginDep("junit")) + compileOnly(intellijPluginDep("testng")) testCompile(projectTests(":idea")) testCompile(projectTests(":idea:idea-test-framework")) diff --git a/idea/idea-gradle/build.gradle.kts.as32 b/idea/idea-gradle/build.gradle.kts.as32 index a3ecc33d3eb..acf0a28b220 100644 --- a/idea/idea-gradle/build.gradle.kts.as32 +++ b/idea/idea-gradle/build.gradle.kts.as32 @@ -20,6 +20,7 @@ dependencies { compileOnly(intellijPluginDep("gradle")) compileOnly(intellijPluginDep("Groovy")) compileOnly(intellijPluginDep("junit")) + compileOnly(intellijPluginDep("testng")) testCompile(projectTests(":idea")) testCompile(projectTests(":idea:idea-test-framework")) diff --git a/idea/idea-gradle/build.gradle.kts.as33 b/idea/idea-gradle/build.gradle.kts.as33 index a3ecc33d3eb..acf0a28b220 100644 --- a/idea/idea-gradle/build.gradle.kts.as33 +++ b/idea/idea-gradle/build.gradle.kts.as33 @@ -20,6 +20,7 @@ dependencies { compileOnly(intellijPluginDep("gradle")) compileOnly(intellijPluginDep("Groovy")) compileOnly(intellijPluginDep("junit")) + compileOnly(intellijPluginDep("testng")) testCompile(projectTests(":idea")) testCompile(projectTests(":idea:idea-test-framework")) diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/KotlinGradleTestRunConfigurationProducer.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/KotlinGradleTestRunConfigurationProducer.kt index 5b51df53dc1..a38bca86200 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/KotlinGradleTestRunConfigurationProducer.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/KotlinGradleTestRunConfigurationProducer.kt @@ -24,6 +24,8 @@ import com.intellij.openapi.extensions.PluginId.getId import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil import com.intellij.openapi.util.Ref +import com.intellij.openapi.util.component1 +import com.intellij.openapi.util.component2 import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiMethod @@ -31,7 +33,23 @@ import org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigu import org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer import org.jetbrains.plugins.gradle.util.GradleConstants -private val IS_JUNIT_INSTALLED by lazy { PluginManager.isPluginInstalled(getId("JUnit")) } +private val IS_TEST_FRAMEWORK_PLUGIN_INSTALLED by lazy { + PluginManager.isPluginInstalled(getId("JUnit")) || PluginManager.isPluginInstalled(getId("TestNG-J")) +} + +private fun getTestClass(leaf: PsiElement): PsiClass? { + KotlinJUnitRunConfigurationProducer.getTestClass(leaf)?.let { return it } + KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.let { (testClass, testMethod) -> + return if (testMethod == null) testClass else null + } + return null +} + +private fun getTestMethod(leaf: PsiElement): PsiMethod? { + KotlinJUnitRunConfigurationProducer.getTestMethodLocation(leaf)?.psiElement?.let { return it } + KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.second?.let { return it } + return null +} class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationProducer() { override fun doSetupConfigurationFromContext( @@ -39,7 +57,7 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP context: ConfigurationContext, sourceElement: Ref ): Boolean { - if (!IS_JUNIT_INSTALLED) return false + if (!IS_TEST_FRAMEWORK_PLUGIN_INSTALLED) return false val contextLocation = context.location ?: return false val module = context.module ?: return false @@ -48,7 +66,7 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP return false } val leaf = context.location?.psiElement ?: return false - val testClass = KotlinJUnitRunConfigurationProducer.getTestClass(leaf) ?: return false + val testClass = getTestClass(leaf) ?: return false sourceElement.set(testClass) if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false @@ -68,7 +86,7 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP } override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean { - if (!IS_JUNIT_INSTALLED) return false + if (!IS_TEST_FRAMEWORK_PLUGIN_INSTALLED) return false val leaf = context.location?.psiElement ?: return false if (context.module == null) return false @@ -77,10 +95,9 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP return false } - val methodLocation = KotlinJUnitRunConfigurationProducer.getTestMethodLocation(leaf) - if (methodLocation != null) return false + if (getTestMethod(leaf) != null) return false - val testClass = KotlinJUnitRunConfigurationProducer.getTestClass(leaf) + val testClass = getTestClass(leaf) if (testClass == null || testClass.qualifiedName == null) return false @@ -105,7 +122,7 @@ class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfiguratio context: ConfigurationContext, sourceElement: Ref ): Boolean { - if (!IS_JUNIT_INSTALLED) return false + if (!IS_TEST_FRAMEWORK_PLUGIN_INSTALLED) return false val contextLocation = context.location ?: return false if (context.module == null) return false @@ -114,8 +131,7 @@ class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfiguratio return false } - val methodLocation = KotlinJUnitRunConfigurationProducer.getTestMethodLocation(contextLocation.psiElement) ?: return false - val psiMethod = methodLocation.psiElement + val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false sourceElement.set(psiMethod) val containingClass = psiMethod.containingClass ?: return false @@ -128,7 +144,7 @@ class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfiguratio } override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean { - if (!IS_JUNIT_INSTALLED) return false + if (!IS_TEST_FRAMEWORK_PLUGIN_INSTALLED) return false if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) { return false @@ -137,8 +153,7 @@ class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfiguratio val contextLocation = context.location ?: return false val module = context.module ?: return false - val methodLocation = KotlinJUnitRunConfigurationProducer.getTestMethodLocation(contextLocation.psiElement) ?: return false - val psiMethod = methodLocation.psiElement + val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false val containingClass = psiMethod.containingClass ?: return false diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinTestNgConfigurationProducer.java b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinTestNgConfigurationProducer.java index afdffa7d144..073e9533344 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinTestNgConfigurationProducer.java +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/run/KotlinTestNgConfigurationProducer.java @@ -32,6 +32,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; import com.intellij.psi.util.PsiClassUtil; @@ -47,7 +48,6 @@ import org.jetbrains.kotlin.idea.project.TargetPlatformDetector; import org.jetbrains.kotlin.idea.util.ProjectRootsUtil; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform; -import org.jetbrains.kotlin.asJava.LightClassUtilsKt; import java.util.List; @@ -126,39 +126,14 @@ public class KotlinTestNgConfigurationProducer extends TestNGConfigurationProduc return false; } - KtNamedDeclaration declarationToRun = getDeclarationToRun(leaf); + Pair classAndMethod = getTestClassAndMethod(leaf); + if (classAndMethod == null) return false; - if (declarationToRun instanceof KtNamedFunction) { - KtNamedFunction function = (KtNamedFunction) declarationToRun; + PsiClass testClass = classAndMethod.getFirst(); + if (testClass == null) return false; + PsiMethod testMethod = classAndMethod.getSecond(); - @SuppressWarnings("unchecked") - KtElement owner = PsiTreeUtil.getParentOfType(function, KtFunction.class, KtClass.class); - - if (owner instanceof KtClass) { - PsiClass delegate = toLightClass((KtClass) owner); - if (delegate != null) { - for (PsiMethod method : delegate.getMethods()) { - if (method.getNavigationElement() == function) { - if (TestNGUtil.hasTest(method)) { - return configure(configuration, location, context, project, delegate, method); - } - break; - } - } - } - } - } - - if (declarationToRun instanceof KtClass) { - PsiClass delegate = toLightClass((KtClassOrObject) declarationToRun); - if (!isTestNGClass(delegate)) { - return false; - } - - return configure(configuration, location, context, project, delegate, null); - } - - return false; + return configure(configuration, location, context, project, testClass, testMethod); } @Override @@ -275,4 +250,39 @@ public class KotlinTestNgConfigurationProducer extends TestNGConfigurationProduc return tempSingleDeclaration; } + + @Nullable + public static Pair getTestClassAndMethod(@NotNull PsiElement leaf) { + KtNamedDeclaration declarationToRun = getDeclarationToRun(leaf); + + if (declarationToRun instanceof KtNamedFunction) { + KtNamedFunction function = (KtNamedFunction) declarationToRun; + + @SuppressWarnings("unchecked") + KtElement owner = PsiTreeUtil.getParentOfType(function, KtFunction.class, KtClass.class); + + if (owner instanceof KtClass) { + PsiClass delegate = toLightClass((KtClass) owner); + if (delegate != null) { + for (PsiMethod method : delegate.getMethods()) { + if (method.getNavigationElement() == function) { + if (TestNGUtil.hasTest(method)) { + return new Pair<>(delegate, method); + } + break; + } + } + } + } + } + + if (declarationToRun instanceof KtClass) { + PsiClass delegate = toLightClass((KtClassOrObject) declarationToRun); + if (isTestNGClass(delegate)) { + return new Pair<>(delegate, null); + } + } + + return null; + } }