diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrSubTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrSubTarget.kt index 6260eb4d24d..7891276e0ca 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrSubTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrSubTarget.kt @@ -11,7 +11,6 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinTargetWithTests -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.whenEvaluated import org.jetbrains.kotlin.gradle.targets.js.KotlinJsIrPlatformTestRun import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsIrSubTargetDsl @@ -112,7 +111,7 @@ abstract class KotlinJsIrSubTarget( } } - private fun configureTestsRun(testRun: KotlinJsIrPlatformTestRun, compilation: KotlinJsCompilation) { + private fun configureTestsRun(testRun: KotlinJsIrPlatformTestRun, compilation: KotlinJsIrCompilation) { fun KotlinJsIrPlatformTestRun.subtargetTestTaskName(): String = disambiguateCamelCased( lowerCamelCaseName( name.takeIf { it != KotlinTargetWithTests.DEFAULT_TEST_RUN_NAME }, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTest.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTest.kt new file mode 100644 index 00000000000..7e94f64343b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTest.kt @@ -0,0 +1,127 @@ +/* + * 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.gradle.targets.js.ir + +import groovy.lang.Closure +import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Internal +import org.gradle.process.internal.DefaultProcessForkOptions +import org.gradle.util.ConfigureUtil +import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec +import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +import org.jetbrains.kotlin.gradle.targets.js.npm.LoadNpmModules +import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies +import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject +import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma +import org.jetbrains.kotlin.gradle.targets.js.testing.mocha.KotlinMocha +import org.jetbrains.kotlin.gradle.tasks.KotlinTest + +open class KotlinJsIrTest : + KotlinTest(), + RequiresNpmDependencies, + LoadNpmModules { + private val nodeJs get() = NodeJsRootPlugin.apply(project.rootProject) + + @get:Internal + internal var testFramework: KotlinJsIrTestFramework? = null + + @Suppress("unused") + val testFrameworkSettings: String + @Input get() = testFramework!!.settingsState + + @Input + var debug: Boolean = false + + @Internal + override lateinit var compilation: KotlinJsIrCompilation + + @Suppress("unused") + val runtimeClasspath: FileCollection + @InputFiles get() = compilation.runtimeDependencyFiles + + @Suppress("unused") + internal val compilationOutputs: FileCollection + @InputFiles get() = compilation.output.allOutputs + + @Suppress("unused") + val compilationId: String + @Input get() = compilation.let { + val target = it.target + target.project.path + "@" + target.name + ":" + it.compilationName + } + + override val nodeModulesToLoad: List + @Internal get() = listOf("./" + compilation.npmProject.main) + + override val nodeModulesRequired: Boolean + @Internal get() = testFramework!!.nodeModulesRequired + + override val requiredNpmDependencies: Collection + @Internal get() = testFramework!!.requiredNpmDependencies + + @Deprecated("Use useMocha instead", ReplaceWith("useMocha()")) + fun useNodeJs() = useMocha() + + @Deprecated("Use useMocha instead", ReplaceWith("useMocha(body)")) + fun useNodeJs(body: KotlinMocha.() -> Unit) = useMocha(body) + + @Deprecated("Use useMocha instead", ReplaceWith("useMocha(fn)")) + fun useNodeJs(fn: Closure<*>) { + useMocha { + ConfigureUtil.configure(fn, this) + } + } + + fun useMocha() = useMocha {} + fun useMocha(body: KotlinMocha.() -> Unit) = use(KotlinMocha(compilation), body) + fun useMocha(fn: Closure<*>) { + useMocha { + ConfigureUtil.configure(fn, this) + } + } + + fun useKarma() = useKarma {} + fun useKarma(body: KotlinKarma.() -> Unit) = use(KotlinKarma(compilation), body) + fun useKarma(fn: Closure<*>) { + useKarma { + ConfigureUtil.configure(fn, this) + } + } + + private inline fun use(runner: T, body: T.() -> Unit): T { + check(testFramework == null) { + "testFramework already configured for task ${this.path}" + } + + val testFramework = runner.also(body) + this.testFramework = testFramework + + return testFramework + } + + override fun executeTests() { + nodeJs.npmResolutionManager.checkRequiredDependencies(this) + super.executeTests() + } + + override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec { + val forkOptions = DefaultProcessForkOptions(fileResolver) + forkOptions.workingDir = compilation.npmProject.dir + forkOptions.executable = nodeJs.environment.nodeExecutable + + val nodeJsArgs = mutableListOf() + + return testFramework!!.createTestExecutionSpec( + task = this, + forkOptions = forkOptions, + nodeJsArgs = nodeJsArgs, + debug = debug + ) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTestFramework.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTestFramework.kt new file mode 100644 index 00000000000..ba78e6d9f10 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTestFramework.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.gradle.targets.js.ir + +import org.gradle.process.ProcessForkOptions +import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec +import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies + +interface KotlinJsIrTestFramework : RequiresNpmDependencies { + val settingsState: String + + fun createTestExecutionSpec( + task: KotlinJsIrTest, + forkOptions: ProcessForkOptions, + nodeJsArgs: MutableList, + debug: Boolean + ): TCServiceMessagesTestExecutionSpec + + /* + override val nodeModulesRequired: Boolean + get() = true + */ +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/LoadNpmModules.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/LoadNpmModules.kt new file mode 100644 index 00000000000..7b3cbcab6f2 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/LoadNpmModules.kt @@ -0,0 +1,10 @@ +/* + * 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.gradle.targets.js.npm + +interface LoadNpmModules { + val nodeModulesToLoad: List +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt index 91af08a9abf..87735072d50 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt @@ -16,13 +16,17 @@ import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecuti import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +import org.jetbrains.kotlin.gradle.targets.js.npm.LoadNpmModules import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma import org.jetbrains.kotlin.gradle.targets.js.testing.mocha.KotlinMocha import org.jetbrains.kotlin.gradle.tasks.KotlinTest -open class KotlinJsTest : KotlinTest(), RequiresNpmDependencies { +open class KotlinJsTest : + KotlinTest(), + RequiresNpmDependencies, + LoadNpmModules { private val nodeJs get() = NodeJsRootPlugin.apply(project.rootProject) @get:Internal @@ -53,7 +57,7 @@ open class KotlinJsTest : KotlinTest(), RequiresNpmDependencies { target.project.path + "@" + target.name + ":" + it.compilationName } - val nodeModulesToLoad: List + override val nodeModulesToLoad: List @Internal get() = listOf("./" + compilation.npmProject.main) override val nodeModulesRequired: Boolean diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt index 663fb13af7a..fc093f820df 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt @@ -20,16 +20,23 @@ import org.jetbrains.kotlin.gradle.targets.js.NpmPackageVersion import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency import org.jetbrains.kotlin.gradle.targets.js.appendConfigsFromDir import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTest +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTestFramework import org.jetbrains.kotlin.gradle.targets.js.jsQuoted import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +import org.jetbrains.kotlin.gradle.targets.js.npm.LoadNpmModules +import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.testing.* import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig +import org.jetbrains.kotlin.gradle.tasks.KotlinTest import org.jetbrains.kotlin.gradle.testing.internal.reportsDir import org.slf4j.Logger import java.io.File -class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestFramework { +class KotlinKarma(override val compilation: KotlinJsCompilation) : + KotlinJsTestFramework, + KotlinJsIrTestFramework { private val project: Project = compilation.target.project private val nodeJs = NodeJsRootPlugin.apply(project.rootProject) private val versions = nodeJs.versions @@ -37,7 +44,7 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestF private val config: KarmaConfig = KarmaConfig() private val requiredDependencies = mutableSetOf() - private val configurators = mutableListOf<(KotlinJsTest) -> Unit>() + private val configurators = mutableListOf<(KotlinTest) -> Unit>() private val envJsCollector = mutableMapOf() private val confJsWriters = mutableListOf<(Appendable) -> Unit>() private var sourceMaps = false @@ -269,12 +276,41 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestF return adapterJs } + override fun createTestExecutionSpec( + task: KotlinJsIrTest, + forkOptions: ProcessForkOptions, + nodeJsArgs: MutableList, + debug: Boolean + ): TCServiceMessagesTestExecutionSpec = + createTestExecutionSpecPrivate( + task = task, + forkOptions = forkOptions, + nodeJsArgs = nodeJsArgs, + debug = debug + ) + override fun createTestExecutionSpec( task: KotlinJsTest, forkOptions: ProcessForkOptions, nodeJsArgs: MutableList, debug: Boolean - ): TCServiceMessagesTestExecutionSpec { + ): TCServiceMessagesTestExecutionSpec = + createTestExecutionSpecPrivate( + task = task, + forkOptions = forkOptions, + nodeJsArgs = nodeJsArgs, + debug = debug + ) + + private fun createTestExecutionSpecPrivate( + task: T, + forkOptions: ProcessForkOptions, + nodeJsArgs: MutableList, + debug: Boolean + ): TCServiceMessagesTestExecutionSpec + where T : KotlinTest, + T : RequiresNpmDependencies, + T : LoadNpmModules { val npmProject = compilation.npmProject val file = task.nodeModulesToLoad diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/mocha/KotlinMocha.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/mocha/KotlinMocha.kt index 1a51998b9b1..306c2def456 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/mocha/KotlinMocha.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/mocha/KotlinMocha.kt @@ -14,15 +14,22 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.KotlinGradleNpmPackage import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTest +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTestFramework import org.jetbrains.kotlin.gradle.targets.js.jsQuoted import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +import org.jetbrains.kotlin.gradle.targets.js.npm.LoadNpmModules +import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinTestRunnerCliArgs +import org.jetbrains.kotlin.gradle.tasks.KotlinTest import java.io.File -class KotlinMocha(override val compilation: KotlinJsCompilation) : KotlinJsTestFramework { +class KotlinMocha(override val compilation: KotlinJsCompilation) : + KotlinJsTestFramework, + KotlinJsIrTestFramework { private val project: Project = compilation.target.project private val nodeJs = NodeJsRootPlugin.apply(project.rootProject) private val versions = nodeJs.versions @@ -40,12 +47,38 @@ class KotlinMocha(override val compilation: KotlinJsCompilation) : KotlinJsTestF // https://mochajs.org/#-timeout-ms-t-ms var timeout: String = DEFAULT_TIMEOUT + override fun createTestExecutionSpec( + task: KotlinJsIrTest, + forkOptions: ProcessForkOptions, + nodeJsArgs: MutableList, + debug: Boolean + ): TCServiceMessagesTestExecutionSpec = + createTestExecutionSpecPrivate( + task, forkOptions, nodeJsArgs, debug + ) + override fun createTestExecutionSpec( task: KotlinJsTest, forkOptions: ProcessForkOptions, nodeJsArgs: MutableList, debug: Boolean - ): TCServiceMessagesTestExecutionSpec { + ): TCServiceMessagesTestExecutionSpec = + createTestExecutionSpecPrivate( + task = task, + forkOptions = forkOptions, + nodeJsArgs = nodeJsArgs, + debug = debug + ) + + private fun createTestExecutionSpecPrivate( + task: T, + forkOptions: ProcessForkOptions, + nodeJsArgs: MutableList, + debug: Boolean + ): TCServiceMessagesTestExecutionSpec + where T : KotlinTest, + T : RequiresNpmDependencies, + T : LoadNpmModules { val clientSettings = TCServiceMessagesClientSettings( task.name, testNameSuffix = task.targetName, @@ -62,6 +95,7 @@ class KotlinMocha(override val compilation: KotlinJsCompilation) : KotlinJsTestF exclude = task.excludePatterns ) + val mocha = npmProject.require("mocha/bin/mocha") val file = task.nodeModulesToLoad