Migrate KaptIncrementalIT to new test DSL
^KT-45745 In Progress
This commit is contained in:
committed by
TeamCityServer
parent
a0cb7c8173
commit
9ca2ce6647
+307
-266
@@ -1,338 +1,379 @@
|
|||||||
package org.jetbrains.kotlin.gradle
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
import org.gradle.api.logging.configuration.WarningMode
|
import org.gradle.api.logging.configuration.WarningMode
|
||||||
import org.jetbrains.kotlin.gradle.util.*
|
import org.gradle.testkit.runner.BuildResult
|
||||||
import org.junit.Test
|
import org.gradle.util.GradleVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
|
import kotlin.io.path.writeText
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
open class KaptIncrementalIT : BaseGradleIT() {
|
@DisplayName("Kapt incremental compilation")
|
||||||
|
@OtherGradlePluginTests
|
||||||
|
open class KaptIncrementalIT : KGPBaseTest() {
|
||||||
companion object {
|
companion object {
|
||||||
private val EXAMPLE_ANNOTATION_REGEX = "@(field:)?example.ExampleAnnotation".toRegex()
|
private val EXAMPLE_ANNOTATION_REGEX = "@(field:)?example.ExampleAnnotation".toRegex()
|
||||||
|
const val PROJECT_NAME = "kaptIncrementalCompilationProject"
|
||||||
|
const val KAPT3_STUBS_PATH = "build/tmp/kapt3/stubs/main"
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getProject() =
|
|
||||||
Project(
|
|
||||||
"kaptIncrementalCompilationProject",
|
|
||||||
GradleVersionRequired.None
|
|
||||||
).apply { setupWorkingDir() }
|
|
||||||
|
|
||||||
private val annotatedElements =
|
private val annotatedElements =
|
||||||
arrayOf("A", "funA", "valA", "funUtil", "valUtil", "B", "funB", "valB", "useB")
|
arrayOf("A", "funA", "valA", "funUtil", "valUtil", "B", "funB", "valB", "useB")
|
||||||
|
|
||||||
override fun defaultBuildOptions(): BuildOptions {
|
override val defaultBuildOptions = super.defaultBuildOptions.copy(
|
||||||
return super.defaultBuildOptions().copy(incremental = true, warningMode = WarningMode.Fail)
|
incremental = true,
|
||||||
}
|
warningMode = WarningMode.Fail,
|
||||||
|
kaptOptions = BuildOptions.KaptOptions(incrementalKapt = true)
|
||||||
|
)
|
||||||
|
|
||||||
@Test
|
@DisplayName("After adding new line compilation is incremental")
|
||||||
fun testAddNewLine() {
|
@GradleTest
|
||||||
val project = getProject()
|
fun testAddNewLine(gradleVersion: GradleVersion) {
|
||||||
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
|
build("clean", "build")
|
||||||
|
|
||||||
project.build("clean", "build") {
|
javaSourcesDir().resolve("bar/useB.kt").modify { "\n$it" }
|
||||||
assertSuccessful()
|
build("build") {
|
||||||
}
|
assertTasksExecuted(":kaptGenerateStubsKotlin", ":compileKotlin")
|
||||||
|
assertTasksUpToDate(":kaptKotlin")
|
||||||
project.projectFile("useB.kt").modify { "\n$it" }
|
assertTasksUpToDate(":compileJava")
|
||||||
project.build("build") {
|
}
|
||||||
assertSuccessful()
|
|
||||||
assertTasksExecuted(":kaptGenerateStubsKotlin", ":compileKotlin")
|
|
||||||
assertTasksUpToDate(":kaptKotlin")
|
|
||||||
assertTasksUpToDate(":compileJava")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@DisplayName("On rebuild without changes tasks should be UP-TO-DATE")
|
||||||
fun testBasic() {
|
@GradleTest
|
||||||
val project = getProject()
|
fun testBasic(gradleVersion: GradleVersion) {
|
||||||
|
project(
|
||||||
|
PROJECT_NAME,
|
||||||
|
gradleVersion,
|
||||||
|
buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)
|
||||||
|
) {
|
||||||
|
build("build") {
|
||||||
|
checkGenerated(kaptGeneratedToPath, *annotatedElements)
|
||||||
|
checkNotGenerated(kaptGeneratedToPath, "notAnnotatedFun")
|
||||||
|
assertOutputContains("foo.ATest PASSED")
|
||||||
|
}
|
||||||
|
|
||||||
project.build("build") {
|
build("build") {
|
||||||
assertSuccessful()
|
assertTasksUpToDate(
|
||||||
checkGenerated(*annotatedElements)
|
":compileKotlin",
|
||||||
checkNotGenerated("notAnnotatedFun")
|
":compileJava"
|
||||||
assertContains("foo.ATest PASSED")
|
)
|
||||||
}
|
|
||||||
|
|
||||||
project.build("build") {
|
assertTasksUpToDate(
|
||||||
assertSuccessful()
|
":kaptKotlin",
|
||||||
assertTasksUpToDate(
|
":kaptGenerateStubsKotlin"
|
||||||
":compileKotlin",
|
)
|
||||||
":compileJava"
|
}
|
||||||
)
|
|
||||||
|
|
||||||
assertTasksUpToDate(
|
|
||||||
":kaptKotlin",
|
|
||||||
":kaptGenerateStubsKotlin"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@DisplayName("Successfully rebuild after error")
|
||||||
fun testCompileError() {
|
@GradleTest
|
||||||
val project = getProject()
|
fun testCompileError(gradleVersion: GradleVersion) {
|
||||||
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
|
build("assemble")
|
||||||
|
|
||||||
project.build("build") {
|
val bKt = javaSourcesDir().resolve("bar/B.kt")
|
||||||
assertSuccessful()
|
val errorKt = bKt.resolveSibling("error.kt")
|
||||||
}
|
errorKt.writeText("<COMPILE_ERROR_MARKER>")
|
||||||
|
|
||||||
val bKt = project.projectDir.getFileByName("B.kt")
|
buildAndFail("assemble") {
|
||||||
val errorKt = bKt.resolveSibling("error.kt")
|
assertTasksFailed(":kaptGenerateStubsKotlin")
|
||||||
errorKt.writeText("<COMPILE_ERROR_MARKER>")
|
}
|
||||||
|
|
||||||
project.build("build") {
|
errorKt.deleteIfExists()
|
||||||
assertFailed()
|
bKt.modify { "$it\n" }
|
||||||
assertTasksFailed(":kaptGenerateStubsKotlin")
|
build("assemble", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
}
|
assertCompiledKotlinSources(listOf(projectPath.relativize(bKt)), output)
|
||||||
|
assertTasksExecuted(":kaptGenerateStubsKotlin", ":compileKotlin")
|
||||||
errorKt.delete()
|
}
|
||||||
bKt.modify { "$it\n" }
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertCompiledKotlinSources(project.relativize(bKt))
|
|
||||||
assertTasksExecuted(":kaptGenerateStubsKotlin", ":compileKotlin")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@DisplayName("Change in the function body without changing the signature")
|
||||||
fun testChangeFunctionBodyWithoutChangingSignature() {
|
@GradleTest
|
||||||
val project = getProject()
|
fun testChangeFunctionBodyWithoutChangingSignature(gradleVersion: GradleVersion) {
|
||||||
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
|
build("build", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
|
checkGenerated(kaptGeneratedToPath, *annotatedElements)
|
||||||
|
checkNotGenerated(kaptGeneratedToPath, "notAnnotatedFun")
|
||||||
|
assertOutputContains("foo.ATest PASSED")
|
||||||
|
}
|
||||||
|
|
||||||
project.build("build") {
|
val utilKt = javaSourcesDir().resolve("baz/util.kt")
|
||||||
assertSuccessful()
|
utilKt.modify { oldContent ->
|
||||||
checkGenerated(*annotatedElements)
|
assert(oldContent.contains("2 * 2 == 4"))
|
||||||
checkNotGenerated("notAnnotatedFun")
|
oldContent.replace("2 * 2 == 4", "2 * 2 == 5")
|
||||||
assertContains("foo.ATest PASSED")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val utilKt = project.projectDir.getFileByName("util.kt")
|
build("assemble") {
|
||||||
utilKt.modify { oldContent ->
|
assertTasksExecuted(":kaptGenerateStubsKotlin")
|
||||||
assert(oldContent.contains("2 * 2 == 4"))
|
assertTasksUpToDate(":kaptKotlin")
|
||||||
oldContent.replace("2 * 2 == 4", "2 * 2 == 5")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertTasksExecuted(":kaptGenerateStubsKotlin")
|
|
||||||
assertTasksUpToDate(":kaptKotlin")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@DisplayName("Adding new annotated element")
|
||||||
fun testAddAnnotatedElement() {
|
@GradleTest
|
||||||
val project = getProject()
|
fun testAddAnnotatedElement(gradleVersion: GradleVersion) {
|
||||||
project.build("build") {
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
assertSuccessful()
|
build("assemble")
|
||||||
}
|
|
||||||
|
|
||||||
val utilKt = project.projectDir.getFileByName("util.kt")
|
val utilKt = javaSourcesDir().resolve("baz/util.kt")
|
||||||
utilKt.modify { oldContent ->
|
utilKt.modify { oldContent ->
|
||||||
"""$oldContent
|
|
||||||
|
|
||||||
@example.ExampleAnnotation
|
|
||||||
fun newUtilFun() {}"""
|
|
||||||
}
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertKapt3FullyExecuted()
|
|
||||||
|
|
||||||
// todo: for kapt with stubs check compileKotlin and compileKotlinAfterJava separately
|
|
||||||
assertCompiledKotlinSourcesHandleKapt3(project.relativize(utilKt))
|
|
||||||
checkGenerated(*(annotatedElements + arrayOf("newUtilFun")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testAddAnnotation() {
|
|
||||||
val project = getProject()
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
}
|
|
||||||
|
|
||||||
val utilKt = project.projectDir.getFileByName("util.kt")
|
|
||||||
utilKt.modify { it.replace("fun notAnnotatedFun", "@example.ExampleAnnotation fun notAnnotatedFun") }
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertKapt3FullyExecuted()
|
|
||||||
assertCompiledKotlinSources(project.relativize(utilKt))
|
|
||||||
checkGenerated(*(annotatedElements + arrayOf("notAnnotatedFun")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testRemoveSourceFile() {
|
|
||||||
val project = getProject()
|
|
||||||
val kapt3IncDataPath = "build/tmp/kapt3/incrementalData/main"
|
|
||||||
val kapt3StubsPath = "build/tmp/kapt3/stubs/main"
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertKapt3FullyExecuted()
|
|
||||||
|
|
||||||
assertFileExists("$kapt3IncDataPath/bar/B.class")
|
|
||||||
assertFileExists("$kapt3IncDataPath/bar/UseBKt.class")
|
|
||||||
assertFileExists("$kapt3StubsPath/bar/B.java")
|
|
||||||
assertFileExists("$kapt3StubsPath/bar/B.kapt_metadata")
|
|
||||||
assertFileExists("$kapt3StubsPath/bar/UseBKt.java")
|
|
||||||
assertFileExists("$kapt3StubsPath/bar/UseBKt.kapt_metadata")
|
|
||||||
}
|
|
||||||
|
|
||||||
with(project.projectDir) {
|
|
||||||
getFileByName("B.kt").delete()
|
|
||||||
getFileByName("useB.kt").delete()
|
|
||||||
}
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertFailed()
|
|
||||||
|
|
||||||
assertNoSuchFile("$kapt3IncDataPath/bar/B.class")
|
|
||||||
assertNoSuchFile("$kapt3IncDataPath/bar/UseBKt.class")
|
|
||||||
assertNoSuchFile("$kapt3StubsPath/bar/B.java")
|
|
||||||
assertNoSuchFile("$kapt3StubsPath/bar/B.kaptMetadata")
|
|
||||||
assertNoSuchFile("$kapt3StubsPath/bar/UseBKt.java")
|
|
||||||
assertNoSuchFile("$kapt3StubsPath/bar/UseBKt.kaptMetadata")
|
|
||||||
}
|
|
||||||
|
|
||||||
project.projectDir.getFileByName("JavaClass.java").delete()
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertKapt3FullyExecuted()
|
|
||||||
assertCompiledKotlinSourcesHandleKapt3(project.relativize(project.projectDir.allKotlinFiles()))
|
|
||||||
val affectedElements = arrayOf("B", "funB", "valB", "useB")
|
|
||||||
checkGenerated(*(annotatedElements.toSet() - affectedElements).toTypedArray())
|
|
||||||
checkNotGenerated(*affectedElements)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testRemoveAllKotlinSources() {
|
|
||||||
val project = getProject()
|
|
||||||
val kapt3StubsPath = "build/tmp/kapt3/stubs/main"
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertFileExists("$kapt3StubsPath/bar/UseBKt.java")
|
|
||||||
}
|
|
||||||
|
|
||||||
with(project.projectDir) {
|
|
||||||
resolve("src/").deleteRecursively()
|
|
||||||
resolve("src/main/java/bar").mkdirs()
|
|
||||||
resolve("src/main/java/bar/MyClass.java").writeText(
|
|
||||||
"""
|
"""
|
||||||
package bar;
|
$oldContent
|
||||||
public class MyClass {}
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
project.build("build") {
|
@example.ExampleAnnotation
|
||||||
assertSuccessful()
|
fun newUtilFun() {}
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure all generated stubs are removed (except for NonExistentClass).
|
build("assemble", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
assertEquals(
|
assertKapt3FullyExecuted()
|
||||||
listOf(fileInWorkingDir("$kapt3StubsPath/error/NonExistentClass.java").canonicalPath),
|
|
||||||
fileInWorkingDir(kapt3StubsPath).walk().filter { it.extension == "java" }.map { it.canonicalPath }.toList()
|
assertCompiledKotlinSourcesHandleKapt3(this, listOf(projectPath.relativize(utilKt)))
|
||||||
)
|
checkGenerated(kaptGeneratedToPath, *(annotatedElements + arrayOf("newUtilFun")))
|
||||||
// Make sure all compiled kt files are cleaned up.
|
}
|
||||||
assertEquals(emptyList(), fileInWorkingDir("build/classes/kotlin").walk().filter { it.extension == "class" }.toList())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@DisplayName("Adding new annotation triggers kapt run")
|
||||||
fun testRemoveAnnotations() {
|
@GradleTest
|
||||||
val project = getProject()
|
fun testAddAnnotation(gradleVersion: GradleVersion) {
|
||||||
project.build("build") {
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
assertSuccessful()
|
build("assemble")
|
||||||
}
|
|
||||||
|
|
||||||
val bKt = project.projectDir.getFileByName("B.kt")
|
val utilKt = javaSourcesDir().resolve("baz/util.kt")
|
||||||
bKt.modify { it.replace(EXAMPLE_ANNOTATION_REGEX, "") }
|
utilKt.modify {
|
||||||
val affectedElements = arrayOf("B", "funB", "valB")
|
it.replace("fun notAnnotatedFun", "@example.ExampleAnnotation fun notAnnotatedFun")
|
||||||
|
}
|
||||||
|
|
||||||
project.build("build") {
|
build("assemble", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
assertSuccessful()
|
assertKapt3FullyExecuted()
|
||||||
|
assertCompiledKotlinSources(listOf(projectPath.relativize(utilKt)), output)
|
||||||
assertKapt3FullyExecuted()
|
checkGenerated(kaptGeneratedToPath, *(annotatedElements + arrayOf("notAnnotatedFun")))
|
||||||
|
}
|
||||||
val useBKt = project.projectDir.getFileByName("useB.kt")
|
|
||||||
assertCompiledKotlinSources(project.relativize(bKt, useBKt), tasks = listOf("kaptGenerateStubsKotlin"))
|
|
||||||
|
|
||||||
// java removal is detected
|
|
||||||
assertCompiledKotlinSources(
|
|
||||||
project.relativize(project.projectDir.allKotlinFiles()),
|
|
||||||
tasks = listOf("compileKotlin")
|
|
||||||
)
|
|
||||||
|
|
||||||
checkGenerated(*(annotatedElements.toSet() - affectedElements).toTypedArray())
|
|
||||||
checkNotGenerated(*affectedElements)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@DisplayName("Kapt run is incremental after source file was removed")
|
||||||
fun testChangeAnnotatedPropertyType() {
|
@GradleTest
|
||||||
val project = getProject()
|
fun testRemoveSourceFile(gradleVersion: GradleVersion) {
|
||||||
project.build("build") {
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
assertSuccessful()
|
val kapt3IncDataPath = "build/tmp/kapt3/incrementalData/main"
|
||||||
}
|
val kapt3StubsPath = "build/tmp/kapt3/stubs/main"
|
||||||
|
|
||||||
val bKt = project.projectDir.getFileByName("B.kt")
|
build("assemble") {
|
||||||
val useBKt = project.projectDir.getFileByName("useB.kt")
|
assertKapt3FullyExecuted()
|
||||||
bKt.modify { it.replace("val valB = \"text\"", "val valB = 4") }
|
|
||||||
|
|
||||||
project.build("build") {
|
assertFileInProjectExists("$kapt3IncDataPath/bar/B.class")
|
||||||
assertSuccessful()
|
assertFileInProjectExists("$kapt3IncDataPath/bar/UseBKt.class")
|
||||||
assertKapt3FullyExecuted()
|
assertFileInProjectExists("$kapt3StubsPath/bar/B.java")
|
||||||
assertCompiledKotlinSourcesHandleKapt3(project.relativize(bKt, useBKt))
|
assertFileInProjectExists("$kapt3StubsPath/bar/B.kapt_metadata")
|
||||||
checkGenerated(*annotatedElements)
|
assertFileInProjectExists("$kapt3StubsPath/bar/UseBKt.java")
|
||||||
|
assertFileInProjectExists("$kapt3StubsPath/bar/UseBKt.kapt_metadata")
|
||||||
|
}
|
||||||
|
|
||||||
|
with(javaSourcesDir()) {
|
||||||
|
resolve("bar/B.kt").deleteIfExists()
|
||||||
|
resolve("bar/useB.kt").deleteIfExists()
|
||||||
|
}
|
||||||
|
|
||||||
|
buildAndFail("assemble") {
|
||||||
|
assertFileInProjectNotExists("$kapt3IncDataPath/bar/B.class")
|
||||||
|
assertFileInProjectNotExists("$kapt3IncDataPath/bar/UseBKt.class")
|
||||||
|
assertFileInProjectNotExists("$kapt3StubsPath/bar/B.java")
|
||||||
|
assertFileInProjectNotExists("$kapt3StubsPath/bar/B.kaptMetadata")
|
||||||
|
assertFileInProjectNotExists("$kapt3StubsPath/bar/UseBKt.java")
|
||||||
|
assertFileInProjectNotExists("$kapt3StubsPath/bar/UseBKt.kaptMetadata")
|
||||||
|
}
|
||||||
|
|
||||||
|
javaSourcesDir().resolve("foo/JavaClass.java").deleteIfExists()
|
||||||
|
|
||||||
|
build("assemble", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
|
assertKapt3FullyExecuted()
|
||||||
|
assertCompiledKotlinSourcesHandleKapt3(
|
||||||
|
this,
|
||||||
|
projectPath.allKotlinFiles.map { projectPath.relativize(it) }
|
||||||
|
)
|
||||||
|
val affectedElements = arrayOf("B", "funB", "valB", "useB")
|
||||||
|
checkGenerated(kaptGeneratedToPath, *(annotatedElements.toSet() - affectedElements).toTypedArray())
|
||||||
|
checkNotGenerated(kaptGeneratedToPath, *affectedElements)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@DisplayName("Incremental kapt run is correct after removing all Kotlin sources")
|
||||||
fun testChangeInlineDelegate() {
|
@GradleTest
|
||||||
val project = getProject()
|
fun testRemoveAllKotlinSources(gradleVersion: GradleVersion) {
|
||||||
project.build("build") {
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
assertSuccessful()
|
build("assemble") {
|
||||||
}
|
assertFileInProjectExists("$KAPT3_STUBS_PATH/bar/UseBKt.java")
|
||||||
|
}
|
||||||
|
|
||||||
val file = project.projectDir.getFileByName("Usage.kt")
|
with(projectPath) {
|
||||||
file.modify { "$it//" }
|
resolve("src/").deleteRecursively()
|
||||||
|
resolve("src/main/java/bar").createDirectories()
|
||||||
|
resolve("src/main/java/bar/MyClass.java").writeText(
|
||||||
|
"""
|
||||||
|
package bar;
|
||||||
|
public class MyClass {}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
project.build("build") {
|
build("assemble") {
|
||||||
assertSuccessful()
|
// Make sure all generated stubs are removed (except for NonExistentClass).
|
||||||
assertTasksExecuted(":kaptGenerateStubsKotlin", ":compileKotlin")
|
assertEquals(
|
||||||
|
listOf(projectPath.resolve("$KAPT3_STUBS_PATH/error/NonExistentClass.java").toRealPath().toString()),
|
||||||
|
projectPath
|
||||||
|
.resolve(KAPT3_STUBS_PATH)
|
||||||
|
.toFile()
|
||||||
|
.walk()
|
||||||
|
.filter { it.extension == "java" }
|
||||||
|
.map { it.canonicalPath }
|
||||||
|
.toList()
|
||||||
|
)
|
||||||
|
// Make sure all compiled kt files are cleaned up.
|
||||||
|
assertEquals(
|
||||||
|
emptyList(),
|
||||||
|
projectPath
|
||||||
|
.resolve("build/classes/kotlin")
|
||||||
|
.toFile()
|
||||||
|
.walk()
|
||||||
|
.filter { it.extension == "class" }
|
||||||
|
.toList()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompiledProject.assertCompiledKotlinSourcesHandleKapt3(
|
@DisplayName("On all annotations remove kapt and compile runs incremenatally")
|
||||||
sources: Iterable<String>,
|
@GradleTest
|
||||||
weakTesting: Boolean = false
|
fun testRemoveAnnotations(gradleVersion: GradleVersion) {
|
||||||
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
|
build("assemble")
|
||||||
|
|
||||||
|
val bKt = javaSourcesDir().resolve("bar/B.kt")
|
||||||
|
bKt.modify { it.replace(EXAMPLE_ANNOTATION_REGEX, "") }
|
||||||
|
val affectedElements = arrayOf("B", "funB", "valB")
|
||||||
|
|
||||||
|
build("assemble", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
|
assertKapt3FullyExecuted()
|
||||||
|
|
||||||
|
val useBKt = javaSourcesDir().resolve("bar/useB.kt")
|
||||||
|
assertCompiledKotlinSources(
|
||||||
|
listOf(projectPath.relativize(bKt), projectPath.relativize(useBKt)),
|
||||||
|
getOutputForTask("kaptGenerateStubs"),
|
||||||
|
errorMessageSuffix = " in task 'kaptGenerateStubs'"
|
||||||
|
)
|
||||||
|
|
||||||
|
// java removal is detected
|
||||||
|
assertCompiledKotlinSources(
|
||||||
|
projectPath.allKotlinFiles.map { projectPath.relativize(it) },
|
||||||
|
output
|
||||||
|
)
|
||||||
|
|
||||||
|
checkGenerated(
|
||||||
|
kaptGeneratedToPath,
|
||||||
|
*(annotatedElements.toSet() - affectedElements).toTypedArray()
|
||||||
|
)
|
||||||
|
checkNotGenerated(kaptGeneratedToPath, *affectedElements)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@DisplayName("Changing annotated property type is handled correctly")
|
||||||
|
@GradleTest
|
||||||
|
fun testChangeAnnotatedPropertyType(gradleVersion: GradleVersion) {
|
||||||
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
|
build("assemble")
|
||||||
|
|
||||||
|
val bKt = javaSourcesDir().resolve("bar/B.kt")
|
||||||
|
val useBKt = javaSourcesDir().resolve("bar/useB.kt")
|
||||||
|
bKt.modify { it.replace("val valB = \"text\"", "val valB = 4") }
|
||||||
|
|
||||||
|
build("assemble", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) {
|
||||||
|
assertKapt3FullyExecuted()
|
||||||
|
assertCompiledKotlinSourcesHandleKapt3(
|
||||||
|
this,
|
||||||
|
listOf(bKt, useBKt).map { projectPath.relativize(it) }
|
||||||
|
)
|
||||||
|
checkGenerated(kaptGeneratedToPath, *annotatedElements)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@DisplayName("Change in inline delegate is handled correctly")
|
||||||
|
@GradleTest
|
||||||
|
fun testChangeInlineDelegate(gradleVersion: GradleVersion) {
|
||||||
|
project(PROJECT_NAME, gradleVersion) {
|
||||||
|
build("assemble")
|
||||||
|
|
||||||
|
val file = javaSourcesDir().resolve("delegate/Usage.kt")
|
||||||
|
file.modify { "$it//" }
|
||||||
|
|
||||||
|
build("assemble") {
|
||||||
|
assertTasksExecuted(":kaptGenerateStubsKotlin", ":compileKotlin")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TestProject.assertCompiledKotlinSourcesHandleKapt3(
|
||||||
|
buildResult: BuildResult,
|
||||||
|
sources: List<Path>
|
||||||
) {
|
) {
|
||||||
assertCompiledKotlinSources(
|
assertCompiledKotlinSources(
|
||||||
sources, weakTesting,
|
sources,
|
||||||
tasks = listOf("compileKotlin", "kaptGenerateStubsKotlin")
|
buildResult.getOutputForTask("kaptGenerateStubsKotlin"),
|
||||||
|
errorMessageSuffix = " in task 'kaptGenerateStubsKotlin"
|
||||||
|
)
|
||||||
|
|
||||||
|
assertCompiledKotlinSources(
|
||||||
|
sources,
|
||||||
|
buildResult.getOutputForTask("compileKotlin"),
|
||||||
|
errorMessageSuffix = " in task 'compileKotlin'"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompiledProject.assertKapt3FullyExecuted() {
|
private fun BuildResult.assertKapt3FullyExecuted() {
|
||||||
assertTasksExecuted(":kaptKotlin", ":kaptGenerateStubsKotlin")
|
assertTasksExecuted(":kaptKotlin", ":kaptGenerateStubsKotlin")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompiledProject.checkGenerated(vararg annotatedElementNames: String) {
|
private fun TestProject.checkGenerated(
|
||||||
|
generateToPath: Path,
|
||||||
|
vararg annotatedElementNames: String
|
||||||
|
) {
|
||||||
getGeneratedFileNames(*annotatedElementNames).forEach {
|
getGeneratedFileNames(*annotatedElementNames).forEach {
|
||||||
val file = project.projectDir.getFileByName(it)
|
assertFileExistsInTree(generateToPath, it)
|
||||||
assert(file.isFile) { "$file must exist" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompiledProject.checkNotGenerated(vararg annotatedElementNames: String) {
|
private fun TestProject.checkNotGenerated(
|
||||||
|
generateToPath: Path,
|
||||||
|
vararg annotatedElementNames: String
|
||||||
|
) {
|
||||||
getGeneratedFileNames(*annotatedElementNames).forEach {
|
getGeneratedFileNames(*annotatedElementNames).forEach {
|
||||||
val file = project.projectDir.findFileByName(it)
|
assertFileNotExistsInTree(generateToPath, it)
|
||||||
assert(file == null) { "$file must not exist" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGeneratedFileNames(vararg annotatedElementNames: String): Iterable<String> {
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
val names = annotatedElementNames.map { it.capitalize() + "Generated" }
|
private fun getGeneratedFileNames(vararg annotatedElementNames: String) =
|
||||||
return names.map { it + ".java" }
|
annotatedElementNames
|
||||||
}
|
.map { name ->
|
||||||
|
name.replaceFirstChar {
|
||||||
|
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
|
||||||
|
} + "Generated.java"
|
||||||
|
}
|
||||||
|
|
||||||
|
val TestProject.kaptGeneratedToPath get() = projectPath.resolve("build/generated/source/kapt")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user