[Gradle] Migrate Kotlin/JS tests to the new test DSL
#KT-45745 In Progress
This commit is contained in:
@@ -66,6 +66,9 @@ val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild ||
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
|
||||||
|
kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.io.path.ExperimentalPathApi"
|
||||||
|
}
|
||||||
|
|
||||||
val cleanTestKitCacheTask = tasks.register<Delete>("cleanTestKitCache") {
|
val cleanTestKitCacheTask = tasks.register<Delete>("cleanTestKitCache") {
|
||||||
group = "Build"
|
group = "Build"
|
||||||
|
|||||||
+12
-74
@@ -11,15 +11,16 @@ import org.gradle.api.logging.configuration.WarningMode
|
|||||||
import org.gradle.tooling.GradleConnector
|
import org.gradle.tooling.GradleConnector
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.intellij.lang.annotations.Language
|
import org.intellij.lang.annotations.Language
|
||||||
import org.jdom.Element
|
|
||||||
import org.jdom.input.SAXBuilder
|
|
||||||
import org.jdom.output.Format
|
|
||||||
import org.jdom.output.XMLOutputter
|
|
||||||
import org.jetbrains.kotlin.gradle.model.ModelContainer
|
import org.jetbrains.kotlin.gradle.model.ModelContainer
|
||||||
import org.jetbrains.kotlin.gradle.model.ModelFetcherBuildAction
|
import org.jetbrains.kotlin.gradle.model.ModelFetcherBuildAction
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
|
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
|
||||||
import org.jetbrains.kotlin.gradle.testbase.enableCacheRedirector
|
import org.jetbrains.kotlin.gradle.testbase.enableCacheRedirector
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.extractJavaCompiledSources
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.extractKotlinCompiledSources
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.prettyPrintXml
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.readAndCleanupTestResults
|
||||||
import org.jetbrains.kotlin.gradle.util.*
|
import org.jetbrains.kotlin.gradle.util.*
|
||||||
|
import org.jetbrains.kotlin.gradle.util.modify
|
||||||
import org.jetbrains.kotlin.test.RunnerWithMuteInDatabase
|
import org.jetbrains.kotlin.test.RunnerWithMuteInDatabase
|
||||||
import org.jetbrains.kotlin.test.util.trimTrailingWhitespaces
|
import org.jetbrains.kotlin.test.util.trimTrailingWhitespaces
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@@ -29,6 +30,7 @@ import org.junit.Before
|
|||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
import kotlin.io.path.isDirectory
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
val SYSTEM_LINE_SEPARATOR: String = System.getProperty("line.separator")
|
val SYSTEM_LINE_SEPARATOR: String = System.getProperty("line.separator")
|
||||||
@@ -372,24 +374,11 @@ abstract class BaseGradleIT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CompiledProject(val project: Project, val output: String, val resultCode: Int) {
|
class CompiledProject(val project: Project, val output: String, val resultCode: Int) {
|
||||||
companion object {
|
fun getCompiledKotlinSources(output: String) =
|
||||||
val kotlinSourcesListRegex = Regex("\\[KOTLIN\\] compile iteration: ([^\\r\\n]*)")
|
extractKotlinCompiledSources(project.projectDir.toPath(), output).map { sourcePath -> sourcePath.toFile() }
|
||||||
val javaSourcesListRegex = Regex("\\[DEBUG\\] \\[[^\\]]*JavaCompiler\\] Compiler arguments: ([^\\r\\n]*)")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCompiledFiles(regex: Regex, output: String) = regex.findAll(output)
|
|
||||||
.asIterable()
|
|
||||||
.flatMap {
|
|
||||||
it.groups[1]!!.value.split(", ")
|
|
||||||
.map { File(project.projectDir, it).canonicalFile }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCompiledKotlinSources(output: String) = getCompiledFiles(kotlinSourcesListRegex, output)
|
|
||||||
|
|
||||||
val compiledJavaSources: Iterable<File> by lazy {
|
val compiledJavaSources: Iterable<File> by lazy {
|
||||||
javaSourcesListRegex.findAll(output).asIterable().flatMap {
|
extractJavaCompiledSources(output).map { sourcePath -> sourcePath.toFile() }
|
||||||
it.groups[1]!!.value.split(" ").filter { it.endsWith(".java", ignoreCase = true) }.map { File(it).canonicalFile }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -846,71 +835,20 @@ Finished executing task ':$taskName'|
|
|||||||
vararg testReportNames: String
|
vararg testReportNames: String
|
||||||
) {
|
) {
|
||||||
val projectDir = project.projectDir
|
val projectDir = project.projectDir
|
||||||
val testReportDirs = testReportNames.map { projectDir.resolve("build/test-results/$it") }
|
val testReportDirs = testReportNames.map { projectDir.resolve("build/test-results/$it").toPath() }
|
||||||
|
|
||||||
testReportDirs.forEach {
|
testReportDirs.forEach {
|
||||||
if (!it.isDirectory) {
|
if (!it.isDirectory()) {
|
||||||
error("Test report dir $it was not created")
|
error("Test report dir $it was not created")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val actualTestResults = readAndCleanupTestResults(testReportDirs, projectDir)
|
val actualTestResults = readAndCleanupTestResults(testReportDirs, projectDir.toPath())
|
||||||
val expectedTestResults = prettyPrintXml(resourcesRootFile.resolve(assertionFileName).readText())
|
val expectedTestResults = prettyPrintXml(resourcesRootFile.resolve(assertionFileName).readText())
|
||||||
|
|
||||||
assertEquals(expectedTestResults, actualTestResults)
|
assertEquals(expectedTestResults, actualTestResults)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readAndCleanupTestResults(testReportDirs: List<File>, projectDir: File): String {
|
|
||||||
val files = testReportDirs
|
|
||||||
.flatMap {
|
|
||||||
(it.listFiles() ?: arrayOf()).filter {
|
|
||||||
it.isFile && it.name.endsWith(".xml")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sortedBy {
|
|
||||||
// let containing test suite be first
|
|
||||||
it.name.replace(".xml", ".A.xml")
|
|
||||||
}
|
|
||||||
|
|
||||||
val xmlString = buildString {
|
|
||||||
appendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
|
|
||||||
appendLine("<results>")
|
|
||||||
files.forEach { file ->
|
|
||||||
appendLine(
|
|
||||||
file.readText()
|
|
||||||
.trimTrailingWhitespaces()
|
|
||||||
.replace(projectDir.absolutePath, "/\$PROJECT_DIR$")
|
|
||||||
.replace(projectDir.name, "\$PROJECT_NAME$")
|
|
||||||
.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
appendLine("</results>")
|
|
||||||
}
|
|
||||||
|
|
||||||
val doc = SAXBuilder().build(xmlString.reader())
|
|
||||||
val skipAttrs = setOf("timestamp", "hostname", "time", "message")
|
|
||||||
val skipContentsOf = setOf("failure")
|
|
||||||
|
|
||||||
fun cleanup(e: Element) {
|
|
||||||
if (e.name in skipContentsOf) e.text = "..."
|
|
||||||
e.attributes.forEach {
|
|
||||||
if (it.name in skipAttrs) {
|
|
||||||
it.value = "..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e.children.forEach {
|
|
||||||
cleanup(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup(doc.rootElement)
|
|
||||||
return XMLOutputter(Format.getPrettyFormat()).outputString(doc)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun prettyPrintXml(uglyXml: String): String =
|
|
||||||
XMLOutputter(Format.getPrettyFormat()).outputString(SAXBuilder().build(uglyXml.reader()))
|
|
||||||
|
|
||||||
private fun Project.createGradleTailParameters(options: BuildOptions, params: Array<out String> = arrayOf()): List<String> =
|
private fun Project.createGradleTailParameters(options: BuildOptions, params: Array<out String> = arrayOf()): List<String> =
|
||||||
params.toMutableList().apply {
|
params.toMutableList().apply {
|
||||||
add("--stacktrace")
|
add("--stacktrace")
|
||||||
|
|||||||
-2
@@ -148,7 +148,6 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() {
|
|||||||
fun testConfigurationCacheJsPlugin(gradleVersion: GradleVersion) {
|
fun testConfigurationCacheJsPlugin(gradleVersion: GradleVersion) {
|
||||||
project("kotlin-js-browser-project", gradleVersion) {
|
project("kotlin-js-browser-project", gradleVersion) {
|
||||||
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
||||||
settingsGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
|
||||||
|
|
||||||
testConfigurationCacheOf(
|
testConfigurationCacheOf(
|
||||||
":app:build",
|
":app:build",
|
||||||
@@ -187,7 +186,6 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() {
|
|||||||
configure: TestProject.() -> Unit = {}
|
configure: TestProject.() -> Unit = {}
|
||||||
) = project("dukat-integration/both", gradleVersion) {
|
) = project("dukat-integration/both", gradleVersion) {
|
||||||
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
||||||
settingsGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
|
||||||
configure(this)
|
configure(this)
|
||||||
testConfigurationCacheOf(
|
testConfigurationCacheOf(
|
||||||
"irGenerateExternalsIntegrated",
|
"irGenerateExternalsIntegrated",
|
||||||
|
|||||||
+863
-900
File diff suppressed because it is too large
Load Diff
+1
@@ -31,6 +31,7 @@ class KotlinSpecificDependenciesIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun jsProject() = Project("kotlin-js-plugin-project").apply {
|
private fun jsProject() = Project("kotlin-js-plugin-project").apply {
|
||||||
|
// TODO: remove settings.gradle from test project after migrating to the new test DSL
|
||||||
setupWorkingDir()
|
setupWorkingDir()
|
||||||
gradleBuildScript().modify { it.lines().filter { "html" !in it }.joinToString("\n") }
|
gradleBuildScript().modify { it.lines().filter { "html" !in it }.joinToString("\n") }
|
||||||
projectFile("Main.kt").modify { "fun f() = listOf(1, 2, 3).joinToString()" }
|
projectFile("Main.kt").modify { "fun f() = listOf(1, 2, 3).joinToString()" }
|
||||||
|
|||||||
+1
-1
@@ -127,7 +127,7 @@ class SimpleKotlinGradleIT : KGPBaseTest() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
build("build") {
|
build("build") {
|
||||||
assertDirectoryExists("$customBuildDirName/classes")
|
assertDirectoryInProjectExists("$customBuildDirName/classes")
|
||||||
assertFileNotExists("build")
|
assertFileNotExists("build")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-8
@@ -5,20 +5,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.tasks
|
package org.jetbrains.kotlin.gradle.tasks
|
||||||
|
|
||||||
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
|
import org.jetbrains.kotlin.gradle.transformProjectWithPluginsDsl
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
|
||||||
|
|
||||||
class CleanDataTaskIT : BaseGradleIT() {
|
@SimpleGradlePluginTests
|
||||||
|
class CleanDataTaskIT : KGPBaseTest() {
|
||||||
|
|
||||||
@Test
|
@DisplayName("nodejs is deleted from Gradle user home")
|
||||||
fun testDownloadedFolderDeletion() {
|
@GradleTest
|
||||||
val project = transformProjectWithPluginsDsl("cleanTask")
|
fun testDownloadedFolderDeletion(gradleVersion: GradleVersion) {
|
||||||
|
project("cleanTask", gradleVersion) {
|
||||||
project.build("testCleanTask") {
|
build("testCleanTask")
|
||||||
assertSuccessful()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-1
@@ -9,6 +9,7 @@ import org.gradle.api.logging.LogLevel
|
|||||||
import org.gradle.api.logging.configuration.WarningMode
|
import org.gradle.api.logging.configuration.WarningMode
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
|
||||||
|
|
||||||
data class BuildOptions(
|
data class BuildOptions(
|
||||||
val logLevel: LogLevel = LogLevel.INFO,
|
val logLevel: LogLevel = LogLevel.INFO,
|
||||||
@@ -23,7 +24,8 @@ data class BuildOptions(
|
|||||||
val fileSystemWatchEnabled: Boolean = false,
|
val fileSystemWatchEnabled: Boolean = false,
|
||||||
val buildCacheEnabled: Boolean = false,
|
val buildCacheEnabled: Boolean = false,
|
||||||
val kaptOptions: KaptOptions? = null,
|
val kaptOptions: KaptOptions? = null,
|
||||||
val androidVersion: String? = null
|
val androidVersion: String? = null,
|
||||||
|
val jsOptions: JsOptions? = null,
|
||||||
) {
|
) {
|
||||||
data class KaptOptions(
|
data class KaptOptions(
|
||||||
val verbose: Boolean = false,
|
val verbose: Boolean = false,
|
||||||
@@ -33,6 +35,13 @@ data class BuildOptions(
|
|||||||
val classLoadersCacheSize: Int? = null
|
val classLoadersCacheSize: Int? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class JsOptions(
|
||||||
|
val useIrBackend: Boolean? = null,
|
||||||
|
val jsCompilerType: KotlinJsCompilerType? = null,
|
||||||
|
val incrementalJs: Boolean? = null,
|
||||||
|
val incrementalJsKlib: Boolean? = null,
|
||||||
|
)
|
||||||
|
|
||||||
fun toArguments(
|
fun toArguments(
|
||||||
gradleVersion: GradleVersion
|
gradleVersion: GradleVersion
|
||||||
): List<String> {
|
): List<String> {
|
||||||
@@ -90,6 +99,13 @@ data class BuildOptions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (jsOptions != null) {
|
||||||
|
jsOptions.incrementalJs?.let { arguments.add("-Pkotlin.incremental.js=$it") }
|
||||||
|
jsOptions.incrementalJsKlib?.let { arguments.add("-Pkotlin.incremental.js.klib=$it") }
|
||||||
|
jsOptions.useIrBackend?.let { arguments.add("-Pkotlin.js.useIrBackend=$it") }
|
||||||
|
jsOptions.jsCompilerType?.let { arguments.add("-Pkotlin.js.compiler=$it") }
|
||||||
|
}
|
||||||
|
|
||||||
if (androidVersion != null) {
|
if (androidVersion != null) {
|
||||||
arguments.add("-Pandroid_tools_version=${androidVersion}")
|
arguments.add("-Pandroid_tools_version=${androidVersion}")
|
||||||
}
|
}
|
||||||
|
|||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.testbase
|
||||||
|
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.relativeTo
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
|
|
||||||
|
private val kotlinSrcRegex by lazy { Regex("\\[KOTLIN\\] compile iteration: ([^\\r\\n]*)") }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts list of compiled .kt files from task output
|
||||||
|
*
|
||||||
|
* Note: log level of output should be set to [LogLevel.DEBUG]
|
||||||
|
*/
|
||||||
|
fun extractKotlinCompiledSources(projectDirectory: Path, output: String) =
|
||||||
|
kotlinSrcRegex.findAll(output)
|
||||||
|
.asIterable()
|
||||||
|
.flatMap { result ->
|
||||||
|
result.groups[1]!!.value.split(", ")
|
||||||
|
.map { source -> projectDirectory.resolve(source).normalize() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val javaSrcRegex by lazy { Regex("\\[DEBUG\\] \\[[^\\]]*JavaCompiler\\] Compiler arguments: ([^\\r\\n]*)") }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts list of compiled .java files from task output
|
||||||
|
*
|
||||||
|
* Note: log level of output should be set to [LogLevel.DEBUG]
|
||||||
|
*/
|
||||||
|
fun extractJavaCompiledSources(output: String): List<Path> =
|
||||||
|
javaSrcRegex.findAll(output).asIterable().flatMap {
|
||||||
|
it.groups[1]!!.value
|
||||||
|
.split(" ")
|
||||||
|
.filter { source -> source.endsWith(".java", ignoreCase = true) }
|
||||||
|
.map { source -> Paths.get(source).normalize() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts all the .kt files from [expectedSources] and only they are compiled
|
||||||
|
*
|
||||||
|
* Note: log level of output should be set to [LogLevel.DEBUG]
|
||||||
|
*/
|
||||||
|
fun GradleProject.assertCompiledKotlinSources(expectedSources: Iterable<Path>, output: String) {
|
||||||
|
val actualSources = extractKotlinCompiledSources(projectPath, output).map {
|
||||||
|
it.relativeTo(projectPath)
|
||||||
|
}
|
||||||
|
assertSameFiles(expectedSources, actualSources, "Compiled Kotlin files differ:\n")
|
||||||
|
}
|
||||||
+99
-8
@@ -7,6 +7,10 @@ package org.jetbrains.kotlin.gradle.testbase
|
|||||||
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.isDirectory
|
||||||
|
import kotlin.io.path.readText
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts file under [file] path exists and is a regular file.
|
* Asserts file under [file] path exists and is a regular file.
|
||||||
@@ -47,16 +51,103 @@ fun GradleProject.assertFileNotExists(
|
|||||||
/**
|
/**
|
||||||
* Asserts directory under [pathToDir] relative to the test project exists and is a directory.
|
* Asserts directory under [pathToDir] relative to the test project exists and is a directory.
|
||||||
*/
|
*/
|
||||||
fun GradleProject.assertDirectoryExists(
|
fun GradleProject.assertDirectoryInProjectExists(
|
||||||
pathToDir: String
|
pathToDir: String
|
||||||
|
) = assertDirectoryExists(projectPath.resolve(pathToDir))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts directory under [file] exists and is a directory.
|
||||||
|
*/
|
||||||
|
fun GradleProject.assertDirectoryExists(
|
||||||
|
dirPath: Path
|
||||||
|
) = assertDirectoriesExist(dirPath)
|
||||||
|
|
||||||
|
fun GradleProject.assertDirectoriesExist(
|
||||||
|
vararg dirPaths: Path
|
||||||
) {
|
) {
|
||||||
val dirPath = projectPath.resolve(pathToDir)
|
val (exist, notExist) = dirPaths.partition { it.exists() }
|
||||||
|
val notDirectories = exist.filterNot { it.isDirectory() }
|
||||||
|
|
||||||
assert(Files.exists(dirPath)) {
|
assert(notExist.isEmpty() && notDirectories.isEmpty()) {
|
||||||
"Directory '${dirPath}' does not exist!"
|
buildString {
|
||||||
}
|
if (notExist.isNotEmpty()) {
|
||||||
|
appendLine("Following directories does not exist:")
|
||||||
assert(Files.isDirectory(dirPath)) {
|
appendLine(notExist.joinToString(separator = "\n"))
|
||||||
"'${dirPath}' is not a directory!"
|
}
|
||||||
|
if (notDirectories.isNotEmpty()) {
|
||||||
|
appendLine("Following files should be directories:")
|
||||||
|
appendLine(notExist.joinToString(separator = "\n"))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts file under [pathToFile] relative to the test project exists and contains all the lines from [expectedLines]
|
||||||
|
*/
|
||||||
|
fun GradleProject.assertFileInProjectContains(
|
||||||
|
pathToFile: String,
|
||||||
|
vararg expectedText: String
|
||||||
|
) {
|
||||||
|
assertFileContains(projectPath.resolve(pathToFile), *expectedText)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts file under [pathToFile] relative to the test project exists and does not contain any line from [unexpectedText]
|
||||||
|
*/
|
||||||
|
fun GradleProject.assertFileInProjectDoesNotContain(
|
||||||
|
pathToFile: String,
|
||||||
|
vararg unexpectedText: String
|
||||||
|
) {
|
||||||
|
assertFileDoesNotContain(projectPath.resolve(pathToFile), *unexpectedText)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts file under [file] exists and contains all the lines from [expectedText]
|
||||||
|
*/
|
||||||
|
fun GradleProject.assertFileContains(
|
||||||
|
file: Path,
|
||||||
|
vararg expectedText: String
|
||||||
|
) {
|
||||||
|
assertFileExists(file)
|
||||||
|
val text = file.readText()
|
||||||
|
val textNotInTheFile = expectedText.filterNot { text.contains(it) }
|
||||||
|
assert(textNotInTheFile.isEmpty()) {
|
||||||
|
"""
|
||||||
|
|$file does not contain:
|
||||||
|
|${textNotInTheFile.joinToString(separator = "\n")}
|
||||||
|
|
|
||||||
|
|actual file content:
|
||||||
|
|$text"
|
||||||
|
|
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts file under [file] exists and does not contain any line from [unexpectedText]
|
||||||
|
*/
|
||||||
|
fun GradleProject.assertFileDoesNotContain(
|
||||||
|
file: Path,
|
||||||
|
vararg unexpectedText: String
|
||||||
|
) {
|
||||||
|
assertFileExists(file)
|
||||||
|
val text = file.readText()
|
||||||
|
val textInTheFile = unexpectedText.filter { text.contains(it) }
|
||||||
|
assert(textInTheFile.isEmpty()) {
|
||||||
|
"""
|
||||||
|
|$file contains lines which it should not contain:
|
||||||
|
|${textInTheFile.joinToString(separator = "\n")}
|
||||||
|
|
|
||||||
|
|actual file content:
|
||||||
|
|$text"
|
||||||
|
|
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun GradleProject.assertSameFiles(expected: Iterable<Path>, actual: Iterable<Path>, messagePrefix: String) {
|
||||||
|
val expectedSet = expected.map { it.toString().normalizePath() }.toSortedSet().joinToString("\n")
|
||||||
|
val actualSet = actual.map { it.toString().normalizePath() }.toSortedSet().joinToString("\n")
|
||||||
|
assertEquals(expectedSet, actualSet, messagePrefix)
|
||||||
|
}
|
||||||
+19
-3
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.gradle.testbase
|
|||||||
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.extension
|
||||||
|
import kotlin.io.path.relativeTo
|
||||||
import kotlin.streams.asSequence
|
import kotlin.streams.asSequence
|
||||||
|
import kotlin.streams.toList
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the file with given [name] in current [Path].
|
* Find the file with given [name] in current [Path].
|
||||||
@@ -15,9 +18,7 @@ import kotlin.streams.asSequence
|
|||||||
* @return `null` if file is absent in current [Path]
|
* @return `null` if file is absent in current [Path]
|
||||||
*/
|
*/
|
||||||
internal fun Path.findInPath(name: String): Path? = Files
|
internal fun Path.findInPath(name: String): Path? = Files
|
||||||
.walk(this)
|
.walk(this).use { stream -> stream.asSequence().find { it.fileName.toString() == name } }
|
||||||
.asSequence()
|
|
||||||
.find { it.fileName.toString() == name }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a temporary directory that will be cleaned up on normal JVM termination, but will be left on non-zero exit status.
|
* Create a temporary directory that will be cleaned up on normal JVM termination, but will be left on non-zero exit status.
|
||||||
@@ -27,3 +28,18 @@ internal fun Path.findInPath(name: String): Path? = Files
|
|||||||
internal fun createTempDir(prefix: String): Path = Files
|
internal fun createTempDir(prefix: String): Path = Files
|
||||||
.createTempDirectory(prefix)
|
.createTempDirectory(prefix)
|
||||||
.apply { toFile().deleteOnExit() }
|
.apply { toFile().deleteOnExit() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns list of all files whose name ends with [ext] extension. The comparison is case-insensitive.
|
||||||
|
*/
|
||||||
|
internal fun Path.allFilesWithExtension(ext: String): List<Path> =
|
||||||
|
Files.walk(this).use { stream -> stream.filter { it.extension.equals(ext, ignoreCase = true) }.toList() }
|
||||||
|
|
||||||
|
internal val Path.allKotlinFiles
|
||||||
|
get() = allFilesWithExtension("kt")
|
||||||
|
|
||||||
|
internal fun Iterable<Path>.relativizeTo(basePath: Path): Iterable<Path> = map {
|
||||||
|
it.relativeTo(basePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun String.normalizePath() = replace("\\", "/")
|
||||||
+15
-10
@@ -28,16 +28,21 @@ internal val DEFAULT_GROOVY_SETTINGS_FILE =
|
|||||||
|
|
||||||
resolutionStrategy {
|
resolutionStrategy {
|
||||||
eachPlugin {
|
eachPlugin {
|
||||||
if (requested.id.id == "com.android.application" ||
|
switch (requested.id.id) {
|
||||||
requested.id.id == "com.android.library" ||
|
case "com.android.application":
|
||||||
requested.id.id == "com.android.test" ||
|
case "com.android.library":
|
||||||
requested.id.id == "com.android.dynamic-feature" ||
|
case "com.android.test":
|
||||||
requested.id.id == "com.android.asset-pack" ||
|
case "com.android.dynamic-feature":
|
||||||
requested.id.id == "com.android.asset-pack-bundle" ||
|
case "com.android.asset-pack":
|
||||||
requested.id.id == "com.android.lint" ||
|
case "com.android.asset-pack-bundle":
|
||||||
requested.id.id == "com.android.instantapp" ||
|
case "com.android.lint":
|
||||||
requested.id.id == "com.android.feature") {
|
case "com.android.instantapp":
|
||||||
useModule("com.android.tools.build:gradle:${'$'}android_tools_version")
|
case "com.android.feature":
|
||||||
|
useModule("com.android.tools.build:gradle:${'$'}android_tools_version")
|
||||||
|
break
|
||||||
|
case "kotlin-dce-js":
|
||||||
|
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${'$'}kotlin_version")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+78
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.testbase
|
||||||
|
|
||||||
|
import org.jdom.Element
|
||||||
|
import org.jdom.input.SAXBuilder
|
||||||
|
import org.jdom.output.Format
|
||||||
|
import org.jdom.output.XMLOutputter
|
||||||
|
import org.jetbrains.kotlin.test.util.trimTrailingWhitespaces
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import kotlin.streams.asSequence
|
||||||
|
import kotlin.streams.toList
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
fun GradleProject.assertTestResults(expectedTestReport: Path, vararg testReportNames: String) {
|
||||||
|
val testReportDirs = testReportNames.map { projectPath.resolve("build/test-results/$it") }
|
||||||
|
|
||||||
|
assertDirectoriesExist(*testReportDirs.toTypedArray())
|
||||||
|
|
||||||
|
val actualTestResults = readAndCleanupTestResults(testReportDirs, projectPath)
|
||||||
|
val expectedTestResults = prettyPrintXml(expectedTestReport.readText())
|
||||||
|
|
||||||
|
assertEquals(expectedTestResults, actualTestResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun readAndCleanupTestResults(testReportDirs: List<Path>, projectPath: Path): String {
|
||||||
|
val files = testReportDirs
|
||||||
|
.flatMap {
|
||||||
|
it.allFilesWithExtension("xml")
|
||||||
|
}
|
||||||
|
.sortedBy {
|
||||||
|
// let containing test suite be first
|
||||||
|
it.name.replace(".xml", ".A.xml")
|
||||||
|
}
|
||||||
|
|
||||||
|
val xmlString = buildString {
|
||||||
|
appendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
|
||||||
|
appendLine("<results>")
|
||||||
|
files.forEach { file ->
|
||||||
|
appendLine(
|
||||||
|
file.readText()
|
||||||
|
.trimTrailingWhitespaces()
|
||||||
|
.replace(projectPath.absolutePathString(), "/\$PROJECT_DIR$")
|
||||||
|
.replace(projectPath.name, "\$PROJECT_NAME$")
|
||||||
|
.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
appendLine("</results>")
|
||||||
|
}
|
||||||
|
|
||||||
|
val doc = SAXBuilder().build(xmlString.reader())
|
||||||
|
val skipAttrs = setOf("timestamp", "hostname", "time", "message")
|
||||||
|
val skipContentsOf = setOf("failure")
|
||||||
|
|
||||||
|
fun cleanup(e: Element) {
|
||||||
|
if (e.name in skipContentsOf) e.text = "..."
|
||||||
|
e.attributes.forEach {
|
||||||
|
if (it.name in skipAttrs) {
|
||||||
|
it.value = "..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e.children.forEach {
|
||||||
|
cleanup(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup(doc.rootElement)
|
||||||
|
return XMLOutputter(Format.getPrettyFormat()).outputString(doc)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun prettyPrintXml(uglyXml: String): String =
|
||||||
|
XMLOutputter(Format.getPrettyFormat()).outputString(SAXBuilder().build(uglyXml.reader()))
|
||||||
+2
-2
@@ -321,7 +321,7 @@ private fun BuildResult.printBuildScanUrl() {
|
|||||||
private fun TestProject.setupNonDefaultJdk(pathToJdk: File) {
|
private fun TestProject.setupNonDefaultJdk(pathToJdk: File) {
|
||||||
gradleProperties.modify {
|
gradleProperties.modify {
|
||||||
"""
|
"""
|
||||||
|org.gradle.java.home=${pathToJdk.absolutePath.replace('\\', '/')}
|
|org.gradle.java.home=${pathToJdk.absolutePath.normalizePath()}
|
||||||
|
|
|
|
||||||
|$it
|
|$it
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
@@ -335,7 +335,7 @@ internal fun Path.enableAndroidSdk() {
|
|||||||
.also { if (!it.exists()) it.createFile() }
|
.also { if (!it.exists()) it.createFile() }
|
||||||
.appendText(
|
.appendText(
|
||||||
"""
|
"""
|
||||||
sdk.dir=${androidSdk.absolutePath.replace('\\', '/')}
|
sdk.dir=${androidSdk.absolutePath.normalizePath()}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
acceptAndroidSdkLicenses(androidSdk)
|
acceptAndroidSdkLicenses(androidSdk)
|
||||||
|
|||||||
+2
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.util
|
|||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.relativeTo
|
||||||
|
|
||||||
fun File.getFileByName(name: String): File =
|
fun File.getFileByName(name: String): File =
|
||||||
findFileByName(name) ?: throw AssertionError("Could not find file with name '$name' in $this")
|
findFileByName(name) ?: throw AssertionError("Could not find file with name '$name' in $this")
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import java.time.*
|
|||||||
import java.util.concurrent.*
|
import java.util.concurrent.*
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "org.jetbrains.kotlin.js" version "<pluginMarkerVersion>"
|
id "org.jetbrains.kotlin.js"
|
||||||
}
|
}
|
||||||
|
|
||||||
String nodeJsVersion
|
String nodeJsVersion
|
||||||
|
|||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
maven { url '<mavenLocalUrl>' }
|
|
||||||
gradlePluginPortal()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = 'cleanTask'
|
|
||||||
+2
-2
@@ -1,5 +1,3 @@
|
|||||||
rootProject.name = "lib2"
|
|
||||||
|
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
@@ -9,3 +7,5 @@ pluginManagement {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rootProject.name = "lib2"
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("js") version "<pluginMarkerVersion>"
|
kotlin("js")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.example"
|
group = "com.example"
|
||||||
|
|||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "js-dynamic-webpack-config-d"
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("js").version("<pluginMarkerVersion>")
|
kotlin("js")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.example"
|
group = "com.example"
|
||||||
|
|||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "kotlin-js-both-mode-with-tests"
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("js") version "<pluginMarkerVersion>"
|
kotlin("js")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "org.example"
|
group = "org.example"
|
||||||
|
|||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "kotlin-js-dependency-with-js-files"
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("org.jetbrains.kotlin.js") version "<pluginMarkerVersion>"
|
id("org.jetbrains.kotlin.js")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "kotlin-js-nodejs"
|
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
resolutionStrategy {
|
resolutionStrategy {
|
||||||
eachPlugin{
|
eachPlugin{
|
||||||
when (requested.id.id) {
|
if (requested.id.id == "kotlin-dce-js") {
|
||||||
"kotlin-dce-js" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:<pluginMarkerVersion>")
|
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:<pluginMarkerVersion>")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("js") version "<pluginMarkerVersion>"
|
kotlin("js")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "kotlin-js-test-webpack-config"
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("js").version("<pluginMarkerVersion>")
|
kotlin("js")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.example"
|
group = "com.example"
|
||||||
|
|||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
rootProject.name = "kotlin-js-yarn-resolutions"
|
||||||
|
|
||||||
|
include("base")
|
||||||
|
include("lib")
|
||||||
-11
@@ -1,11 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "kotlin-js-yarn-resolutions"
|
|
||||||
|
|
||||||
include("base")
|
|
||||||
include("lib")
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("js") version "<pluginMarkerVersion>"
|
kotlin("js")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.example"
|
group = "com.example"
|
||||||
|
|||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "npm-dependencies"
|
|
||||||
+1
-1
@@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnSetupTask
|
|||||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn
|
import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("js") version "<pluginMarkerVersion>"
|
kotlin("js")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.example"
|
group = "com.example"
|
||||||
|
|||||||
-8
@@ -1,8 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "yarn-setup"
|
|
||||||
Reference in New Issue
Block a user