diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt
index 7fcf8a15492e8..fcb9da16b8c36 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt
@@ -1815,4 +1815,50 @@ class Kotlin2JsIrGradlePluginIT : KGPBaseTest() {
}
}
}
+
+ @DisplayName("Check that nodeTest run tests with commonjs module kind")
+ @GradleTest
+ fun testFailedJsTestWithCommonJs(gradleVersion: GradleVersion) {
+ project("kotlin-js-project-failed-test", gradleVersion) {
+ buildGradle.appendText(
+ """
+ |
+ |tasks.withType(KotlinJsCompile).configureEach {
+ | kotlinOptions { moduleKind = "commonjs" }
+ |}
+ """.trimMargin()
+ )
+ buildAndFail("nodeTest") {
+ assertTasksFailed(":nodeTest")
+
+ assertTestResults(
+ projectPath.resolve("TEST-all.xml"),
+ "nodeTest"
+ )
+ }
+ }
+ }
+
+ @DisplayName("Check that nodeTest run tests with ESM module kind")
+ @GradleTest
+ fun testFailedJsTestWithESM(gradleVersion: GradleVersion) {
+ project("kotlin-js-project-failed-test", gradleVersion) {
+ buildGradle.appendText(
+ """
+ |
+ |tasks.withType(KotlinJsCompile).configureEach {
+ | kotlinOptions { moduleKind = "es" }
+ |}
+ """.trimMargin()
+ )
+ buildAndFail("nodeTest") {
+ assertTasksFailed(":nodeTest")
+
+ assertTestResults(
+ projectPath.resolve("TEST-all.xml"),
+ "nodeTest"
+ )
+ }
+ }
+ }
}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/TEST-all.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/TEST-all.xml
new file mode 100644
index 0000000000000..716ec274701b3
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/TEST-all.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ ...
+
+
+
+
+
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/build.gradle
new file mode 100644
index 0000000000000..358e430e87e3a
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/build.gradle
@@ -0,0 +1,22 @@
+import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile
+
+plugins {
+ id("org.jetbrains.kotlin.js")
+}
+
+dependencies {
+ implementation("org.jetbrains.kotlin:kotlin-stdlib-js")
+ testImplementation("org.jetbrains.kotlin:kotlin-test-js")
+}
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
+
+kotlin {
+ js {
+ binaries.executable()
+ nodejs()
+ }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/custom/main.txt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/custom/main.txt
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/gradle.properties b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/gradle.properties
new file mode 100644
index 0000000000000..cc1416ef29778
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/gradle.properties
@@ -0,0 +1 @@
+kotlin.tests.individualTaskReports=true
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/src/main/kotlin/Base.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/src/main/kotlin/Base.kt
new file mode 100644
index 0000000000000..122e2fd9a3105
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/src/main/kotlin/Base.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 com.example
+
+fun getValue(): Int {
+ return 42
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/src/test/kotlin/Tests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/src/test/kotlin/Tests.kt
new file mode 100644
index 0000000000000..a87db839f6ef4
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-project-failed-test/src/test/kotlin/Tests.kt
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2010-2021 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.
+ */
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class Tests {
+ @Test
+ fun testHello() {
+ assertEquals(73, com.example.getValue())
+ }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsCompilation.kt
index 1288cf3af83a4..96ee5ae2c6338 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsCompilation.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsCompilation.kt
@@ -12,6 +12,8 @@ import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.tasks.TaskProvider
+import org.gradle.api.provider.Provider
+import org.jetbrains.kotlin.gradle.dsl.JsModuleKind
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
import org.jetbrains.kotlin.gradle.plugin.*
@@ -99,3 +101,15 @@ open class KotlinJsCompilation @Inject internal constructor(
}
}
}
+
+internal val KotlinJsCompilation.fileExtension: Provider
+ get() {
+ val isWasm = platformType == KotlinPlatformType.wasm
+ return compilerOptions.options.moduleKind.map { moduleKind ->
+ if (isWasm || moduleKind == JsModuleKind.MODULE_ES) {
+ "mjs"
+ } else {
+ "js"
+ }
+ }
+ }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt
index f6552801264ed..a54a0b608c480 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
+import org.jetbrains.kotlin.gradle.plugin.mpp.fileExtension
import org.jetbrains.kotlin.gradle.plugin.tcs
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
@@ -41,7 +42,8 @@ internal open class BaseKotlin2JsCompileConfig(
configureAdditionalFreeCompilerArguments(task, compilation)
- val compilationTarget = compilation.tcs.compilation.target
+ val binaryCompilation = compilation.tcs.compilation
+ val compilationTarget = binaryCompilation.target
if (compilationTarget is KotlinJsTarget ||
(compilationTarget is KotlinWithJavaTarget<*, *> && compilationTarget.platformType == KotlinPlatformType.js)
) {
@@ -55,10 +57,14 @@ internal open class BaseKotlin2JsCompileConfig(
@Suppress("DEPRECATION")
task.outputFileProperty.value(
task.destinationDirectory.flatMap { dir ->
- if (task.compilerOptions.outputFile.orNull != null) {
- task.compilerOptions.outputFile.map { File(it) }
- } else {
- task.compilerOptions.moduleName.map { name ->
+ when {
+ task.compilerOptions.outputFile.orNull != null -> task.compilerOptions.outputFile.map { File(it) }
+ binaryCompilation is KotlinJsCompilation -> task.compilerOptions.moduleName.flatMap { name ->
+ binaryCompilation.fileExtension.map {
+ dir.file("$name.$it").asFile
+ }
+ }
+ else -> task.compilerOptions.moduleName.map { name ->
dir.file(name + compilation.platformType.fileExtension).asFile
}
}