diff --git a/idea/src/META-INF/junit.xml b/idea/src/META-INF/junit.xml
index 099716d030a..7484657e0f0 100644
--- a/idea/src/META-INF/junit.xml
+++ b/idea/src/META-INF/junit.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/run/JetTestNgConfigurationProducer.java b/idea/src/org/jetbrains/kotlin/idea/run/JetTestNgConfigurationProducer.java
index a2662807dc6..a3f73d4211e 100644
--- a/idea/src/org/jetbrains/kotlin/idea/run/JetTestNgConfigurationProducer.java
+++ b/idea/src/org/jetbrains/kotlin/idea/run/JetTestNgConfigurationProducer.java
@@ -90,7 +90,7 @@ public class JetTestNgConfigurationProducer extends TestNGConfigurationProducer
JetClass jetClass = PsiTreeUtil.getParentOfType(leaf, JetClass.class, false);
if (jetClass == null) {
- jetClass = KotlinJUnitRunConfigurationProducer.Companion.getClassDeclarationInFile(jetFile);
+ jetClass = getClassDeclarationInFile(jetFile);
}
if (jetClass == null) {
@@ -128,4 +128,25 @@ public class JetTestNgConfigurationProducer extends TestNGConfigurationProducer
private static boolean isTestNGClass(PsiClass psiClass) {
return psiClass != null && PsiClassUtil.isRunnableClass(psiClass, true, false) && TestNGUtil.hasTest(psiClass);
}
+
+ @Nullable
+ static JetClass getClassDeclarationInFile(JetFile jetFile) {
+ JetClass tempSingleDeclaration = null;
+
+ for (JetDeclaration jetDeclaration : jetFile.getDeclarations()) {
+ if (jetDeclaration instanceof JetClass) {
+ JetClass declaration = (JetClass) jetDeclaration;
+
+ if (tempSingleDeclaration == null) {
+ tempSingleDeclaration = declaration;
+ }
+ else {
+ // There are several class declarations in file
+ return null;
+ }
+ }
+ }
+
+ return tempSingleDeclaration;
+ }
}
diff --git a/idea/src/org/jetbrains/kotlin/idea/run/KotlinJUnitRunConfigurationProducer.kt b/idea/src/org/jetbrains/kotlin/idea/run/KotlinJUnitRunConfigurationProducer.kt
index dc6d8d021ec..015201848b5 100644
--- a/idea/src/org/jetbrains/kotlin/idea/run/KotlinJUnitRunConfigurationProducer.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/run/KotlinJUnitRunConfigurationProducer.kt
@@ -16,17 +16,16 @@
package org.jetbrains.kotlin.idea.run
-import com.intellij.execution.JavaRunConfigurationExtensionManager
-import com.intellij.execution.Location
-import com.intellij.execution.PsiLocation
-import com.intellij.execution.RunnerAndConfigurationSettings
+import com.intellij.execution.*
import com.intellij.execution.actions.ConfigurationContext
+import com.intellij.execution.actions.RunConfigurationProducer
+import com.intellij.execution.configurations.ModuleBasedConfiguration
import com.intellij.execution.junit.JUnitConfiguration
import com.intellij.execution.junit.JUnitConfigurationType
import com.intellij.execution.junit.JUnitUtil
-import com.intellij.execution.junit.RuntimeConfigurationProducer
-import com.intellij.openapi.module.Module
+import com.intellij.execution.junit.PatternConfigurationProducer
import com.intellij.openapi.project.DumbService
+import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
@@ -34,114 +33,116 @@ import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
-import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.JetClass
+import org.jetbrains.kotlin.psi.JetFile
+import org.jetbrains.kotlin.psi.JetFunction
+import org.jetbrains.kotlin.psi.JetNamedFunction
+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
-public class KotlinJUnitRunConfigurationProducer : RuntimeConfigurationProducer(JUnitConfigurationType.getInstance()) {
- private var myElement: JetElement? = null
+public class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer(JUnitConfigurationType.getInstance()) {
+ override fun isConfigurationFromContext(configuration: JUnitConfiguration,
+ context: ConfigurationContext): Boolean {
+ if (RunConfigurationProducer.getInstance(javaClass()).isMultipleElementsSelected(context)) {
+ return false
+ }
- override fun getSourceElement(): PsiElement? {
- return myElement
+ val leaf = context.getLocation()?.getPsiElement() ?: return false
+ val methodLocation = getTestMethodLocation(leaf)
+ val testClass = getTestClass(leaf)
+ val testObject = configuration.getTestObject()
+
+ if (!testObject.isConfiguredByElement(configuration, testClass, methodLocation?.getPsiElement(), null, null)) {
+ return false
+ }
+
+ return settingsMatchTemplate(configuration, context)
}
- override fun createConfigurationByElement(location: Location<*>, context: ConfigurationContext): RunnerAndConfigurationSettings? {
- if (DumbService.getInstance(location.getProject()).isDumb()) return null
+ // copied from JUnitConfigurationProducer in IDEA
+ private fun settingsMatchTemplate(configuration: JUnitConfiguration, context: ConfigurationContext): Boolean {
+ val predefinedConfiguration = context.getOriginalConfiguration(JUnitConfigurationType.getInstance())
+ val vmParameters = (predefinedConfiguration as? CommonJavaRunConfigurationParameters)?.getVMParameters()
+ if (vmParameters != null && configuration.getVMParameters() != vmParameters) return false
+
+ val template = RunManager.getInstance(configuration.getProject()).getConfigurationTemplate(getConfigurationFactory())
+ val predefinedModule = (template.getConfiguration() as ModuleBasedConfiguration<*>).getConfigurationModule().getModule()
+ val configurationModule = configuration.getConfigurationModule().getModule()
+ return configurationModule == context.getLocation()?.getModule() || configurationModule == predefinedModule
+ }
+
+ override fun setupConfigurationFromContext(configuration: JUnitConfiguration,
+ context: ConfigurationContext,
+ sourceElement: Ref): Boolean {
+ if (DumbService.getInstance(context.getProject()).isDumb()) return false
+
+ val location = context.getLocation() ?: return false
val leaf = location.getPsiElement()
if (!ProjectRootsUtil.isInProjectOrLibSource(leaf)) {
- return null
+ return false
}
if (leaf.getContainingFile() !is JetFile) {
- return null
+ return false
}
val jetFile = leaf.getContainingFile() as JetFile
if (ProjectStructureUtil.isJsKotlinModule(jetFile)) {
- return null
+ return false
}
- val function = PsiTreeUtil.getParentOfType(leaf, javaClass(), false)
- if (function != null) {
- myElement = function
+ val methodLocation = getTestMethodLocation(leaf)
+ if (methodLocation != null) {
+ val originalModule = configuration.getConfigurationModule().getModule()
+ configuration.beMethodConfiguration(methodLocation)
+ configuration.restoreOriginalModule(originalModule)
+ JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
+ return true
+ }
- @SuppressWarnings("unchecked")
- val owner = PsiTreeUtil.getParentOfType(function, javaClass(), javaClass())
+ val testClass = getTestClass(leaf)
+ if (testClass != null) {
+ val originalModule = configuration.getConfigurationModule().getModule()
+ configuration.beClassConfiguration(testClass)
+ configuration.restoreOriginalModule(originalModule)
+ JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
+ return true
+ }
- if (owner is JetClass) {
- val delegate = LightClassUtil.getPsiClass(owner)
- if (delegate != null) {
- for (method in delegate.getMethods()) {
- if (method.getNavigationElement() === function) {
- val methodLocation = PsiLocation.fromPsiElement(method)
- if (JUnitUtil.isTestMethod(methodLocation, false)) {
- val settings = cloneTemplateConfiguration(context.getProject(), context)
- val configuration = settings.getConfiguration() as JUnitConfiguration
+ return false
+ }
- val originalModule = configuration.getConfigurationModule().getModule()
- configuration.beMethodConfiguration(methodLocation)
- configuration.restoreOriginalModule(originalModule)
- JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
+ private fun getTestMethodLocation(leaf: PsiElement): Location? {
+ val function = leaf.getParentOfType(false) ?: return null
+ val owner = PsiTreeUtil.getParentOfType(function, javaClass(), javaClass())
- return settings
- }
- break
- }
- }
- }
+ if (owner is JetClass) {
+ val delegate = LightClassUtil.getPsiClass(owner) ?: return null
+ val method = delegate.getMethods().firstOrNull() { it.getNavigationElement() == function } ?: return null
+ val methodLocation = PsiLocation.fromPsiElement(method)
+ if (JUnitUtil.isTestMethod(methodLocation, false)) {
+ return methodLocation
}
}
-
- var jetClass = PsiTreeUtil.getParentOfType(leaf, javaClass(), false)
-
- if (jetClass == null) {
- jetClass = getClassDeclarationInFile(jetFile)
- }
-
- if (jetClass != null) {
- myElement = jetClass
- val delegate = LightClassUtil.getPsiClass(jetClass)
-
- if (delegate != null && JUnitUtil.isTestClass(delegate)) {
- val settings = cloneTemplateConfiguration(context.getProject(), context)
- val configuration = settings.getConfiguration() as JUnitConfiguration
-
- val originalModule = configuration.getConfigurationModule().getModule()
- configuration.beClassConfiguration(delegate)
- configuration.restoreOriginalModule(originalModule)
- JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
-
- return settings
- }
- }
-
return null
}
- override fun compareTo(o: Any?): Int {
- return 0
- }
-
- companion object {
-
- fun getClassDeclarationInFile(jetFile: JetFile): JetClass? {
- var tempSingleDeclaration: JetClass? = null
-
- for (jetDeclaration in jetFile.getDeclarations()) {
- if (jetDeclaration is JetClass) {
-
- if (tempSingleDeclaration == null) {
- tempSingleDeclaration = jetDeclaration
- }
- else {
- // There are several class declarations in file
- return null
- }
- }
- }
-
- return tempSingleDeclaration
+ private fun getTestClass(leaf: PsiElement): PsiClass? {
+ var jetClass = leaf.getParentOfType(false)
+ if (!jetClass.isJUnitTestClass()) {
+ jetClass = getTestClassInFile(leaf.getContainingFile() as JetFile)
}
+ if (jetClass != null) {
+ return LightClassUtil.getPsiClass(jetClass)
+ }
+ return null
}
+
+ private fun JetClass?.isJUnitTestClass() =
+ LightClassUtil.getPsiClass(this)?.let { JUnitUtil.isTestClass(it) } ?: false
+
+ private fun getTestClassInFile(jetFile: JetFile) =
+ jetFile.getDeclarations().filterIsInstance().singleOrNull { it.isJUnitTestClass() }
}