Migrate UpToDateIT to new test dsl

^KT-45745 In Progress
This commit is contained in:
Yahor Berdnikau
2022-03-04 18:42:37 +01:00
parent 745b591b2e
commit 10f43b9fd7
@@ -1,60 +1,77 @@
package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Assert
import org.junit.Assume
import org.junit.Test
import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
import java.io.File
import java.nio.file.Path
import kotlin.io.path.appendText
import kotlin.io.path.deleteExisting
import kotlin.io.path.exists
import kotlin.test.assertTrue
class UpToDateIT : BaseGradleIT() {
@Test
fun testLanguageVersionChange() {
@DisplayName("Kotlin options change")
@JvmGradlePluginTests
class UpToDateIT : KGPBaseTest() {
@DisplayName("Language version change")
@GradleTest
fun testLanguageVersionChange(gradleVersion: GradleVersion) {
testMutations(
*propertyMutationChain(
gradleVersion,
propertyMutationChain(
"compileKotlin.kotlinOptions.languageVersion",
"null", "'1.5'", "'1.4'", "null"
"null", "'1.6'", "'1.5'", "'1.4'", "null"
)
)
}
@Test
fun testApiVersionChange() {
@DisplayName("Api version change")
@GradleTest
fun testApiVersionChange(gradleVersion: GradleVersion) {
testMutations(
*propertyMutationChain(
gradleVersion,
propertyMutationChain(
"compileKotlin.kotlinOptions.apiVersion",
"null", "'1.5'", "'1.4'", "null"
"null", "'1.6'", "'1.5'", "'1.4'", "null"
)
)
}
@Test
fun testOther() {
@DisplayName("Misc changes")
@GradleTest
fun testOther(gradleVersion: GradleVersion) {
testMutations(
emptyMutation,
OptionMutation("compileKotlin.kotlinOptions.jvmTarget", "'1.6'", "'1.8'"),
OptionMutation("compileKotlin.kotlinOptions.freeCompilerArgs", "[]", "['-Xallow-kotlin-package']"),
OptionMutation("kotlin.experimental.coroutines", "'error'", "'enable'"),
OptionMutation("archivesBaseName", "'someName'", "'otherName'"),
subpluginOptionMutation,
externalOutputMutation,
compilerClasspathMutation
gradleVersion,
setOf(
emptyMutation,
OptionMutation("compileKotlin.kotlinOptions.jvmTarget", "'1.8'", "'11'"),
OptionMutation("compileKotlin.kotlinOptions.freeCompilerArgs", "[]", "['-Xallow-kotlin-package']"),
OptionMutation("archivesBaseName", "'someName'", "'otherName'"),
subpluginOptionMutation,
externalOutputMutation,
compilerClasspathMutation
)
)
}
private fun testMutations(vararg mutations: ProjectMutation) {
val project = Project("kotlinProject")
project.setupWorkingDir()
mutations.forEach {
it.initProject(project)
project.build("classes") { assertSuccessful() }
private fun testMutations(
gradleVersion: GradleVersion,
mutations: Set<ProjectMutation>
) {
project("kotlinProject", gradleVersion) {
mutations.forEach { mutation ->
mutation.initProject(this)
build("classes")
it.mutateProject(project)
project.build("classes") {
try {
assertSuccessful()
it.checkAfterRebuild(this)
} catch (e: Throwable) {
throw RuntimeException("Mutation '${it.name}' has failed", e)
mutation.mutateProject(this)
build("classes") {
try {
mutation.checkAfterRebuild(this)
} catch (e: Throwable) {
throw RuntimeException("Mutation '${mutation.name}' has failed", e)
}
}
}
}
@@ -63,48 +80,59 @@ class UpToDateIT : BaseGradleIT() {
private val emptyMutation = object : ProjectMutation {
override val name = "emptyMutation"
override fun initProject(project: Project) = Unit
override fun mutateProject(project: Project) = Unit
override fun initProject(project: TestProject) = Unit
override fun mutateProject(project: TestProject) = Unit
override fun checkAfterRebuild(compiledProject: CompiledProject) = with(compiledProject) {
assertTasksUpToDate(listOf(":compileKotlin"))
override fun checkAfterRebuild(buildResult: BuildResult) = with(buildResult) {
assertTasksUpToDate(":compileKotlin")
}
}
private val compilerClasspathMutation = object : ProjectMutation {
override val name = "compilerClasspathMutation"
private val compilerClasspathRegex = "compiler_cp=\\[(.*)]".toRegex()
lateinit var originalCompilerCp: List<String>
val originalPaths get() = originalCompilerCp.map { it.replace("\\", "/") }.joinToString(", ") { "'$it'" }
override fun initProject(project: Project) = with(project) {
override fun initProject(project: TestProject) = with(project) {
buildGradle.appendText(
"\nafterEvaluate { println 'compiler_cp=' + compileKotlin.getDefaultCompilerClasspath\$kotlin_gradle_plugin().toList() }"
)
build("clean") { originalCompilerCp = "compiler_cp=\\[(.*)]".toRegex().find(output)!!.groupValues[1].split(", ") }
buildGradle.appendText("""${'\n'}
build("clean") {
originalCompilerCp = compilerClasspathRegex.find(output)!!.groupValues[1].split(", ")
}
buildGradle.appendText(
"""
// Add Kapt to the project to test its input checks as well:
apply plugin: 'kotlin-kapt'
compileKotlin.getDefaultCompilerClasspath${'$'}kotlin_gradle_plugin().setFrom(files($originalPaths).toList())
afterEvaluate {
kaptGenerateStubsKotlin.getDefaultCompilerClasspath${'$'}kotlin_gradle_plugin().setFrom(files($originalPaths).toList())
}
""".trimIndent())
""".trimIndent()
)
}
override fun mutateProject(project: Project) = with(project) {
override fun mutateProject(project: TestProject) = with(project) {
buildGradle.modify {
val modifiedClasspath = originalCompilerCp.map {
val file = File(it)
val newFile = File(projectDir, file.nameWithoutExtension + "-1.jar")
val newFile = projectPath.resolve(file.nameWithoutExtension + "-1.jar").toFile()
file.copyTo(newFile)
newFile.absolutePath
}.reversed()
it.replace(originalPaths, modifiedClasspath.joinToString(", ") { "'${it.replace("\\", "/")}'" })
it.replace(
originalPaths,
modifiedClasspath.joinToString(", ") { "'${it.replace("\\", "/")}'" }
)
}
}
override fun checkAfterRebuild(compiledProject: CompiledProject) = with(compiledProject) {
override fun checkAfterRebuild(buildResult: BuildResult) = with(buildResult) {
assertTasksExecuted(":compileKotlin", ":kaptGenerateStubsKotlin", ":kaptKotlin")
}
}
@@ -112,20 +140,21 @@ class UpToDateIT : BaseGradleIT() {
private val subpluginOptionMutation = object : ProjectMutation {
override val name: String get() = "subpluginOptionMutation"
override fun initProject(project: Project) = with(project) {
override fun initProject(project: TestProject) = with(project) {
buildGradle.appendText(
"\n" + """
"""
plugins.apply("org.jetbrains.kotlin.plugin.allopen")
allOpen { annotation("allopen.Foo"); annotation("allopen.Bar") }
""".trimIndent()
""".trimIndent()
)
}
override fun mutateProject(project: Project) = with(project) {
override fun mutateProject(project: TestProject) = with(project) {
buildGradle.modify { it.replace("allopen.Foo", "allopen.Baz") }
}
override fun checkAfterRebuild(compiledProject: CompiledProject) = with(compiledProject) {
override fun checkAfterRebuild(buildResult: BuildResult) = with(buildResult) {
assertTasksExecuted(":compileKotlin")
}
}
@@ -133,40 +162,46 @@ class UpToDateIT : BaseGradleIT() {
private val externalOutputMutation = object : ProjectMutation {
override val name = "externalOutputMutation"
override fun initProject(project: Project) = Unit
override fun initProject(project: TestProject) = Unit
lateinit var helloWorldKtClass: File
lateinit var helloWorldKtClass: Path
override fun mutateProject(project: Project) = with(project) {
val kotlinOutputPath = project.classesDir()
override fun mutateProject(project: TestProject) = with(project) {
val kotlinOutputPath = kotlinClassesDir()
helloWorldKtClass = File(projectDir, kotlinOutputPath + "demo/KotlinGreetingJoiner.class")
Assume.assumeTrue(helloWorldKtClass.exists())
helloWorldKtClass.delete(); Unit
helloWorldKtClass = kotlinOutputPath.resolve("demo/KotlinGreetingJoiner.class")
assertTrue(helloWorldKtClass.exists())
helloWorldKtClass.deleteExisting()
}
override fun checkAfterRebuild(compiledProject: CompiledProject) = with(compiledProject) {
override fun checkAfterRebuild(buildResult: BuildResult) = with(buildResult) {
assertTasksExecuted(":compileKotlin")
Assert.assertTrue(helloWorldKtClass.exists())
assertTrue(helloWorldKtClass.exists())
}
}
private val BaseGradleIT.Project.buildGradle get() = File(projectDir, "build.gradle")
private interface ProjectMutation {
fun initProject(project: Project)
fun mutateProject(project: Project)
fun checkAfterRebuild(compiledProject: CompiledProject)
fun initProject(project: TestProject)
fun mutateProject(project: TestProject)
fun checkAfterRebuild(buildResult: BuildResult)
val name: String
}
private fun propertyMutationChain(path: String, vararg values: String): Array<ProjectMutation> =
arrayListOf<ProjectMutation>().apply {
for (i in 1..values.lastIndex) {
add(OptionMutation(path, values[i - 1], values[i], shouldInit = i == 1))
}
}.toTypedArray()
private fun propertyMutationChain(
path: String,
vararg values: String
): Set<OptionMutation> = values
.drop(1)
.mapIndexed { index, value ->
val actualIndex = index + 1
OptionMutation(
path,
values[actualIndex - 1],
value,
index == 0
)
}
.toSet()
private inner class OptionMutation(
private val path: String,
@@ -176,17 +211,17 @@ class UpToDateIT : BaseGradleIT() {
) : ProjectMutation {
override val name = "OptionMutation(path='$path', oldValue='$oldValue', newValue='$newValue')"
override fun initProject(project: Project) = with(project) {
override fun initProject(project: TestProject) = with(project) {
if (shouldInit) {
buildGradle.appendText("\n$path = $oldValue")
}
}
override fun mutateProject(project: Project) = with(project) {
override fun mutateProject(project: TestProject) = with(project) {
buildGradle.modify { it.replace("$path = $oldValue", "$path = $newValue") }
}
override fun checkAfterRebuild(compiledProject: CompiledProject) = with(compiledProject) {
override fun checkAfterRebuild(buildResult: BuildResult) = with(buildResult) {
assertTasksExecuted(":compileKotlin")
}
}