Minor: refactor KotlinJUnitRunConfigurationProducer

Clarify 'getTestMethod' and 'onFirstRun' functions
This commit is contained in:
Pavel V. Talanov
2018-11-08 17:44:29 +01:00
parent 47935c19e6
commit aae023909d
2 changed files with 33 additions and 24 deletions
@@ -54,7 +54,7 @@ private fun getTestClass(leaf: PsiElement): PsiClass? {
private fun getTestMethod(leaf: PsiElement): PsiMethod? { private fun getTestMethod(leaf: PsiElement): PsiMethod? {
if (IS_JUNIT_ENABLED) { if (IS_JUNIT_ENABLED) {
KotlinJUnitRunConfigurationProducer.getTestMethodLocation(leaf)?.psiElement?.let { return it } KotlinJUnitRunConfigurationProducer.getTestMethod(leaf)?.let { return it }
} }
if (IS_TESTNG_ENABLED) { if (IS_TESTNG_ENABLED) {
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.second?.let { return it } KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.second?.let { return it }
@@ -5,17 +5,20 @@
package org.jetbrains.kotlin.idea.run package org.jetbrains.kotlin.idea.run
import com.intellij.execution.* import com.intellij.execution.CommonJavaRunConfigurationParameters
import com.intellij.execution.PsiLocation
import com.intellij.execution.RunManager
import com.intellij.execution.RunnerAndConfigurationSettings
import com.intellij.execution.actions.ConfigurationContext import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.ConfigurationFromContext import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.execution.actions.RunConfigurationProducer import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.execution.configurations.ModuleBasedConfiguration
import com.intellij.execution.junit.* import com.intellij.execution.junit.*
import com.intellij.execution.testframework.AbstractPatternBasedConfigurationProducer import com.intellij.execution.testframework.AbstractPatternBasedConfigurationProducer
import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.DumbService
import com.intellij.openapi.util.Ref import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiClass import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMember
import com.intellij.psi.PsiMethod import com.intellij.psi.PsiMethod
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.asJava.toLightClass
@@ -40,11 +43,11 @@ class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfig
} }
val leaf = context.location?.psiElement ?: return false val leaf = context.location?.psiElement ?: return false
val methodLocation = getTestMethodLocation(leaf) val method = getTestMethod(leaf)
val testClass = getTestClass(leaf) val testClass = getTestClass(leaf)
val testObject = configuration.testObject val testObject = configuration.testObject
if (!testObject.isConfiguredByElement(configuration, testClass, methodLocation?.psiElement, null, null)) { if (!testObject.isConfiguredByElement(configuration, testClass, method, null, null)) {
return false return false
} }
@@ -83,9 +86,9 @@ class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfig
return false return false
} }
val methodLocation = getTestMethodLocation(leaf) val method = getTestMethod(leaf)
if (methodLocation != null) { if (method != null) {
configuration.beMethodConfiguration(methodLocation) configuration.beMethodConfiguration(method.toLocation())
JavaRunConfigurationExtensionManagerUtil.getInstance().extendCreatedConfiguration(configuration, location) JavaRunConfigurationExtensionManagerUtil.getInstance().extendCreatedConfiguration(configuration, location)
configuration.setModule(module) configuration.setModule(module)
return true return true
@@ -104,22 +107,27 @@ class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfig
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) { override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
val leaf = fromContext.sourceElement val leaf = fromContext.sourceElement
getTestClass(leaf)?.let { testClass -> val sourceElement = getTestClass(leaf) ?: return super.onFirstRun(fromContext, context, performRunnable)
val fromContextSubstitute = object : ConfigurationFromContext() {
override fun getConfigurationSettings() = fromContext.configurationSettings
override fun setConfigurationSettings(configurationSettings: RunnerAndConfigurationSettings) { val contextWithLightElement = createDelegatingContextWithLightElement(fromContext, sourceElement)
fromContext.configurationSettings = configurationSettings // TODO: use TestClassConfigurationProducer when constructor becomes public
} return object : AbstractTestClassConfigurationProducer(JUnitConfigurationType.getInstance()) {}
.onFirstRun(contextWithLightElement, context, performRunnable)
}
override fun getSourceElement() = testClass private fun createDelegatingContextWithLightElement(
fromContext: ConfigurationFromContext,
lightElement: PsiMember
): ConfigurationFromContext {
return object : ConfigurationFromContext() {
override fun getConfigurationSettings() = fromContext.configurationSettings
override fun setConfigurationSettings(configurationSettings: RunnerAndConfigurationSettings) {
fromContext.configurationSettings = configurationSettings
} }
// TODO: use TestClassConfigurationProducer when constructor becomes public
return object : AbstractTestClassConfigurationProducer(JUnitConfigurationType.getInstance()){}
.onFirstRun(fromContextSubstitute, context, performRunnable)
}
super.onFirstRun(fromContext, context, performRunnable) override fun getSourceElement() = lightElement
}
} }
companion object { companion object {
@@ -132,16 +140,15 @@ class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfig
return ktClass?.toLightClass() return ktClass?.toLightClass()
} }
fun getTestMethodLocation(leaf: PsiElement): Location<PsiMethod>? { fun getTestMethod(leaf: PsiElement): PsiMethod? {
val function = leaf.getParentOfType<KtNamedFunction>(false) ?: return null val function = leaf.getParentOfType<KtNamedFunction>(false) ?: return null
val owner = PsiTreeUtil.getParentOfType(function, KtFunction::class.java, KtClass::class.java) val owner = PsiTreeUtil.getParentOfType(function, KtFunction::class.java, KtClass::class.java)
if (owner is KtClass) { if (owner is KtClass) {
val delegate = owner.toLightClass() ?: return null val delegate = owner.toLightClass() ?: return null
val method = delegate.methods.firstOrNull() { it.navigationElement == function } ?: return null val method = delegate.methods.firstOrNull() { it.navigationElement == function } ?: return null
val methodLocation = PsiLocation.fromPsiElement(method) if (JUnitUtil.isTestMethod(method.toLocation(), false)) {
if (JUnitUtil.isTestMethod(methodLocation, false)) { return method
return methodLocation
} }
} }
return null return null
@@ -154,3 +161,5 @@ class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfig
ktFile.declarations.filterIsInstance<KtClass>().singleOrNull { it.isJUnitTestClass() } ktFile.declarations.filterIsInstance<KtClass>().singleOrNull { it.isJUnitTestClass() }
} }
} }
private fun PsiMethod.toLocation() = PsiLocation.fromPsiElement(this)