diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/AbstractKotlinTestMethodGradleConfigurationProducer.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/AbstractKotlinTestMethodGradleConfigurationProducer.kt index 5582c7d3c93..68d0f8714e8 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/AbstractKotlinTestMethodGradleConfigurationProducer.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/AbstractKotlinTestMethodGradleConfigurationProducer.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.idea.run import com.intellij.execution.Location -import com.intellij.execution.PsiLocation import com.intellij.execution.actions.ConfigurationContext import com.intellij.execution.actions.ConfigurationFromContext import com.intellij.execution.junit.InheritorChooser @@ -80,23 +79,16 @@ abstract class AbstractKotlinMultiplatformTestMethodGradleConfigurationProducer ) { val dataContext = MultiplatformTestTasksChooser.createContext(context.dataContext, psiMethod.name) - val availableTargets = - classes - .mapNotNull { psiClass -> psiClass.module } - .flatMap { module -> module.externalSystemTestRunTasks() } - .map { extTask -> extTask.targetName } - .distinct() + val contextualSuffix = (context.location as? PsiMemberParameterizedLocation)?.paramSetName?.trim('[', ']') - mppTestTasksChooser.multiplatformChooseTasks(context.project, dataContext, classes.asList()) { tasks -> + mppTestTasksChooser.multiplatformChooseTasks(context.project, dataContext, classes.asList(), contextualSuffix) { tasks -> val configuration = fromContext.configuration as ExternalSystemRunConfiguration val settings = configuration.settings val result = settings.applyTestConfiguration(context.module, tasks, *classes) { var filters = createTestFilterFrom(context.location, it, psiMethod, true) - if (context.location is PsiMemberParameterizedLocation) { - availableTargets.forEach { targetName -> - filters = filters.replace("[*$targetName*]", "") - } + if (context.location is PsiMemberParameterizedLocation && contextualSuffix != null) { + filters = filters.replace("[*$contextualSuffix*]", "") } filters } diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/MultiplatformTestTasksChooser.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/MultiplatformTestTasksChooser.kt index c64ecaffa30..d9ef2548885 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/MultiplatformTestTasksChooser.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/run/MultiplatformTestTasksChooser.kt @@ -10,6 +10,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.ExternalSystemRunTask +import org.jetbrains.kotlin.config.ExternalSystemTestRunTask import org.jetbrains.kotlin.idea.facet.externalSystemTestRunTasks import org.jetbrains.kotlin.idea.util.module import org.jetbrains.plugins.gradle.execution.test.runner.* @@ -17,6 +18,8 @@ import org.jetbrains.plugins.gradle.util.TasksToRun import java.util.* import java.util.function.Consumer +private typealias TaskFilter = (ExternalSystemTestRunTask) -> Boolean + class MultiplatformTestTasksChooser : TestTasksChooser() { companion object { fun createContext(context: DataContext, locationName: String?): DataContext { @@ -28,10 +31,11 @@ class MultiplatformTestTasksChooser : TestTasksChooser() { project: Project, dataContext: DataContext, elements: Iterable, + contextualSuffix: String? = null, // like "js, browser, HeadlessChrome85.0.4183, MacOSX10.14.6" handler: (List>) -> Unit ) { val consumer = Consumer>> { handler(it) } - val testTasks = resolveTestTasks(elements) + val testTasks = resolveTestTasks(elements, contextualFilter(contextualSuffix )) when { testTasks.isEmpty() -> super.chooseTestTasks(project, dataContext, elements, consumer) @@ -40,14 +44,37 @@ class MultiplatformTestTasksChooser : TestTasksChooser() { } } - private fun resolveTestTasks(elements: Iterable): Map> { + private fun contextualFilter(contextualSuffix: String?): TaskFilter { + val parts = contextualSuffix?.split(", ") + ?.filter { it.isNotEmpty() } + ?.takeIf { it.isNotEmpty() } + ?: return { _ -> true } + + val targetName = parts[0] + + if (parts.size == 1) { + return { it.targetName == targetName } + } + + val taskPrefix = targetName + parts[1].capitalize() + + return { it.targetName == targetName && it.taskName.startsWith(taskPrefix) } + } + + private fun resolveTestTasks( + elements: Iterable, + taskFilter: TaskFilter + ): Map> { val tasks = mutableMapOf>() + for (element in elements) { val module = element.module ?: continue val sourceFile = getSourceFile(element) ?: continue - val groupedTasks = module.externalSystemTestRunTasks().groupBy { it.targetName } + val groupedTasks = module.externalSystemTestRunTasks() + .filter { taskFilter(it) } + .groupBy { it.targetName } for ((group, tasksInGroup) in groupedTasks) { if (tasksInGroup.isEmpty()) {