diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt index f32a39341c5..a3fa375365b 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt @@ -33,7 +33,9 @@ import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.impl.libraries.LibraryImpl import com.intellij.openapi.roots.libraries.PersistentLibraryKind import com.intellij.util.PathUtil +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments import org.jetbrains.kotlin.config.CoroutineSupport import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.LanguageFeature @@ -205,11 +207,20 @@ private fun configureFacetByGradleModule( adjustClasspath(kotlinFacet, dependencyClasspath) } - kotlinFacet.configuration.settings.implementedModuleName = getImplementedModuleName(moduleNode, sourceSetName) + with(kotlinFacet.configuration.settings) { + implementedModuleName = getImplementedModuleName(moduleNode, sourceSetName) + testOutputPath = getExplicitTestOutputPath(moduleNode, platformKind) + } return kotlinFacet } +private fun getExplicitTestOutputPath(moduleNode: DataNode, platformKind: TargetPlatformKind<*>?): String? { + if (platformKind !is TargetPlatformKind.JavaScript) return null + val k2jsArgumentList = moduleNode.compilerArgumentsBySourceSet?.get("test")?.currentArguments ?: return null + return K2JSCompilerArguments().apply { parseCommandLineArguments(k2jsArgumentList, this) }.outputFile +} + private fun getImplementedModuleName(moduleNode: DataNode, sourceSetName: String?): String? { val baseModuleName = moduleNode.implementedModule?.data?.internalName if (baseModuleName == null || sourceSetName == null) return baseModuleName diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt index 953955365ad..297204c51d7 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt @@ -18,7 +18,10 @@ package org.jetbrains.kotlin.gradle import com.intellij.openapi.roots.DependencyScope import com.intellij.openapi.util.text.StringUtil +import com.intellij.util.PathUtil +import junit.framework.TestCase import org.jetbrains.kotlin.idea.codeInsight.gradle.GradleImportingTestCase +import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.junit.Test import java.io.File @@ -477,4 +480,131 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() { assertModuleModuleDepScope("project3", "project1", DependencyScope.COMPILE) } + + @Test + fun testJsTestOutputFile() { + createProjectSubFile( + "settings.gradle", + "include ':project1', ':project2', ':project3'" + ) + + val kotlinVersion = "1.1.51" + + createProjectSubFile("build.gradle", """ + buildscript { + repositories { + jcenter() + maven { url 'https://maven.google.com' } + } + + dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") + classpath 'com.android.tools.build:gradle:2.3.3' + } + } + + project('project1') { + apply plugin: 'kotlin-platform-common' + } + + project('project2') { + repositories { + mavenCentral() + } + + apply plugin: 'kotlin-platform-js' + + dependencies { + implement project(':project1') + } + } + """) + + importProject() + + TestCase.assertEquals( + projectPath + "/project2/build/classes/test/project2_test.js", + PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_main"))!!.configuration.settings.testOutputPath) + ) + TestCase.assertEquals( + projectPath + "/project2/build/classes/test/project2_test.js", + PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2_test"))!!.configuration.settings.testOutputPath) + ) + } + + @Test + fun testJsTestOutputFileInProjectWithAndroid() { + createProjectSubFile( + "settings.gradle", + "include ':project1', ':project2', ':project3'" + ) + + val kotlinVersion = "1.1.51" + + createProjectSubFile("build.gradle", """ + buildscript { + repositories { + jcenter() + maven { url 'https://maven.google.com' } + } + + dependencies { + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") + classpath 'com.android.tools.build:gradle:2.3.3' + } + } + + project('project1') { + apply plugin: 'kotlin-platform-common' + } + + project('project2') { + repositories { + mavenCentral() + } + + apply plugin: 'kotlin-platform-js' + + dependencies { + implement project(':project1') + } + } + + project('project3') { + repositories { + mavenCentral() + } + + apply plugin: 'com.android.application' + apply plugin: 'kotlin-android' + + sourceSets { + custom + } + + android { + compileSdkVersion 23 + buildToolsVersion "23.0.1" + defaultConfig { + applicationId "org.jetbrains.kotlin" + minSdkVersion 18 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + } + } + """) + createProjectSubFile("local.properties", """ + sdk.dir=/${StringUtil.escapeBackSlashes(File(homePath).parent + "/dependencies/androidSDK")} + """) + + importProject() + + TestCase.assertEquals( + projectPath + "/project2/build/classes/test/project2_test.js", + PathUtil.toSystemIndependentName(KotlinFacet.get (getModule("project2"))!!.configuration.settings.testOutputPath) + ) + } } \ No newline at end of file diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt index 68fe7afa20c..7883fb746d5 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt @@ -151,6 +151,8 @@ class KotlinFacetSettings { } var implementedModuleName: String? = null + + var testOutputPath: String? = null } fun TargetPlatformKind<*>.createCompilerArguments(init: CommonCompilerArguments.() -> Unit = {}): CommonCompilerArguments { diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt index 8551ed971f8..167bb61393c 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt @@ -108,6 +108,9 @@ private fun readV2AndLaterConfig(element: Element): KotlinFacetSettings { compilerArguments = platformKind.createCompilerArguments() XmlSerializer.deserializeInto(compilerArguments!!, it) } + testOutputPath = element.getChild("testOutputPath")?.let { + PathUtil.toSystemDependentName((it.content.firstOrNull() as? Text)?.textTrim) + } ?: (compilerArguments as? K2JSCompilerArguments)?.outputFile } } @@ -232,6 +235,11 @@ private fun KotlinFacetSettings.writeLatestConfig(element: Element) { implementedModuleName?.let { element.addContent(Element("implements").apply { addContent(it) }) } + testOutputPath?.let { + if (it != (compilerArguments as? K2JSCompilerArguments)?.outputFile) { + element.addContent(Element("testOutputPath").apply { addContent(PathUtil.toSystemIndependentName(it)) }) + } + } compilerSettings?.let { copyBean(it) }?.let { it.convertPathsToSystemIndependent() buildChildElement(element, "compilerSettings", it, filter)