diff --git a/burst-gradle-plugin/src/test/kotlin/app/cash/burst/gradle/BurstGradlePluginTest.kt b/burst-gradle-plugin/src/test/kotlin/app/cash/burst/gradle/BurstGradlePluginTest.kt index 288c653..a14c92d 100644 --- a/burst-gradle-plugin/src/test/kotlin/app/cash/burst/gradle/BurstGradlePluginTest.kt +++ b/burst-gradle-plugin/src/test/kotlin/app/cash/burst/gradle/BurstGradlePluginTest.kt @@ -303,6 +303,32 @@ class BurstGradlePluginTest { } } + /** https://github.com/cashapp/burst/issues/90 */ + @Test + fun subclass() { + val projectDir = File("src/test/projects/subclass") + + val taskName = ":lib:test" + val result = createRunner(projectDir, "clean", taskName).build() + assertThat(result.task(taskName)!!.outcome).isIn(*SUCCESS_OUTCOMES) + + val testResults = projectDir.resolve("lib/build/test-results") + with(readTestSuite(testResults.resolve("test/TEST-CoffeeTest.xml"))) { + assertThat(testCases.map { it.name }).containsExactlyInAnyOrder( + "hasFakeOverride", + "hasFakeOverride_Oat", + "hasRealOverride", + "hasRealOverride_Oat", + ) + assertThat(systemOut.trim().lines()).containsExactlyInAnyOrder( + "running fakeOverride Milk", + "running fakeOverride Oat", + "running realOverride Milk", + "running realOverride Oat", + ) + } + } + private fun createRunner( projectDir: File, vararg taskNames: String, diff --git a/burst-gradle-plugin/src/test/projects/subclass/build.gradle.kts b/burst-gradle-plugin/src/test/projects/subclass/build.gradle.kts new file mode 100644 index 0000000..66fc2bb --- /dev/null +++ b/burst-gradle-plugin/src/test/projects/subclass/build.gradle.kts @@ -0,0 +1,37 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile + +buildscript { + repositories { + maven { + url = file("$rootDir/../../../../../build/testMaven").toURI() + } + mavenCentral() + google() + } + dependencies { + classpath("app.cash.burst:burst-gradle-plugin:${project.property("burstVersion")}") + classpath(libs.kotlin.gradlePlugin) + } +} + +allprojects { + repositories { + maven { + url = file("$rootDir/../../../../../build/testMaven").toURI() + } + mavenCentral() + google() + } + + tasks.withType(JavaCompile::class.java).configureEach { + sourceCompatibility = "1.8" + targetCompatibility = "1.8" + } + + tasks.withType(KotlinJvmCompile::class.java).configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_1_8) + } + } +} diff --git a/burst-gradle-plugin/src/test/projects/subclass/lib/build.gradle.kts b/burst-gradle-plugin/src/test/projects/subclass/lib/build.gradle.kts new file mode 100644 index 0000000..36cb092 --- /dev/null +++ b/burst-gradle-plugin/src/test/projects/subclass/lib/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + kotlin("jvm") + id("app.cash.burst") +} + +dependencies { + testImplementation(kotlin("test")) +} diff --git a/burst-gradle-plugin/src/test/projects/subclass/lib/src/test/kotlin/CoffeeTest.kt b/burst-gradle-plugin/src/test/projects/subclass/lib/src/test/kotlin/CoffeeTest.kt new file mode 100644 index 0000000..01e23ba --- /dev/null +++ b/burst-gradle-plugin/src/test/projects/subclass/lib/src/test/kotlin/CoffeeTest.kt @@ -0,0 +1,24 @@ +import app.cash.burst.Burst +import app.cash.burst.burstValues +import kotlin.test.Test + +@Burst +class CoffeeTest : BaseCoffeeTest() { + @Test + override fun hasRealOverride(dairy: String) { + println("running realOverride $dairy") + } +} + +@Burst +abstract class BaseCoffeeTest { + @Test + open fun hasRealOverride(dairy: String = burstValues("Milk", "Oat")) { + error("unexpected call") + } + + @Test + open fun hasFakeOverride(dairy: String = burstValues("Milk", "Oat")) { + println("running fakeOverride $dairy") + } +} diff --git a/burst-gradle-plugin/src/test/projects/subclass/settings.gradle.kts b/burst-gradle-plugin/src/test/projects/subclass/settings.gradle.kts new file mode 100644 index 0000000..78eeed4 --- /dev/null +++ b/burst-gradle-plugin/src/test/projects/subclass/settings.gradle.kts @@ -0,0 +1,9 @@ +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../../../../../gradle/libs.versions.toml")) + } + } +} + +include(":lib") diff --git a/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/FunctionSpecializer.kt b/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/FunctionSpecializer.kt index afa85dc..fdd25f5 100644 --- a/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/FunctionSpecializer.kt +++ b/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/FunctionSpecializer.kt @@ -72,6 +72,17 @@ internal class FunctionSpecializer( val originalDispatchReceiver = original.dispatchReceiverParameter ?: throw BurstCompilationException("Unexpected dispatch receiver", original) + // Drop `@Test` from the original's annotations. + original.annotations = original.annotations.filter { + it.type.classOrNull != testAnnotationClassSymbol + } + + // Skip overrides. Burst will specialize the overridden function, and that's sufficient! (And + // we can't do anything here anyway, because overrides don't support default parameters.) + if (original.overriddenSymbols.isNotEmpty()) { + return + } + val specializations = specializations(pluginContext, burstApis, valueParameters) val indexOfDefaultSpecialization = specializations.indexOfFirst { it.isDefault } @@ -83,11 +94,6 @@ internal class FunctionSpecializer( ) } - // Drop `@Test` from the original's annotations. - original.annotations = original.annotations.filter { - it.type.classOrNull != testAnnotationClassSymbol - } - // Add new declarations. for (function in functions) { originalParent.addDeclaration(function)