Launch common tests on local JVM via run gutter

For projects with android target and without jvm one. #KT-42463
This commit is contained in:
Kirill Shmakov
2020-10-20 18:02:28 +03:00
parent 1c1e8f7beb
commit 29aaf70d21
2 changed files with 29 additions and 16 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 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.
*/
@@ -473,8 +473,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtensionComp
val dependsOnReverseGraph: MutableMap<String, MutableSet<KotlinSourceSet>> = HashMap()
mppModel.targets.forEach { target ->
target.compilations.forEach { compilation ->
val testRunTasks = target.testRunTasks
.filter { task -> task.compilationName == compilation.name }
val testRunTasks = target.testTasksFor(compilation)
.map {
ExternalSystemTestRunTask(
it.taskName,
@@ -1102,6 +1101,13 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtensionComp
}
}
private fun KotlinTarget.testTasksFor(compilation: KotlinCompilation) = testRunTasks.filter { task ->
when (name) {
"android" -> task.taskName.endsWith(compilation.name, true)
else -> task.compilationName == compilation.name
}
}
fun ProjectResolverContext.getMppModel(gradleModule: IdeaModule): KotlinMPPGradleModel? {
val mppModel = this.getExtraProject(gradleModule, KotlinMPPGradleModel::class.java)
return if (mppModel is Proxy) {
@@ -473,6 +473,15 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
}
}
private fun Named.testTaskClass(className: String) = try {
// This is a workaround that makes assumptions about the tasks naming logic
// and is therefore an unstable and temporary solution until test runs API is implemented:
@Suppress("UNCHECKED_CAST")
this.javaClass.classLoader.loadClass(className) as Class<out Task>
} catch (_: ClassNotFoundException) {
null
}
private fun buildTestRunTasks(project: Project, gradleTarget: Named): Collection<KotlinTestRunTask> {
val getTestRunsMethod = gradleTarget.javaClass.getMethodOrNull("getTestRuns")
if (getTestRunsMethod != null) {
@@ -501,14 +510,9 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
return emptyList()
}
// Otherwise, find the Kotlin test task with names matching the target name. This is a workaround that makes assumptions about
// the tasks naming logic and is therefore an unstable and temporary solution until test runs API is implemented:
@Suppress("UNCHECKED_CAST")
val kotlinTestTaskClass = try {
gradleTarget.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.tasks.KotlinTest") as Class<out Task>
} catch (_: ClassNotFoundException) {
return emptyList()
}
// Otherwise, find the Kotlin/JVM test task with names matching the target name or
// aggregate Android JVM tasks (like testDebugUnitTest).
val kotlinTestTaskClass = gradleTarget.testTaskClass("org.jetbrains.kotlin.gradle.tasks.KotlinTest") ?: return emptyList()
val targetDisambiguationClassifier = run {
val getDisambiguationClassifier = gradleTarget.javaClass.getMethodOrNull("getDisambiguationClassifier")
@@ -520,13 +524,16 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
// The 'targetName' of a test task matches the target disambiguation classifier, potentially with suffix, e.g. jsBrowser
val getTargetName = kotlinTestTaskClass.getDeclaredMethodOrNull("getTargetName") ?: return emptyList()
val jvmTestTaskClass = try {
gradleTarget.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest") as Class<out Task>
} catch (_: ClassNotFoundException) {
return emptyList()
}
val jvmTestTaskClass = gradleTarget.testTaskClass("org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest") ?: return emptyList()
val getJvmTargetName = jvmTestTaskClass.getDeclaredMethodOrNull("getTargetName") ?: return emptyList()
if (targetDisambiguationClassifier == "android") {
val androidUnitTestClass = gradleTarget.testTaskClass("com.android.build.gradle.tasks.factory.AndroidUnitTest")
?: return emptyList()
return project.tasks.filter { androidUnitTestClass.isInstance(it) }.mapNotNull { task -> task.name }
.map { KotlinTestRunTaskImpl(it, KotlinCompilation.TEST_COMPILATION_NAME) }
}
return project.tasks.filter { kotlinTestTaskClass.isInstance(it) || jvmTestTaskClass.isInstance(it) }.mapNotNull { task ->
val testTaskDisambiguationClassifier =