Prefer Kotlin Gradle test run configurations when possible (KT-33787)

This commit is contained in:
Yan Zhulanow
2019-10-23 19:20:22 +09:00
parent 214810ca01
commit 987307cf92
8 changed files with 199 additions and 7 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.run
import com.intellij.execution.Location
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.execution.junit.InheritorChooser
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration
import com.intellij.openapi.module.Module
@@ -40,12 +41,12 @@ abstract class AbstractKotlinMultiplatformTestClassGradleConfigurationProducer :
return isApplicable(module, platform)
}
override fun isPreferredConfiguration(self: ConfigurationFromContext?, other: ConfigurationFromContext): Boolean {
return other.isJpsJunitConfiguration()
override fun isPreferredConfiguration(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return other.isJpsJunitConfiguration() || super.isPreferredConfiguration(self, other)
}
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return other.isJpsJunitConfiguration()
return other.isJpsJunitConfiguration() || super.shouldReplace(self, other)
}
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
@@ -94,6 +95,10 @@ abstract class AbstractKotlinMultiplatformTestClassGradleConfigurationProducer :
abstract class AbstractKotlinTestClassGradleConfigurationProducer
: TestClassGradleConfigurationProducer(), KotlinGradleConfigurationProducer
{
override fun getConfigurationFactory(): ConfigurationFactory {
return KotlinGradleExternalTaskConfigurationType.instance.factory
}
override fun isConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!context.check()) {
return false
@@ -133,4 +138,20 @@ abstract class AbstractKotlinTestClassGradleConfigurationProducer
override fun getPsiClassForLocation(contextLocation: Location<*>) = getTestClassForKotlinTest(contextLocation)
override fun getPsiMethodForLocation(contextLocation: Location<*>) = getTestMethodForKotlinTest(contextLocation)
}
override fun isPreferredConfiguration(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return checkShouldReplace(self, other) || super.isPreferredConfiguration(self, other)
}
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return checkShouldReplace(self, other) || super.shouldReplace(self, other)
}
private fun checkShouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
if (self.isProducedBy(javaClass) && other.isProducedBy(TestClassGradleConfigurationProducer::class.java)) {
return true
}
return false
}
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.run
import com.intellij.execution.Location
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.execution.junit.InheritorChooser
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration
import com.intellij.openapi.module.Module
@@ -41,12 +42,12 @@ abstract class AbstractKotlinMultiplatformTestMethodGradleConfigurationProducer
return isApplicable(module, platform)
}
override fun isPreferredConfiguration(self: ConfigurationFromContext?, other: ConfigurationFromContext): Boolean {
return other.isJpsJunitConfiguration()
override fun isPreferredConfiguration(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return other.isJpsJunitConfiguration() || super.isPreferredConfiguration(self, other)
}
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return other.isJpsJunitConfiguration()
return other.isJpsJunitConfiguration() || super.shouldReplace(self, other)
}
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
@@ -97,6 +98,10 @@ abstract class AbstractKotlinMultiplatformTestMethodGradleConfigurationProducer
abstract class AbstractKotlinTestMethodGradleConfigurationProducer
: TestMethodGradleConfigurationProducer(), KotlinGradleConfigurationProducer
{
override fun getConfigurationFactory(): ConfigurationFactory {
return KotlinGradleExternalTaskConfigurationType.instance.factory
}
override fun isConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!context.check()) {
return false
@@ -135,4 +140,24 @@ abstract class AbstractKotlinTestMethodGradleConfigurationProducer
}
override fun getPsiMethodForLocation(contextLocation: Location<*>) = getTestMethodForKotlinTest(contextLocation)
override fun isPreferredConfiguration(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return checkShouldReplace(self, other) || super.isPreferredConfiguration(self, other)
}
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
return checkShouldReplace(self, other) || super.shouldReplace(self, other)
}
private fun checkShouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
if (self.isProducedBy(javaClass)) {
if (other.isProducedBy(TestMethodGradleConfigurationProducer::class.java) ||
other.isProducedBy(AbstractKotlinTestClassGradleConfigurationProducer::class.java)
) {
return true
}
}
return false
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.run
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.execution.configurations.ConfigurationType
import com.intellij.execution.configurations.ConfigurationTypeUtil
import com.intellij.openapi.externalSystem.model.ProjectSystemId
import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration
import com.intellij.openapi.project.Project
import org.jetbrains.plugins.gradle.service.execution.GradleRunConfiguration
import org.jetbrains.plugins.gradle.util.GradleConstants
class KotlinGradleExternalTaskConfigurationType : AbstractExternalSystemTaskConfigurationType(GradleConstants.SYSTEM_ID) {
companion object {
val instance: KotlinGradleExternalTaskConfigurationType
get() = ConfigurationTypeUtil.findConfigurationType(KotlinGradleExternalTaskConfigurationType::class.java)
}
override fun getId() = "Kotlin" + externalSystemId.readableName + "RunConfiguration"
@Suppress("SpellCheckingInspection")
override fun getHelpTopic() = "reference.dialogs.rundebug.GradleRunConfiguration"
override fun doCreateConfiguration(
externalSystemId: ProjectSystemId,
project: Project,
factory: ConfigurationFactory,
name: String
): ExternalSystemRunConfiguration {
return KotlinGradleRunConfiguration(project, factory, name)
}
}
class KotlinGradleRunConfiguration(project: Project?, factory: ConfigurationFactory?, name: String?) :
GradleRunConfiguration(project, factory, name)
@@ -0,0 +1,70 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.codeInsight.gradle
import com.intellij.execution.PsiLocation
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import org.junit.Test
import com.intellij.testFramework.runInEdtAndWait
import com.intellij.util.PlatformUtils
import org.jetbrains.kotlin.idea.run.KotlinGradleRunConfiguration
import org.jetbrains.kotlin.idea.run.KotlinJvmTestClassGradleConfigurationProducer
import org.jetbrains.kotlin.idea.run.KotlinJvmTestMethodGradleConfigurationProducer
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer
import org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer
import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions
class GradleTestRunConfigurationTest : GradleImportingTestCase() {
@Test
@TargetVersions("4.7+")
fun testPreferredConfigurations() {
if (!PlatformUtils.isIntelliJ()) {
return
}
val files = importProjectFromTestData()
runInEdtAndWait {
runReadAction {
val javaFile = files.first { it.name == "MyTest.java" }
val kotlinFile = files.first { it.name == "MyKotlinTest.kt" }
val javaClassConfiguration = getConfiguration(javaFile, "MyTest")
javaClassConfiguration.isProducedBy(TestClassGradleConfigurationProducer::class.java)
assert(javaClassConfiguration.configuration !is KotlinGradleRunConfiguration)
val javaMethodConfiguration = getConfiguration(javaFile, "testA")
javaMethodConfiguration.isProducedBy(TestMethodGradleConfigurationProducer::class.java)
assert(javaMethodConfiguration.configuration !is KotlinGradleRunConfiguration)
val kotlinClassConfiguration = getConfiguration(kotlinFile, "MyKotlinTest")
kotlinClassConfiguration.isProducedBy(KotlinJvmTestClassGradleConfigurationProducer::class.java)
assert(kotlinClassConfiguration.configuration is KotlinGradleRunConfiguration)
val kotlinFunctionConfiguration = getConfiguration(kotlinFile, "testA")
kotlinFunctionConfiguration.isProducedBy(KotlinJvmTestMethodGradleConfigurationProducer::class.java)
assert(kotlinFunctionConfiguration.configuration is KotlinGradleRunConfiguration)
}
}
}
private fun getConfiguration(file: VirtualFile, pattern: String): ConfigurationFromContext {
val psiFile = PsiManager.getInstance(myTestFixture.project).findFile(file) ?: error("PsiFile not found for $file")
val offset = psiFile.text.indexOf(pattern)
val psiElement = psiFile.findElementAt(offset)
val location = PsiLocation(psiElement)
val context = ConfigurationContext.createEmptyContextForLocation(location)
return context.configurationsFromContext.orEmpty().singleOrNull() ?: error("Configuration not found for pattern $pattern")
}
override fun testDataDirName(): String {
return "testRunConfigurations"
}
}
+1
View File
@@ -19,6 +19,7 @@
</extensions>
<extensions defaultExtensionNs="com.intellij">
<configurationType implementation="org.jetbrains.kotlin.idea.run.KotlinGradleExternalTaskConfigurationType"/>
<projectTaskRunner implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinMPPGradleProjectTaskRunner" order="first, before gradle"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectSettingsDataService"/>
@@ -0,0 +1,15 @@
plugins {
id 'java'
id 'org.jetbrains.kotlin.jvm' version '1.3.50'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testCompile "junit:junit:4.12"
}
@@ -0,0 +1,9 @@
import org.junit.Test;
public class MyTest {
@Test
public void testA() {}
@Test
public void testB() {}
}
@@ -0,0 +1,11 @@
import org.junit.Test
class MyKotlinTest {
@Test
fun testA() {
}
@Test
fun testB() {
}
}