[Gradle] Migrate Kapt3AndroidIT to the new test DSL

#KT-44350 Fixed
#KT-45748 In Progress
This commit is contained in:
Alexander Likhachev
2022-10-13 05:07:21 +02:00
committed by Space Team
parent 8581c8a546
commit 8bbf98f24c
8 changed files with 480 additions and 457 deletions
@@ -1,452 +0,0 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.configuration.WarningMode
import org.jetbrains.kotlin.gradle.testbase.TestVersions
import org.jetbrains.kotlin.gradle.util.*
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.junit.Assert
import org.junit.Assume
import org.junit.Ignore
import org.junit.Test
import java.io.File
open class Kapt3Android41IT : Kapt3AndroidIT() {
override val androidGradlePluginVersion: AGPVersion
get() = AGPVersion.v4_1_0
// AGP 3.+ is not working with Gradle 7+
override val defaultGradleVersion: GradleVersionRequired
get() = GradleVersionRequired.Until(TestVersions.Gradle.G_6_9)
@Test
fun testAndroidxNavigationSafeArgs() = with(Project("androidx-navigation-safe-args", directoryPrefix = "kapt2")) {
// KT-30735
build("assembleDebug") {
assertSuccessful()
assertFileExists("build/generated/source/navigation-args/debug/test/androidx/navigation/StartFragmentDirections.java")
assertFileExists("build/tmp/kotlin-classes/debug/test/androidx/navigation/StartFragmentKt.class")
}
}
/** Regression test for Android projects and KT-31127. */
@Test
fun testKotlinProcessorUsingFiler() {
val project = Project("AndroidLibraryKotlinProject").apply {
setupWorkingDir()
gradleBuildScript().appendText(
"""
apply plugin: 'kotlin-kapt'
android {
defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = false
libraryVariants.all {
it.generateBuildConfig.enabled = false
}
}
dependencies {
kapt "org.jetbrains.kotlin:annotation-processor-example:${"$"}kotlin_version"
implementation "org.jetbrains.kotlin:annotation-processor-example:${"$"}kotlin_version"
}
""".trimIndent()
)
// The test must not contain any java sources in order to detect the issue.
Assert.assertEquals(emptyList<File>(), projectDir.allJavaFiles().toList())
projectDir.getFileByName("Dummy.kt").modify {
it.replace("class Dummy", "@example.KotlinFilerGenerated class Dummy")
}
}
project.build("assembleDebug") {
assertSuccessful()
assertFileExists("build/generated/source/kapt/debug/demo/DummyGenerated.kt")
assertTasksExecuted(":compileDebugKotlin")
assertTasksSkipped(":compileDebugJavaWithJavac")
}
}
}
class Kapt3Android70IT : Kapt3AndroidIT() {
override val androidGradlePluginVersion: AGPVersion
get() = AGPVersion.v7_0_0
override val defaultGradleVersion: GradleVersionRequired
get() = GradleVersionRequired.AtLeast(TestVersions.Gradle.G_7_0)
override fun defaultBuildOptions(): BuildOptions {
val javaHome = File(System.getProperty("jdk11Home")!!)
Assume.assumeTrue("JDK 11 should be available", javaHome.isDirectory)
return super.defaultBuildOptions().copy(javaHome = javaHome, warningMode = WarningMode.Summary)
}
@Ignore("KT-44350")
override fun testRealm() = Unit
@Ignore("KT-44350")
override fun testDatabinding() = Unit
@Ignore("KT-44350")
override fun testDagger() = Unit
@Ignore("KT-44350")
override fun testButterKnife() = Unit
@Test
override fun testInterProjectIC() {
with(Project("android-inter-project-ic", directoryPrefix = "kapt2")) {
setupWorkingDir()
// includeCompileClasspath was removed in AGP 7
projectDir.resolve("app").getFileByName("build.gradle").modify { originalContent ->
originalContent
.lines()
.filter { !it.contains("javaCompileOptions") }
.joinToString(separator = "\n")
}
build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
}
fun modifyAndCheck(utilFileName: String, useUtilFileName: String) {
val utilKt = projectDir.getFileByName(utilFileName)
utilKt.modify {
it.checkedReplace("Int", "Number")
}
build("assembleDebug") {
assertSuccessful()
val affectedFile = projectDir.getFileByName(useUtilFileName)
assertCompiledKotlinSources(
relativize(affectedFile),
tasks = listOf("app:kaptGenerateStubsDebugKotlin", "app:compileDebugKotlin")
)
}
}
modifyAndCheck("libAndroidUtil.kt", "useLibAndroidUtil.kt")
modifyAndCheck("libJvmUtil.kt", "useLibJvmUtil.kt")
}
}
}
class Kapt3Android42IT : BaseGradleIT() {
companion object {
private val KAPT_SUCCESSFUL_REGEX = "Annotation processing complete, errors: 0".toRegex()
}
private fun kaptOptions(): KaptOptions =
KaptOptions(verbose = true)
private fun CompiledProject.assertKaptSuccessful() {
KAPT_SUCCESSFUL_REGEX.findAll(this.output).count() > 0
}
override fun defaultBuildOptions(): BuildOptions =
super.defaultBuildOptions().copy(
kaptOptions = kaptOptions(),
warningMode = WarningMode.Summary,
androidHome = KtTestUtil.findAndroidSdk(),
androidGradlePluginVersion = AGPVersion.v4_2_0
)
/** Regression test for https://youtrack.jetbrains.com/issue/KT-44020. */
@Test
fun testDatabindingWithAndroidX() {
val project = Project("android-databinding-androidX", directoryPrefix = "kapt2")
project.build("kaptDebugKotlin") {
assertSuccessful()
assertKaptSuccessful()
}
}
}
abstract class Kapt3AndroidIT : BaseGradleIT() {
companion object {
private val KAPT_SUCCESSFUL_REGEX = "Annotation processing complete, errors: 0".toRegex()
}
protected open fun kaptOptions(): KaptOptions =
KaptOptions(verbose = true)
fun CompiledProject.assertKaptSuccessful() {
KAPT_SUCCESSFUL_REGEX.findAll(this.output).count() > 0
}
protected abstract val androidGradlePluginVersion: AGPVersion
override fun defaultBuildOptions() =
super.defaultBuildOptions().copy(
kaptOptions = kaptOptions(),
warningMode = WarningMode.Summary,
androidHome = KtTestUtil.findAndroidSdk(),
androidGradlePluginVersion = androidGradlePluginVersion
)
@Test
open fun testButterKnife() {
val project = Project("android-butterknife", directoryPrefix = "kapt2")
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("app/build/generated/source/kapt/debug/org/example/kotlin/butterknife/SimpleActivity\$\$ViewBinder.java")
val butterknifeJavaClassesDir =
"app/build/intermediates/javac/debug/classes/org/example/kotlin/butterknife/"
assertFileExists(butterknifeJavaClassesDir + "SimpleActivity\$\$ViewBinder.class")
assertFileExists("app/build/tmp/kotlin-classes/debug/org/example/kotlin/butterknife/SimpleAdapter\$ViewHolder.class")
}
project.build("assembleDebug") {
assertSuccessful()
assertTasksUpToDate(":compileDebugKotlin", ":compileDebugJavaWithJavac")
}
}
@Test
open fun testDagger() {
val project = Project("android-dagger", directoryPrefix = "kapt2")
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("app/build/generated/source/kapt/debug/com/example/dagger/kotlin/DaggerApplicationComponent.java")
assertFileExists("app/build/generated/source/kapt/debug/com/example/dagger/kotlin/ui/HomeActivity_MembersInjector.java")
val daggerJavaClassesDir =
"app/build/intermediates/javac/debug/classes/com/example/dagger/kotlin/"
assertFileExists(daggerJavaClassesDir + "DaggerApplicationComponent.class")
assertFileExists("app/build/tmp/kotlin-classes/debug/com/example/dagger/kotlin/AndroidModule.class")
}
}
@Test
fun testKt15001() {
val project = Project("kt15001", directoryPrefix = "kapt2")
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
}
}
@Test
fun testDbFlow() {
val project = Project(
"android-dbflow",
directoryPrefix = "kapt2",
minLogLevel = LogLevel.INFO
)
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("app/build/generated/source/kapt/debug/com/raizlabs/android/dbflow/config/GeneratedDatabaseHolder.java")
assertFileExists("app/build/generated/source/kapt/debug/com/raizlabs/android/dbflow/config/AppDatabaseAppDatabase_Database.java")
assertFileExists("app/build/generated/source/kapt/debug/mobi/porquenao/poc/kotlin/core/Item_Table.java")
}
}
@Test
open fun testRealm() {
val project = Project("android-realm", directoryPrefix = "kapt2")
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("build/generated/source/kapt/debug/io/realm/CatRealmProxy.java")
assertFileExists("build/generated/source/kapt/debug/io/realm/CatRealmProxyInterface.java")
assertFileExists("build/generated/source/kapt/debug/io/realm/DefaultRealmModule.java")
assertFileExists("build/generated/source/kapt/debug/io/realm/DefaultRealmModuleMediator.java")
}
}
@Test
open fun testInterProjectIC() = with(Project("android-inter-project-ic", directoryPrefix = "kapt2")) {
build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
}
fun modifyAndCheck(utilFileName: String, useUtilFileName: String) {
val utilKt = projectDir.getFileByName(utilFileName)
utilKt.modify {
it.checkedReplace("Int", "Number")
}
build("assembleDebug") {
assertSuccessful()
val affectedFile = projectDir.getFileByName(useUtilFileName)
assertCompiledKotlinSources(
relativize(affectedFile),
tasks = listOf("app:kaptGenerateStubsDebugKotlin", "app:compileDebugKotlin")
)
}
}
modifyAndCheck("libAndroidUtil.kt", "useLibAndroidUtil.kt")
modifyAndCheck("libJvmUtil.kt", "useLibJvmUtil.kt")
}
@Test
fun testICWithAnonymousClasses() {
val project = Project("icAnonymousTypes", directoryPrefix = "kapt2")
setupDataBinding(project)
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
}
val aKt = project.projectDir.getFileByName("a.kt").also { assert(it.exists()) }
aKt.modify {
assert(it.contains("CrashMe2(1000)"))
it.replace("CrashMe2(1000)", "CrashMe2(2000)")
}
project.build("assembleDebug") {
assertSuccessful()
assertKaptSuccessful()
}
}
@Test
open fun testDatabinding() {
val javaHome = File(System.getProperty("jdk11Home")!!)
Assume.assumeTrue("JDK 11 should be available", javaHome.isDirectory)
val project = Project("android-databinding", directoryPrefix = "kapt2")
setupDataBinding(project)
project.build(
"assembleDebug", "assembleAndroidTest",
options = defaultBuildOptions().copy(javaHome = javaHome)
) {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("app/build/generated/source/kapt/debug/com/example/databinding/BR.java")
// databinding compiler v2 was introduced in AGP 3.1.0, was enabled by default in AGP 3.2.0
assertContains("-Aandroid.databinding.enableV2=1")
assertNoSuchFile("library/build/generated/source/kapt/debugAndroidTest/android/databinding/DataBinderMapperImpl.java")
assertFileExists("app/build/generated/source/kapt/debug/com/example/databinding/databinding/ActivityTestBindingImpl.java")
// KT-23866
assertNotContains("The following options were not recognized by any processor")
}
}
// KT-45532
@Test
open fun kaptTasksShouldNotCreateOutputsOnConfigurationPhase() {
Project(
"android-dagger",
directoryPrefix = "kapt2"
).build("--dry-run", "assembleDebug") {
assertSuccessful()
assertNoSuchFile("app/build/tmp")
assertNoSuchFile("app/build/generated")
}
}
@Test
fun testStaticDslOptionsPassedToKapt() = with(Project("android-dagger", directoryPrefix = "kapt2")) {
setupWorkingDir()
gradleBuildScript(subproject = "app").appendText(
"""
apply plugin: 'kotlin-kapt'
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments += ["enable.some.test.option": "true"]
}
}
}
}
""".trimIndent()
)
build(":app:kaptDebugKotlin") {
assertSuccessful()
assertContainsRegex(Regex("AP options.*enable\\.some\\.test\\.option=true"))
}
}
@Test
fun generateStubsTaskShouldRunIncrementallyOnChangesInAndroidVariantJavaSources() {
with(Project("android-dagger", directoryPrefix = "kapt2")) {
setupWorkingDir()
val javaFile = projectDir.resolve("app/src/main/java/com/example/dagger/kotlin/Utils.java")
javaFile.writeText(
//language=Java
"""
package com.example.dagger.kotlin;
class Utils {
public String oneMethod() {
return "fake!";
}
}
""".trimIndent()
)
build(":app:kaptDebugKotlin") {
assertSuccessful()
assertTasksExecuted(":app:kaptGenerateStubsDebugKotlin")
}
javaFile.writeText(
//language=Java
"""
package com.example.dagger.kotlin;
class Utils {
public String oneMethod() {
return "fake!";
}
public void anotherMethod() {
int one = 1;
}
}
""".trimIndent()
)
build(":app:kaptDebugKotlin") {
assertSuccessful()
assertTasksExecuted(":app:kaptGenerateStubsDebugKotlin")
assertNotContains(
"The input changes require a full rebuild for incremental task ':app:kaptGenerateStubsDebugKotlin'."
)
}
}
}
private fun setupDataBinding(project: Project) {
project.setupWorkingDir()
project.gradleBuildScript().modify {
it + "\n\n" + """
allprojects {
plugins.withId("kotlin-kapt") {
println("${'$'}project android.databinding.enableV2=${'$'}{project.findProperty('android.databinding.enableV2')}")
// With new AGP, there's no need in the Databinding kapt dependency:
configurations.kapt.exclude group: "com.android.databinding", module: "compiler"
}
}
""".trimIndent()
}
}
}
@@ -0,0 +1,469 @@
/*
* Copyright 2010-2022 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.android
import org.gradle.api.JavaVersion
import org.gradle.api.logging.LogLevel
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.Kapt3BaseIT
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.testbase.TestVersions.AGP.AGP_42
import org.jetbrains.kotlin.gradle.util.*
import org.junit.jupiter.api.DisplayName
import java.io.File
import java.nio.file.Path
import kotlin.io.path.appendText
import kotlin.io.path.relativeTo
import kotlin.io.path.writeText
@DisplayName("android with kapt3 tests")
@AndroidGradlePluginTests
class Kapt3AndroidIT : Kapt3BaseIT() {
@DisplayName("kapt works with butterknife")
@GradleAndroidTest
fun testButterKnife(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-butterknife".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
build("assembleDebug") {
assertKaptSuccessful()
assertFileInProjectExists("app/build/generated/source/kapt/debug/org/example/kotlin/butterknife/SimpleActivity\$\$ViewBinder.java")
val butterknifeJavaClassesDir = "app/build/intermediates/javac/debug/classes/org/example/kotlin/butterknife/"
assertFileInProjectExists(butterknifeJavaClassesDir + "SimpleActivity\$\$ViewBinder.class")
assertFileInProjectExists("app/build/tmp/kotlin-classes/debug/org/example/kotlin/butterknife/SimpleAdapter\$ViewHolder.class")
}
build("assembleDebug") {
assertTasksUpToDate(":app:compileDebugKotlin", ":app:compileDebugJavaWithJavac")
}
}
}
@DisplayName("kapt works with dagger")
@GradleAndroidTest
fun testDagger(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-dagger".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
build("assembleDebug") {
assertKaptSuccessful()
assertFileInProjectExists("app/build/generated/source/kapt/debug/com/example/dagger/kotlin/DaggerApplicationComponent.java")
assertFileInProjectExists("app/build/generated/source/kapt/debug/com/example/dagger/kotlin/ui/HomeActivity_MembersInjector.java")
val daggerJavaClassesDir =
"app/build/intermediates/javac/debug/classes/com/example/dagger/kotlin/"
assertFileInProjectExists(daggerJavaClassesDir + "DaggerApplicationComponent.class")
assertFileInProjectExists("app/build/tmp/kotlin-classes/debug/com/example/dagger/kotlin/AndroidModule.class")
}
}
}
@DisplayName("KT-15001")
@GradleAndroidTest
fun testKt15001(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"kt15001".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
build("assembleDebug") {
assertKaptSuccessful()
}
}
}
@DisplayName("kapt works with DbFlow")
@GradleAndroidTest
fun testDbFlow(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-dbflow".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
build("assembleDebug") {
assertKaptSuccessful()
assertFileInProjectExists("app/build/generated/source/kapt/debug/com/raizlabs/android/dbflow/config/GeneratedDatabaseHolder.java")
assertFileInProjectExists("app/build/generated/source/kapt/debug/com/raizlabs/android/dbflow/config/AppDatabaseAppDatabase_Database.java")
assertFileInProjectExists("app/build/generated/source/kapt/debug/mobi/porquenao/poc/kotlin/core/Item_Table.java")
}
}
}
@DisplayName("kapt works with realm")
@GradleAndroidTest
fun testRealm(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-realm".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
build("assembleDebug") {
assertKaptSuccessful()
assertFileInProjectExists("build/generated/source/kapt/debug/io/realm/CatRealmProxy.java")
assertFileInProjectExists("build/generated/source/kapt/debug/io/realm/CatRealmProxyInterface.java")
assertFileInProjectExists("build/generated/source/kapt/debug/io/realm/DefaultRealmModule.java")
assertFileInProjectExists("build/generated/source/kapt/debug/io/realm/DefaultRealmModuleMediator.java")
}
}
}
@DisplayName("kapt works with databinding")
@GradleAndroidTest
fun testDatabinding(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-databinding".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
// TODO: remove the `if` when we drop support for [TestVersions.AGP.AGP_42]
buildJdk = if (jdkVersion.version >= JavaVersion.VERSION_11) jdkVersion.location else File(System.getProperty("jdk11Home"))
) {
setupDataBinding()
build(
"assembleDebug", "assembleAndroidTest",
) {
assertKaptSuccessful()
assertFileInProjectExists("app/build/generated/source/kapt/debug/com/example/databinding/BR.java")
// databinding compiler v2 was introduced in AGP 3.1.0, was enabled by default in AGP 3.2.0
assertOutputContains("-Aandroid.databinding.enableV2=1")
assertFileInProjectNotExists("library/build/generated/source/kapt/debugAndroidTest/android/databinding/DataBinderMapperImpl.java")
assertFileInProjectExists("app/build/generated/source/kapt/debug/com/example/databinding/databinding/ActivityTestBindingImpl.java")
// KT-23866
assertOutputDoesNotContain("The following options were not recognized by any processor")
}
}
}
@DisplayName("KT-25374: kapt doesn't fail with anonymous classes with IC")
@GradleAndroidTest
fun testICWithAnonymousClasses(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"icAnonymousTypes".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
setupDataBinding()
build("assembleDebug") {
assertKaptSuccessful()
}
val modifiedSource = javaSourcesDir().resolve("a.kt")
modifiedSource.modify {
assert(it.contains("CrashMe2(1000)"))
it.replace("CrashMe2(1000)", "CrashMe2(2000)")
}
build("assembleDebug")
}
}
@DisplayName("static dsl options are passed to kapt")
@GradleAndroidTest
fun testStaticDslOptionsPassedToKapt(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-dagger".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
subProject("app").buildGradle.appendText(
"""
apply plugin: 'kotlin-kapt'
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments += ["enable.some.test.option": "true"]
}
}
}
}
""".trimIndent()
)
build(":app:kaptDebugKotlin") {
assertOutputContains(Regex("AP options.*enable\\.some\\.test\\.option=true"))
}
}
}
@DisplayName("stubs generation is incremental on changes in android variant java sources")
@GradleAndroidTest
fun generateStubsTaskShouldRunIncrementallyOnChangesInAndroidVariantJavaSources(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-dagger".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
val javaFile = subProject("app").javaSourcesDir().resolve("com/example/dagger/kotlin/Utils.java")
javaFile.writeText(
//language=Java
"""
package com.example.dagger.kotlin;
class Utils {
public String oneMethod() {
return "fake!";
}
}
""".trimIndent()
)
build(":app:kaptDebugKotlin") {
assertTasksExecuted(":app:kaptGenerateStubsDebugKotlin")
}
javaFile.writeText(
//language=Java
"""
package com.example.dagger.kotlin;
class Utils {
public String oneMethod() {
return "fake!";
}
public void anotherMethod() {
int one = 1;
}
}
""".trimIndent()
)
build(":app:kaptDebugKotlin") {
assertTasksExecuted(":app:kaptGenerateStubsDebugKotlin")
assertOutputDoesNotContain(
"The input changes require a full rebuild for incremental task ':app:kaptGenerateStubsDebugKotlin'."
)
}
}
}
@DisplayName("KT-45532: kapt tasks shouldn't create outputs at configuration time")
@GradleAndroidTest
fun kaptTasksShouldNotCreateOutputsOnConfigurationPhase(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-dagger".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
build("--dry-run", "assembleDebug") {
assertFileInProjectNotExists("app/build/tmp")
assertFileInProjectNotExists("app/build/generated")
}
}
}
@DisplayName("KT-30735: kapt works with androidx.navigation.safeargs")
@GradleAndroidTest
fun testAndroidxNavigationSafeArgs(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"androidx-navigation-safe-args".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
val safeArgsVersion = if (gradleVersion >= GradleVersion.version(TestVersions.Gradle.G_7_0)) "2.5.3" else "2.1.0"
build("assembleDebug", "-Psafe_args_version=$safeArgsVersion") {
assertFileInProjectExists("build/generated/source/navigation-args/debug/test/androidx/navigation/StartFragmentDirections.java")
assertFileInProjectExists("build/tmp/kotlin-classes/debug/test/androidx/navigation/StartFragmentKt.class")
}
}
}
@DisplayName("KT-31127: kapt doesn't break JavaCompile when using Filer API")
@GradleAndroidTest
fun testKotlinProcessorUsingFiler(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"AndroidLibraryKotlinProject",
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
buildGradle.appendText(
"""
apply plugin: 'kotlin-kapt'
android {
libraryVariants.all {
it.generateBuildConfig.enabled = false
}
}
dependencies {
kapt "org.jetbrains.kotlin:annotation-processor-example:${"$"}kotlin_version"
implementation "org.jetbrains.kotlin:annotation-processor-example:${"$"}kotlin_version"
}
""".trimIndent()
)
// The test must not contain any java sources in order to detect the issue.
val javaSources = projectPath.allJavaSources
assert(javaSources.isEmpty()) {
"Test project shouldn't contain any java sources, but it contains: $javaSources"
}
kotlinSourcesDir().resolve("Dummy.kt").modify {
it.replace("class Dummy", "@example.KotlinFilerGenerated class Dummy")
}
build("assembleDebug") {
assertFileInProjectExists("build/generated/source/kapt/debug/demo/DummyGenerated.kt")
assertTasksExecuted(":compileDebugKotlin")
assertTasksNoSource(":compileDebugJavaWithJavac")
}
}
}
@DisplayName("inter-project IC works with kapt")
@GradleAndroidTest
fun testInterProjectIC(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-inter-project-ic".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
build("assembleDebug") {
assertKaptSuccessful()
}
fun modifyAndCheck(utilKt: Path, useUtilFileName: String) {
utilKt.modify {
it.checkedReplace("Int", "Number")
}
build("assembleDebug", buildOptions = buildOptions.copy(logLevel = LogLevel.DEBUG)) {
val affectedFile = subProject("app").kotlinSourcesDir().resolve("org.example.inter.project.ic")
.resolve(useUtilFileName).relativeTo(projectPath)
assertCompiledKotlinSources(
listOf(affectedFile),
getOutputForTask("app:kaptGenerateStubsDebugKotlin"),
errorMessageSuffix = " in task ':app:kaptGenerateStubsDebugKotlin"
)
assertCompiledKotlinSources(
listOf(affectedFile),
getOutputForTask("app:compileDebugKotlin"),
errorMessageSuffix = " in task ':app:compileDebugKotlin"
)
}
}
val libAndroidProject = subProject("lib-android")
modifyAndCheck(libAndroidProject.kotlinSourcesDir().resolve("libAndroidUtil.kt"), "useLibAndroidUtil.kt")
val libJvmProject = subProject("lib-jvm")
modifyAndCheck(libJvmProject.kotlinSourcesDir().resolve("libJvmUtil.kt"), "useLibJvmUtil.kt")
}
}
@DisplayName("kapt works with androidx")
@GradleAndroidTest
@AndroidTestVersions(minVersion = AGP_42, maxVersion = AGP_42)
fun testDatabindingWithAndroidX(
gradleVersion: GradleVersion,
agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk,
) {
project(
"android-databinding-androidX".withPrefix,
gradleVersion,
buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion),
buildJdk = jdkVersion.location
) {
build("kaptDebugKotlin") {
assertKaptSuccessful()
}
}
}
private fun TestProject.setupDataBinding() {
buildGradle.appendText(
//language=Gradle
"""
allprojects {
plugins.withId("kotlin-kapt") {
println("${'$'}project android.databinding.enableV2=${'$'}{project.findProperty('android.databinding.enableV2')}")
// With new AGP, there's no need in the Databinding kapt dependency:
configurations.kapt.exclude group: "com.android.databinding", module: "compiler"
}
}
""".trimIndent()
)
}
}
@@ -35,5 +35,6 @@ dependencies {
implementation 'com.google.dagger:dagger:2.9'
kapt 'com.google.dagger:dagger-compiler:2.9'
kapt 'javax.annotation:javax.annotation-api:1.3.2'
compileOnly 'org.glassfish:javax.annotation:10.0-b28'
}
@@ -24,6 +24,6 @@ android {
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile 'com.android.support.constraint:constraint-layout:1.0.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}
@@ -7,7 +7,7 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<activity android:name=".MainActivity" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
@@ -11,7 +11,6 @@ android {
targetSdkVersion 23
versionCode 1
versionName "1.0"
javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true
}
// Needed for older AGP. It can be removed when the lowest supported AGP version is 4.2.0 or newer.
@@ -16,6 +16,12 @@ buildscript {
}
}
// workaround for com.android.tools.build:gradle:1.1.1 adding dependencies to the `compile` configuration
configurations {
maybeCreate("compile")
implementation.extendsFrom(compile)
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
@@ -7,7 +7,7 @@ buildscript {
dependencies {
classpath "com.android.tools.build:gradle:$android_tools_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.1.0-alpha01"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$safe_args_version"
}
}