From 10f43b9fd711949ce1088244ecf07189f7e4c46c Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Fri, 4 Mar 2022 18:42:37 +0100 Subject: [PATCH] Migrate UpToDateIT to new test dsl ^KT-45745 In Progress --- .../org/jetbrains/kotlin/gradle/UpToDateIT.kt | 189 +++++++++++------- 1 file changed, 112 insertions(+), 77 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/UpToDateIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/UpToDateIT.kt index 810d7b6e92a..b27969cd361 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/UpToDateIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/UpToDateIT.kt @@ -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 + ) { + 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 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 = - arrayListOf().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 = 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") } }