Gradle: Kotlin NodeJS tests runner for single target
#KT-30528
This commit is contained in:
@@ -27,30 +27,32 @@ class CodeConformanceTest : TestCase() {
|
||||
private val JAVA_FILE_PATTERN = Pattern.compile(".+\\.java")
|
||||
private val SOURCES_FILE_PATTERN = Pattern.compile("(.+\\.java|.+\\.kt|.+\\.js)")
|
||||
private val EXCLUDED_FILES_AND_DIRS = listOf(
|
||||
"android.tests.dependencies",
|
||||
"buildSrc",
|
||||
"core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections",
|
||||
"js/js.tests/.gradle",
|
||||
"js/js.translator/testData/node_modules",
|
||||
"libraries/kotlin.test/js/it/.gradle",
|
||||
"libraries/kotlin.test/js/it/node_modules",
|
||||
"libraries/stdlib/js/.gradle",
|
||||
"libraries/stdlib/js/build",
|
||||
"libraries/reflect/build",
|
||||
"libraries/reflect/api/src/java9/java/kotlin/reflect/jvm/internal/impl",
|
||||
"libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools",
|
||||
"dependencies",
|
||||
"js/js.translator/qunit/qunit.js",
|
||||
"libraries/tools/kotlin-js-tests/src/test/web/qunit.js",
|
||||
"out",
|
||||
"dist",
|
||||
"libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/build/tmp",
|
||||
"libraries/tools/kotlin-maven-plugin/target",
|
||||
"libraries/tools/kotlinp/src",
|
||||
"compiler/testData/psi/kdoc",
|
||||
"compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt",
|
||||
"compiler/util/src/org/jetbrains/kotlin/config/MavenComparableVersion.java",
|
||||
"dependencies/protobuf/protobuf-relocated/build"
|
||||
"android.tests.dependencies",
|
||||
"buildSrc",
|
||||
"core/reflection.jvm/src/kotlin/reflect/jvm/internal/pcollections",
|
||||
"js/js.tests/.gradle",
|
||||
"js/js.translator/testData/node_modules",
|
||||
"libraries/kotlin.test/js/it/.gradle",
|
||||
"libraries/kotlin.test/js/it/node_modules",
|
||||
"libraries/stdlib/js/.gradle",
|
||||
"libraries/stdlib/js/build",
|
||||
"libraries/reflect/build",
|
||||
"libraries/reflect/api/src/java9/java/kotlin/reflect/jvm/internal/impl",
|
||||
"libraries/tools/binary-compatibility-validator/src/main/kotlin/org.jetbrains.kotlin.tools",
|
||||
"dependencies",
|
||||
"js/js.translator/qunit/qunit.js",
|
||||
"libraries/tools/kotlin-js-tests/src/test/web/qunit.js",
|
||||
"out",
|
||||
"dist",
|
||||
"libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/build/tmp",
|
||||
"libraries/tools/kotlin-maven-plugin/target",
|
||||
"libraries/tools/kotlinp/src",
|
||||
"libraries/tools/kotlin-test-nodejs-runner/node_modules",
|
||||
"libraries/tools/kotlin-test-nodejs-runner/.gradle",
|
||||
"compiler/testData/psi/kdoc",
|
||||
"compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt",
|
||||
"compiler/util/src/org/jetbrains/kotlin/config/MavenComparableVersion.java",
|
||||
"dependencies/protobuf/protobuf-relocated/build"
|
||||
).map(::File)
|
||||
|
||||
private val COPYRIGHT_EXCLUDED_FILES_AND_DIRS = listOf(
|
||||
@@ -72,6 +74,8 @@ class CodeConformanceTest : TestCase() {
|
||||
"libraries/stdlib/js/node_modules",
|
||||
"libraries/tools/kotlin-maven-plugin-test/target",
|
||||
"libraries/tools/kotlin-gradle-plugin-integration-tests/build",
|
||||
"libraries/tools/kotlin-test-nodejs-runner/node_modules",
|
||||
"libraries/tools/kotlin-test-nodejs-runner/.gradle",
|
||||
"buildSrc/prepare-deps/build"
|
||||
)
|
||||
}
|
||||
@@ -95,49 +99,49 @@ class CodeConformanceTest : TestCase() {
|
||||
val atAuthorPattern = Pattern.compile("/\\*.+@author.+\\*/", Pattern.DOTALL)
|
||||
|
||||
val tests = listOf(
|
||||
TestData(
|
||||
"%d source files contain @author javadoc tag.\nPlease remove them or exclude in this test:\n%s",
|
||||
{ source ->
|
||||
// substring check is an optimization
|
||||
"@author" in source && atAuthorPattern.matcher(source).find() &&
|
||||
"ASM: a very small and fast Java bytecode manipulation framework" !in source
|
||||
}
|
||||
),
|
||||
TestData(
|
||||
"%d source files use something from com.beust.jcommander.internal package.\n" +
|
||||
TestData(
|
||||
"%d source files contain @author javadoc tag.\nPlease remove them or exclude in this test:\n%s",
|
||||
{ source ->
|
||||
// substring check is an optimization
|
||||
"@author" in source && atAuthorPattern.matcher(source).find() &&
|
||||
"ASM: a very small and fast Java bytecode manipulation framework" !in source
|
||||
}
|
||||
),
|
||||
TestData(
|
||||
"%d source files use something from com.beust.jcommander.internal package.\n" +
|
||||
"This code won't work when there's no TestNG in the classpath of our IDEA plugin, " +
|
||||
"because there's only an optional dependency on testng.jar.\n" +
|
||||
"Most probably you meant to use Guava's Lists, Maps or Sets instead. " +
|
||||
"Please change references in these files to com.google.common.collect:\n%s",
|
||||
{ source ->
|
||||
"com.beust.jcommander.internal" in source
|
||||
}
|
||||
),
|
||||
TestData(
|
||||
"%d source files contain references to package org.jetbrains.jet.\n" +
|
||||
{ source ->
|
||||
"com.beust.jcommander.internal" in source
|
||||
}
|
||||
),
|
||||
TestData(
|
||||
"%d source files contain references to package org.jetbrains.jet.\n" +
|
||||
"Package org.jetbrains.jet is deprecated now in favor of org.jetbrains.kotlin. " +
|
||||
"Please consider changing the package in these files:\n%s",
|
||||
{ source ->
|
||||
"org.jetbrains.jet" in source
|
||||
}
|
||||
),
|
||||
TestData(
|
||||
"%d source files contain references to package kotlin.reflect.jvm.internal.impl.\n" +
|
||||
{ source ->
|
||||
"org.jetbrains.jet" in source
|
||||
}
|
||||
),
|
||||
TestData(
|
||||
"%d source files contain references to package kotlin.reflect.jvm.internal.impl.\n" +
|
||||
"This package contains internal reflection implementation and is a result of a " +
|
||||
"post-processing of kotlin-reflect.jar by jarjar.\n" +
|
||||
"Most probably you meant to use classes from org.jetbrains.kotlin.**.\n" +
|
||||
"Please change references in these files or exclude them in this test:\n%s",
|
||||
{ source ->
|
||||
"kotlin.reflect.jvm.internal.impl" in source
|
||||
}
|
||||
),
|
||||
TestData(
|
||||
"%d source files contain references to package org.objectweb.asm.\n" +
|
||||
{ source ->
|
||||
"kotlin.reflect.jvm.internal.impl" in source
|
||||
}
|
||||
),
|
||||
TestData(
|
||||
"%d source files contain references to package org.objectweb.asm.\n" +
|
||||
"Package org.jetbrains.org.objectweb.asm should be used instead to avoid troubles with different asm versions in classpath. " +
|
||||
"Please consider changing the package in these files:\n%s",
|
||||
{ source ->
|
||||
" org.objectweb.asm" in source
|
||||
})
|
||||
{ source ->
|
||||
" org.objectweb.asm" in source
|
||||
})
|
||||
)
|
||||
|
||||
for (sourceFile in FileUtil.findFilesByMask(SOURCES_FILE_PATTERN, File("."))) {
|
||||
@@ -170,7 +174,7 @@ class CodeConformanceTest : TestCase() {
|
||||
for (sourceFile in FileUtil.findFilesByMask(SOURCES_FILE_PATTERN, root)) {
|
||||
val relativePath = FileUtil.toSystemIndependentName(sourceFile.toRelativeString(root))
|
||||
if (COPYRIGHT_EXCLUDED_FILES_AND_DIRS.any { relativePath.startsWith(it) } ||
|
||||
knownThirdPartyCode.any { relativePath.startsWith(it) }) continue
|
||||
knownThirdPartyCode.any { relativePath.startsWith(it)}) continue
|
||||
|
||||
sourceFile.useLines { lineSequence ->
|
||||
for (line in lineSequence) {
|
||||
@@ -181,23 +185,21 @@ class CodeConformanceTest : TestCase() {
|
||||
}
|
||||
}
|
||||
if (filesWithUnlistedCopyrights.isNotEmpty()) {
|
||||
fail(
|
||||
"The following files contain third-party copyrights and no license information. " +
|
||||
"Please update license/README.md accordingly:\n${filesWithUnlistedCopyrights.joinToString("\n")}"
|
||||
)
|
||||
fail("The following files contain third-party copyrights and no license information. " +
|
||||
"Please update license/README.md accordingly:\n${filesWithUnlistedCopyrights.joinToString("\n")}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadKnownThirdPartyCodeList(): List<String> {
|
||||
File("license/README.md").useLines { lineSequence ->
|
||||
return lineSequence
|
||||
.filter { it.startsWith(" - Path: ") }
|
||||
.map { it.removePrefix(" - Path: ").trim().ensureFileOrEndsWithSlash() }
|
||||
.toList()
|
||||
.filter { it.startsWith(" - Path: ") }
|
||||
.map { it.removePrefix(" - Path: ").trim().ensureFileOrEndsWithSlash() }
|
||||
.toList()
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.ensureFileOrEndsWithSlash() =
|
||||
if (endsWith("/") || "." in substringAfterLast('/')) this else this + "/"
|
||||
if (endsWith("/") || "." in substringAfterLast('/')) this else this + "/"
|
||||
|
||||
+2
@@ -379,6 +379,8 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
|
||||
assertTrue { "kotlin-stdlib-js</artifactId><version>$kotlinVersion</version><scope>runtime</scope>" in pomText }
|
||||
|
||||
assertFileExists(moduleDir + "kotlin-js-plugin-1.0-sources.jar")
|
||||
|
||||
assertTestResults("testProject/kotlin-js-plugin-project/tests.xml", "test")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-17
@@ -297,7 +297,7 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMppNodeJsTestRun() = with(Project("new-mpp-js-tests", GradleVersionRequired.AtLeast("4.10.2"))) {
|
||||
fun testMppNodeJsTestRun() = with(Project("new-mpp-js-tests", GradleVersionRequired.AtLeast("5.0"))) {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
|
||||
gradleSettingsScript().modify(::transformBuildScriptWithPluginsDsl)
|
||||
@@ -307,12 +307,12 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
||||
assertSuccessful()
|
||||
|
||||
assertTasksRegisteredAndNotRealized(
|
||||
":clientKotlinJsNodeModules",
|
||||
":clientKotlinJsNodeModulesTestRuntime",
|
||||
":kotlinNodeJsTestRuntimeExtract",
|
||||
|
||||
":clientTestNodeModules",
|
||||
":clientTest",
|
||||
|
||||
":serverKotlinJsNodeModules",
|
||||
":serverKotlinJsNodeModulesTestRuntime",
|
||||
":serverTestNodeModules",
|
||||
":serverTest"
|
||||
)
|
||||
}
|
||||
@@ -321,12 +321,12 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
||||
assertSuccessful()
|
||||
|
||||
assertTasksExecuted(
|
||||
":clientKotlinJsNodeModules",
|
||||
":clientKotlinJsNodeModulesTestRuntime",
|
||||
":kotlinNodeJsTestRuntimeExtract",
|
||||
|
||||
":clientTestNodeModules",
|
||||
":clientTest",
|
||||
|
||||
":serverKotlinJsNodeModules",
|
||||
":serverKotlinJsNodeModulesTestRuntime",
|
||||
":serverTestNodeModules",
|
||||
":serverTest"
|
||||
)
|
||||
|
||||
@@ -339,12 +339,12 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
||||
assertSuccessful()
|
||||
|
||||
assertTasksUpToDate(
|
||||
":clientKotlinJsNodeModules",
|
||||
":clientKotlinJsNodeModulesTestRuntime",
|
||||
":kotlinNodeJsTestRuntimeExtract",
|
||||
|
||||
":clientTestNodeModules",
|
||||
":clientTest",
|
||||
|
||||
":serverKotlinJsNodeModules",
|
||||
":serverKotlinJsNodeModulesTestRuntime",
|
||||
":serverTestNodeModules",
|
||||
":serverTest"
|
||||
)
|
||||
}
|
||||
@@ -356,15 +356,14 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
||||
assertSuccessful()
|
||||
|
||||
assertTasksUpToDate(
|
||||
":clientKotlinJsNodeModulesTestRuntime",
|
||||
":serverKotlinJsNodeModulesTestRuntime"
|
||||
":kotlinNodeJsTestRuntimeExtract"
|
||||
)
|
||||
|
||||
assertTasksExecuted(
|
||||
":clientKotlinJsNodeModules",
|
||||
":clientTestNodeModules",
|
||||
":clientTest",
|
||||
|
||||
":serverKotlinJsNodeModules",
|
||||
":serverTestNodeModules",
|
||||
":serverTest"
|
||||
)
|
||||
|
||||
|
||||
+16
-8
@@ -1,15 +1,23 @@
|
||||
package com.example
|
||||
|
||||
import kotlinx.html.dom.create
|
||||
import kotlinx.html.js.div
|
||||
import kotlinx.html.p
|
||||
import kotlin.browser.document
|
||||
import kotlinx.html.a
|
||||
import kotlinx.html.body
|
||||
import kotlinx.html.div
|
||||
import kotlinx.html.html
|
||||
import kotlinx.html.stream.appendHTML
|
||||
|
||||
fun hello() = "hello"
|
||||
|
||||
fun main() {
|
||||
document.create.div {
|
||||
p { hello() }
|
||||
}
|
||||
console.log(hello())
|
||||
println(
|
||||
StringBuilder().appendHTML().html {
|
||||
body {
|
||||
div {
|
||||
a("https://kotlinlang.org") {
|
||||
hello()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<results>
|
||||
<testsuite name="MainTest" tests="1" skipped="0" failures="0" errors="0" timestamp="..." hostname="..." time="...">
|
||||
<properties />
|
||||
<testcase name="testHello" classname="MainTest" time="..." />
|
||||
<system-out />
|
||||
<system-err />
|
||||
</testsuite>
|
||||
</results>
|
||||
|
||||
+4
-4
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
|
||||
class TaskProviderHolder<T : Task>(project: Project, private val name: String, type: Class<T>, configureAction: (T) -> (Unit)) :
|
||||
TaskHolder<T> {
|
||||
private val provider: TaskProvider<T> = project.tasks.register(name, type, configureAction)
|
||||
class TaskProviderHolder<T : Task>(
|
||||
private val name: String,
|
||||
private val provider: TaskProvider<T>
|
||||
) : TaskHolder<T> {
|
||||
|
||||
override fun getTaskOrProvider(): Any = provider
|
||||
|
||||
|
||||
+44
-31
@@ -1,44 +1,52 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.internal.plugins.DslObject
|
||||
import org.gradle.api.plugins.JavaBasePlugin
|
||||
import org.gradle.testing.base.plugins.TestingBasePlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationToRunnableFiles
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsSetupTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.tasks.KotlinJsNodeModulesTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.tasks.KotlinNodeJsTestRuntimeToNodeModulesTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.tasks.KotlinNodeJsTestTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.io.File
|
||||
|
||||
internal class KotlinJsCompilationTestsConfigurator(
|
||||
val compilation: KotlinCompilationToRunnableFiles<*>
|
||||
val compilation: KotlinCompilationToRunnableFiles<*>
|
||||
) {
|
||||
private val target get() = compilation.target
|
||||
private val disambiguationClassifier get() = target.disambiguationClassifier
|
||||
private val project get() = target.project
|
||||
private val compileTestKotlin2Js get() = compilation.compileKotlinTask as Kotlin2JsCompile
|
||||
private val isSinglePlatformProject get() = target is KotlinWithJavaTarget<*>
|
||||
private val testTaskName: String
|
||||
get() = if (isSinglePlatformProject) "testJs" else camelCaseTargetName("test")
|
||||
|
||||
private fun camelCaseTargetName(prefix: String): String {
|
||||
return if (isSinglePlatformProject) prefix
|
||||
else target.name + prefix.capitalize()
|
||||
private fun disambiguate(name: String, includeCompilation: Boolean = false): MutableList<String> {
|
||||
val components = mutableListOf<String>()
|
||||
|
||||
components.addIfNotNull(disambiguationClassifier)
|
||||
if (includeCompilation) components.add(compilation.name)
|
||||
components.add(name)
|
||||
return components
|
||||
}
|
||||
|
||||
private fun disambiguateCamelCased(name: String, includeCompilation: Boolean): String {
|
||||
val components = disambiguate(name, includeCompilation)
|
||||
|
||||
return components.first() + components.drop(1).joinToString("") { it.capitalize() }
|
||||
}
|
||||
|
||||
@Suppress("SameParameterValue")
|
||||
private fun underscoredCompilationName(prefix: String): String {
|
||||
return if (isSinglePlatformProject) prefix
|
||||
else "${target.name}_${compilation.name}_$prefix"
|
||||
}
|
||||
private fun disambiguateUnderscored(name: String, includeCompilation: Boolean) =
|
||||
disambiguate(name, includeCompilation).joinToString("_")
|
||||
|
||||
private val testTaskName: String
|
||||
get() = disambiguateCamelCased("test", false)
|
||||
|
||||
private val nodeModulesDir
|
||||
get() = project.buildDir.resolve(underscoredCompilationName("node_modules"))
|
||||
get() = project.buildDir.resolve(disambiguateUnderscored("node_modules", true))
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
private val Project.testResults: File
|
||||
@@ -56,41 +64,46 @@ internal class KotlinJsCompilationTestsConfigurator(
|
||||
|
||||
fun configure() {
|
||||
val nodeModulesTask = registerTask(
|
||||
project,
|
||||
camelCaseTargetName("kotlinJsNodeModules"),
|
||||
KotlinJsNodeModulesTask::class.java
|
||||
project,
|
||||
disambiguateCamelCased("nodeModules", true),
|
||||
KotlinJsNodeModulesTask::class.java
|
||||
) {
|
||||
it.dependsOn(compileTestKotlin2Js)
|
||||
|
||||
it.onlyIf {
|
||||
compileTestKotlin2Js.outputFile.exists()
|
||||
}
|
||||
|
||||
it.nodeModulesDir = nodeModulesDir
|
||||
it.classpath = compileTask.jsRuntimeClasspath
|
||||
}
|
||||
|
||||
val nodeModulesTestRuntimeTask = registerTask(
|
||||
project,
|
||||
camelCaseTargetName("kotlinJsNodeModulesTestRuntime"),
|
||||
KotlinNodeJsTestRuntimeToNodeModulesTask::class.java
|
||||
) {
|
||||
it.nodeModulesDir = nodeModulesDir
|
||||
}
|
||||
|
||||
val projectWithNodeJsPlugin = NodeJsPlugin.ensureAppliedInHierarchy(target.project)
|
||||
val kotlinJsExtractTestRunnerTask = project.kotlinNodeJsTestRuntimeExtractTask
|
||||
|
||||
val testTask = registerTask(project, testTaskName, KotlinNodeJsTestTask::class.java) { testJs ->
|
||||
testJs.group = "verification"
|
||||
|
||||
testJs.dependsOn(
|
||||
nodeModulesTask.getTaskOrProvider(),
|
||||
nodeModulesTestRuntimeTask.getTaskOrProvider()
|
||||
nodeModulesTask.getTaskOrProvider(),
|
||||
kotlinJsExtractTestRunnerTask.getTaskOrProvider()
|
||||
)
|
||||
|
||||
if (!isSinglePlatformProject) {
|
||||
testJs.targetName = target.name
|
||||
testJs.onlyIf {
|
||||
// run only if there is org.jetbrains.kotlin:kotlin-test-js in classpath
|
||||
// (kotlin-test-nodejs-runner.js requires kotlin-test.js)
|
||||
nodeModulesDir.resolve("kotlin-test.js").exists()
|
||||
compileTestKotlin2Js.outputFile.exists()
|
||||
}
|
||||
|
||||
if (disambiguationClassifier != null) {
|
||||
testJs.targetName = disambiguationClassifier
|
||||
}
|
||||
|
||||
testJs.nodeJsProcessOptions.workingDir = project.projectDir
|
||||
|
||||
testJs.nodeModulesDir = nodeModulesDir
|
||||
testJs.testRuntimeNodeModule = project.extractedKotlinTestNodeJsRunner
|
||||
testJs.nodeModulesToLoad = setOf(compileTestKotlin2Js.outputFile.name)
|
||||
|
||||
val htmlReport = DslObject(testJs.reports.html)
|
||||
|
||||
+14
-4
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.targets.js
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
|
||||
class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
||||
@@ -19,13 +18,24 @@ class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
||||
return Kotlin2JsSourceSetProcessor(compilation.target.project, tasksProvider, compilation, kotlinPluginVersion)
|
||||
}
|
||||
|
||||
override fun configureCompilations(platformTarget: KotlinOnlyTarget<KotlinJsCompilation>) {
|
||||
super.configureCompilations(platformTarget)
|
||||
|
||||
platformTarget.compilations.all {
|
||||
it.compileKotlinTask.kotlinOptions.moduleKind = "umd"
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureTest(target: KotlinOnlyTarget<KotlinJsCompilation>) {
|
||||
target.compilations.all {
|
||||
it.compileKotlinTask.kotlinOptions.moduleKind = "umd"
|
||||
|
||||
if (it.name == KotlinCompilation.TEST_COMPILATION_NAME) {
|
||||
if (isTestCompilation(it)) {
|
||||
KotlinJsCompilationTestsConfigurator(it).configure()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal fun isTestCompilation(it: KotlinJsCompilation) =
|
||||
it.name == KotlinCompilation.TEST_COMPILATION_NAME
|
||||
}
|
||||
}
|
||||
-4
@@ -7,12 +7,8 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.plugin.Kotlin2JsSourceSetProcessor
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
|
||||
open class KotlinJsTargetPreset(
|
||||
project: Project,
|
||||
|
||||
+14
-4
@@ -35,10 +35,15 @@ open class NodeJsSetupTask : DefaultTask() {
|
||||
val repo = project.repositories.ivy { repo ->
|
||||
repo.name = "Node Distributions at ${settings.distBaseUrl}"
|
||||
repo.url = URI(settings.distBaseUrl)
|
||||
repo.layout("pattern") { layout ->
|
||||
layout as IvyPatternRepositoryLayout
|
||||
layout.artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]")
|
||||
layout.ivy("v[revision]/ivy.xml")
|
||||
|
||||
if (isGradleVersionAtLeast(5, 0)) {
|
||||
repo.patternLayout { layout ->
|
||||
configureNodeJsIvyPatternLayout(layout)
|
||||
}
|
||||
} else {
|
||||
repo.layout("pattern") { layout ->
|
||||
configureNodeJsIvyPatternLayout(layout as IvyPatternRepositoryLayout)
|
||||
}
|
||||
}
|
||||
repo.metadataSources { it.artifact() }
|
||||
|
||||
@@ -62,6 +67,11 @@ open class NodeJsSetupTask : DefaultTask() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureNodeJsIvyPatternLayout(layout: IvyPatternRepositoryLayout) {
|
||||
layout.artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]")
|
||||
layout.ivy("v[revision]/ivy.xml")
|
||||
}
|
||||
|
||||
private fun unpackNodeArchive(archive: File, destination: File) {
|
||||
project.logger.kotlinInfo("Unpacking $archive to $destination")
|
||||
|
||||
|
||||
+8
-8
@@ -22,27 +22,27 @@ open class KotlinJsNodeModulesTask : DefaultTask() {
|
||||
|
||||
@TaskAction
|
||||
fun copyFromRuntimeClasspath() {
|
||||
project.copy { copy ->
|
||||
copy.includeEmptyDirs = false
|
||||
project.sync { sync ->
|
||||
sync.includeEmptyDirs = false
|
||||
|
||||
classpath.forEach {
|
||||
if (it.isZip) copy.from(project.zipTree(it))
|
||||
else copy.from(it)
|
||||
if (it.isZip) sync.from(project.zipTree(it))
|
||||
else sync.from(it)
|
||||
}
|
||||
|
||||
copy.include { fileTreeElement ->
|
||||
sync.include { fileTreeElement ->
|
||||
isKotlinJsRuntimeFile(fileTreeElement.file)
|
||||
}
|
||||
|
||||
copy.into(nodeModulesDir)
|
||||
sync.into(nodeModulesDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val File.isZip
|
||||
private val File.isZip
|
||||
get() = isFile && name.endsWith(".jar")
|
||||
|
||||
fun isKotlinJsRuntimeFile(file: File): Boolean {
|
||||
internal fun isKotlinJsRuntimeFile(file: File): Boolean {
|
||||
if (!file.isFile) return false
|
||||
val name = file.name
|
||||
return (name.endsWith(".js") && !name.endsWith(".meta.js"))
|
||||
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.*
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
|
||||
const val kotlinNodeJsTestRuntimeBin: String = "kotlin-js-test"
|
||||
|
||||
open class KotlinNodeJsTestRuntimeToNodeModulesTask : DefaultTask() {
|
||||
@Input
|
||||
public var resourceName: String = "/kotlin-js-test.js"
|
||||
|
||||
@OutputDirectory
|
||||
@SkipWhenEmpty
|
||||
public lateinit var nodeModulesDir: File
|
||||
|
||||
@TaskAction
|
||||
fun copyRuntime() {
|
||||
val testsRuntime = javaClass.getResourceAsStream(resourceName) ?: error("Cannot find `$resourceName` in resources")
|
||||
val bin = nodeModulesDir.resolve(".bin").resolve(kotlinNodeJsTestRuntimeBin)
|
||||
bin.parentFile.mkdirs()
|
||||
Files.copy(
|
||||
testsRuntime,
|
||||
bin.toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class KotlinNodeJsTestRunnerCliArgs(
|
||||
val moduleNames: List<String>,
|
||||
val include: Collection<String> = listOf(),
|
||||
val exclude: Collection<String> = listOf(),
|
||||
val ignoredTestSuites: IgnoredTestSuitesReporting = IgnoredTestSuitesReporting.reportAllInnerTestsAsIgnored
|
||||
) {
|
||||
fun toList(): List<String> = mutableListOf<String>().also { args ->
|
||||
if (include.isNotEmpty()) {
|
||||
args.add("--include")
|
||||
args.add(include.joinToString(","))
|
||||
}
|
||||
|
||||
if (exclude.isNotEmpty()) {
|
||||
args.add("--exclude")
|
||||
args.add(exclude.joinToString(","))
|
||||
}
|
||||
|
||||
if (ignoredTestSuites !== IgnoredTestSuitesReporting.reportAllInnerTestsAsIgnored) {
|
||||
args.add("--ignoredTestSuites")
|
||||
args.add(ignoredTestSuites.name)
|
||||
}
|
||||
|
||||
args.addAll(moduleNames)
|
||||
}
|
||||
|
||||
@Suppress("EnumEntryName")
|
||||
enum class IgnoredTestSuitesReporting {
|
||||
skip, reportAsIgnoredTest, reportAllInnerTestsAsIgnored
|
||||
}
|
||||
}
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.SkipWhenEmpty
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
|
||||
const val kotlinTestNodeJsRunnerJs = "kotlin-test-nodejs-runner.js"
|
||||
|
||||
internal val Project.extractedKotlinTestNodeJsRunner: File
|
||||
get() = project.buildDir.resolve("kotlin/$kotlinTestNodeJsRunnerJs")
|
||||
|
||||
internal val Project.kotlinNodeJsTestRuntimeExtractTask
|
||||
get() = project.locateOrRegisterTask<KotlinNodeJsTestRuntimeExtractTask>(
|
||||
"kotlinNodeJsTestRuntimeExtract"
|
||||
) { task ->
|
||||
task.destination = extractedKotlinTestNodeJsRunner
|
||||
}
|
||||
|
||||
open class KotlinNodeJsTestRuntimeExtractTask : DefaultTask() {
|
||||
@Input
|
||||
public var resourceName: String = "/$kotlinTestNodeJsRunnerJs"
|
||||
|
||||
@OutputFile
|
||||
@SkipWhenEmpty
|
||||
public lateinit var destination: File
|
||||
|
||||
@TaskAction
|
||||
fun copyRuntime() {
|
||||
val testsRuntime = javaClass.getResourceAsStream(resourceName)
|
||||
?: error("Cannot find `$resourceName` in resources")
|
||||
|
||||
check(destination.parentFile.exists() || destination.parentFile.mkdirs()) {
|
||||
"Cannot create directory ${destination.parentFile}"
|
||||
}
|
||||
|
||||
Files.copy(
|
||||
testsRuntime,
|
||||
destination.toPath(),
|
||||
StandardCopyOption.REPLACE_EXISTING
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+33
-7
@@ -45,8 +45,7 @@ open class KotlinNodeJsTestTask : AbstractTestTask() {
|
||||
var nodeModulesToLoad: Set<String> = setOf()
|
||||
|
||||
@InputFile
|
||||
@Optional
|
||||
var testRuntimeNodeModule: File? = null
|
||||
lateinit var testRuntimeNodeModule: File
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
private val filterExt: DefaultTestFilter
|
||||
@@ -99,7 +98,7 @@ open class KotlinNodeJsTestTask : AbstractTestTask() {
|
||||
|
||||
return TCServiceMessagesTestExecutionSpec(
|
||||
extendedForkOptions,
|
||||
listOf(finalTestRuntimeNodeModule.absolutePath) + cliArgs.toList(),
|
||||
listOf(testRuntimeNodeModule.absolutePath) + cliArgs.toList(),
|
||||
clientSettings
|
||||
)
|
||||
}
|
||||
@@ -108,16 +107,43 @@ open class KotlinNodeJsTestTask : AbstractTestTask() {
|
||||
open val execHandleFactory: ExecHandleFactory
|
||||
get() = injected
|
||||
|
||||
private val finalTestRuntimeNodeModule: File
|
||||
get() = testRuntimeNodeModule
|
||||
?: nodeModulesDir!!.resolve(".bin").resolve(kotlinNodeJsTestRuntimeBin)
|
||||
|
||||
override fun createTestExecuter() = TCServiceMessagesTestExecutor(
|
||||
execHandleFactory,
|
||||
buildOperationExecutor
|
||||
)
|
||||
}
|
||||
|
||||
data class KotlinNodeJsTestRunnerCliArgs(
|
||||
val moduleNames: List<String>,
|
||||
val include: Collection<String> = listOf(),
|
||||
val exclude: Collection<String> = listOf(),
|
||||
val ignoredTestSuites: IgnoredTestSuitesReporting = IgnoredTestSuitesReporting.reportAllInnerTestsAsIgnored
|
||||
) {
|
||||
fun toList(): List<String> = mutableListOf<String>().also { args ->
|
||||
if (include.isNotEmpty()) {
|
||||
args.add("--include")
|
||||
args.add(include.joinToString(","))
|
||||
}
|
||||
|
||||
if (exclude.isNotEmpty()) {
|
||||
args.add("--exclude")
|
||||
args.add(exclude.joinToString(","))
|
||||
}
|
||||
|
||||
if (ignoredTestSuites !== IgnoredTestSuitesReporting.reportAllInnerTestsAsIgnored) {
|
||||
args.add("--ignoredTestSuites")
|
||||
args.add(ignoredTestSuites.name)
|
||||
}
|
||||
|
||||
args.addAll(moduleNames)
|
||||
}
|
||||
|
||||
@Suppress("EnumEntryName")
|
||||
enum class IgnoredTestSuitesReporting {
|
||||
skip, reportAsIgnoredTest, reportAllInnerTestsAsIgnored
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableMap<String, Any>.addPath(key: String, path: String) {
|
||||
val prev = get(key)
|
||||
if (prev == null) set(key, path)
|
||||
|
||||
+32
-3
@@ -18,20 +18,22 @@ package org.jetbrains.kotlin.gradle.tasks
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.UnknownTaskException
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.defaultSourceSetName
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask
|
||||
|
||||
internal val useLazyTaskConfiguration = org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast(4, 9)
|
||||
internal val canLocateTask = org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast(5, 0)
|
||||
|
||||
/**
|
||||
* Registers the task with name @param name and type @param type and initialization script @param body
|
||||
* If gradle with version <4.9 is used the task will be created
|
||||
* Registers the task with [name] and [type] and initialization script [body]
|
||||
* If Gradle with version <4.9 is used the task will be created
|
||||
*/
|
||||
internal fun <T : Task> registerTask(project: Project, name: String, type: Class<T>, body: (T) -> (Unit)): TaskHolder<T> {
|
||||
return if (useLazyTaskConfiguration) {
|
||||
TaskProviderHolder(project, name, type) { with(it, body) }
|
||||
TaskProviderHolder(name, project.tasks.register(name, type) { with(it, body) })
|
||||
} else {
|
||||
val result = LegacyTaskHolder(project.tasks.create(name, type))
|
||||
with(result.doGetTask(), body)
|
||||
@@ -39,6 +41,33 @@ internal fun <T : Task> registerTask(project: Project, name: String, type: Class
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates a task by [name] and [type], without triggering its creation or configuration.
|
||||
*/
|
||||
internal fun <T : Task> locateTask(project: Project, name: String, type: Class<T>): TaskHolder<T>? =
|
||||
if (canLocateTask) {
|
||||
try {
|
||||
TaskProviderHolder(name, project.tasks.named(name, type))
|
||||
} catch (e: UnknownTaskException) {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
project.tasks.findByName(name)?.let {
|
||||
check(type.isInstance(it))
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
LegacyTaskHolder(it as T)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates a task by [name] and [type], without triggering its creation or configuration or registers new task
|
||||
* with [name], type [T] and initialization script [body]
|
||||
*/
|
||||
internal inline fun <reified T : Task> Project.locateOrRegisterTask(name: String, noinline body: (T) -> (Unit)): TaskHolder<T> {
|
||||
return locateTask(project, name, T::class.java) ?: registerTask(project, name, T::class.java, body)
|
||||
}
|
||||
|
||||
internal open class KotlinTasksProvider(val targetName: String) {
|
||||
open fun registerKotlinJVMTask(
|
||||
project: Project,
|
||||
|
||||
+1
-1
@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.gradle.utils
|
||||
/**
|
||||
* Utility for functions annotated with @Inject
|
||||
*/
|
||||
val injected: Nothing get() = error("Should be injected");
|
||||
internal val injected: Nothing get() = error("Should be injected");
|
||||
|
||||
@@ -26,7 +26,7 @@ tasks {
|
||||
args = listOf("build")
|
||||
|
||||
inputs.dir(projectDir.resolve("src"))
|
||||
outputs.file(projectDir.resolve("lib/kotlin-js-test.js"))
|
||||
outputs.file(projectDir.resolve("lib/kotlin-test-nodejs-runner.js"))
|
||||
}
|
||||
|
||||
create<Delete>("cleanYarn") {
|
||||
@@ -43,7 +43,7 @@ tasks {
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("archives", projectDir.resolve("lib/kotlin-js-test.js")) {
|
||||
add("archives", projectDir.resolve("lib/kotlin-test-nodejs-runner.js")) {
|
||||
builtBy("yarnBuild")
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export default [
|
||||
{
|
||||
input: './cli.ts',
|
||||
output: {
|
||||
file: 'lib/kotlin-js-test.js',
|
||||
file: 'lib/kotlin-test-nodejs-runner.js',
|
||||
format: 'cjs',
|
||||
banner: '#!/usr/bin/env node'
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user