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 32d0580..f724ed1 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 @@ -30,45 +30,95 @@ import org.junit.Test class BurstGradlePluginTest { @Test - fun multiplatform() { + fun multiplatformJvm() { + multiplatform( + testTaskName = "jvmTest", + platformName = "jvm", + ) + } + + @Test + fun multiplatformJs() { + multiplatform( + testTaskName = "jsNodeTest", + platformName = "js, node", + ) + } + + private fun multiplatform( + testTaskName: String, + platformName: String, + ) { val projectDir = File("src/test/projects/multiplatform") - val taskName = ":lib:jvmTest" + val taskName = ":lib:$testTaskName" val result = createRunner(projectDir, "clean", taskName).build() assertThat(SUCCESS_OUTCOMES) .contains(result.task(taskName)!!.outcome) val testResults = projectDir.resolve("lib/build/test-results") - val jvmTestXmlFile = testResults.resolve("jvmTest/TEST-CoffeeTest.xml") - - val testSuite = readTestSuite(jvmTestXmlFile) - assertThat(testSuite.testCases.map { it.name }).containsExactlyInAnyOrder( - "test[jvm]", - "test_Decaf_Milk[jvm]", - "test_Decaf_None[jvm]", - "test_Decaf_Oat[jvm]", - "test_Double_Milk[jvm]", - "test_Double_None[jvm]", - "test_Double_Oat[jvm]", - "test_Regular_Milk[jvm]", - "test_Regular_None[jvm]", - "test_Regular_Oat[jvm]", - ) - - val originalTest = testSuite.testCases.single { it.name == "test[jvm]" } - assertThat(originalTest.skipped).isFalse() - - val defaultSpecialization = testSuite.testCases.single { it.name == "test_Decaf_None[jvm]" } - assertThat(defaultSpecialization.skipped).isTrue() - - val sampleSpecialization = testSuite.testCases.single { it.name == "test_Regular_Milk[jvm]" } - assertThat(sampleSpecialization.skipped).isFalse() + // The original test class runs the default specialization. + with(readTestSuite(testResults.resolve("$testTaskName/TEST-CoffeeTest.xml"))) { + assertThat(testCases.map { it.name }).containsExactlyInAnyOrder( + "test[$platformName]", + "test_Milk[$platformName]", + "test_None[$platformName]", + "test_Oat[$platformName]", + ) + + val defaultFunction = testCases.single { it.name == "test[$platformName]" } + assertThat(defaultFunction.skipped).isFalse() + + val defaultSpecialization = testCases.single { it.name == "test_None[$platformName]" } + assertThat(defaultSpecialization.skipped).isTrue() + + val sampleSpecialization = testCases.single { it.name == "test_Milk[$platformName]" } + assertThat(sampleSpecialization.skipped).isFalse() + } + + // The default test class is completely skipped. + with(readTestSuite(testResults.resolve("$testTaskName/TEST-CoffeeTest_Decaf.xml"))) { + assertThat(testCases.map { it.name }).containsExactlyInAnyOrder( + "test[$platformName]", + "test_Milk[$platformName]", + "test_None[$platformName]", + "test_Oat[$platformName]", + ) + + val defaultFunction = testCases.single { it.name == "test[$platformName]" } + assertThat(defaultFunction.skipped).isTrue() + + val defaultSpecialization = testCases.single { it.name == "test_None[$platformName]" } + assertThat(defaultSpecialization.skipped).isTrue() + + val sampleSpecialization = testCases.single { it.name == "test_Milk[$platformName]" } + assertThat(sampleSpecialization.skipped).isTrue() + } + + // Another test class is executed normally with nothing skipped. + with(readTestSuite(testResults.resolve("$testTaskName/TEST-CoffeeTest_Regular.xml"))) { + assertThat(testCases.map { it.name }).containsExactlyInAnyOrder( + "test[$platformName]", + "test_Milk[$platformName]", + "test_None[$platformName]", + "test_Oat[$platformName]", + ) + + val defaultFunction = testCases.single { it.name == "test[$platformName]" } + assertThat(defaultFunction.skipped).isFalse() + + val defaultSpecialization = testCases.single { it.name == "test_None[$platformName]" } + assertThat(defaultSpecialization.skipped).isTrue() + + val sampleSpecialization = testCases.single { it.name == "test_Milk[$platformName]" } + assertThat(sampleSpecialization.skipped).isFalse() + } } @Test - fun jvm() { - val projectDir = File("src/test/projects/jvm") + fun functionParameters() { + val projectDir = File("src/test/projects/functionParameters") val taskName = ":lib:test" val result = createRunner(projectDir, "clean", taskName).build() diff --git a/burst-gradle-plugin/src/test/projects/jvm/build.gradle.kts b/burst-gradle-plugin/src/test/projects/functionParameters/build.gradle.kts similarity index 100% rename from burst-gradle-plugin/src/test/projects/jvm/build.gradle.kts rename to burst-gradle-plugin/src/test/projects/functionParameters/build.gradle.kts diff --git a/burst-gradle-plugin/src/test/projects/jvm/lib/build.gradle.kts b/burst-gradle-plugin/src/test/projects/functionParameters/lib/build.gradle.kts similarity index 100% rename from burst-gradle-plugin/src/test/projects/jvm/lib/build.gradle.kts rename to burst-gradle-plugin/src/test/projects/functionParameters/lib/build.gradle.kts diff --git a/burst-gradle-plugin/src/test/projects/jvm/lib/src/test/kotlin/CoffeeTest.kt b/burst-gradle-plugin/src/test/projects/functionParameters/lib/src/test/kotlin/CoffeeTest.kt similarity index 100% rename from burst-gradle-plugin/src/test/projects/jvm/lib/src/test/kotlin/CoffeeTest.kt rename to burst-gradle-plugin/src/test/projects/functionParameters/lib/src/test/kotlin/CoffeeTest.kt diff --git a/burst-gradle-plugin/src/test/projects/jvm/settings.gradle.kts b/burst-gradle-plugin/src/test/projects/functionParameters/settings.gradle.kts similarity index 100% rename from burst-gradle-plugin/src/test/projects/jvm/settings.gradle.kts rename to burst-gradle-plugin/src/test/projects/functionParameters/settings.gradle.kts diff --git a/burst-gradle-plugin/src/test/projects/multiplatform/lib/build.gradle.kts b/burst-gradle-plugin/src/test/projects/multiplatform/lib/build.gradle.kts index c16da92..dbbc712 100644 --- a/burst-gradle-plugin/src/test/projects/multiplatform/lib/build.gradle.kts +++ b/burst-gradle-plugin/src/test/projects/multiplatform/lib/build.gradle.kts @@ -5,6 +5,9 @@ plugins { kotlin { jvm() + js { + nodejs() + } sourceSets { commonTest { diff --git a/burst-gradle-plugin/src/test/projects/multiplatform/lib/src/commonTest/kotlin/CoffeeTest.kt b/burst-gradle-plugin/src/test/projects/multiplatform/lib/src/commonTest/kotlin/CoffeeTest.kt index f0d9d02..9833508 100644 --- a/burst-gradle-plugin/src/test/projects/multiplatform/lib/src/commonTest/kotlin/CoffeeTest.kt +++ b/burst-gradle-plugin/src/test/projects/multiplatform/lib/src/commonTest/kotlin/CoffeeTest.kt @@ -1,10 +1,18 @@ import app.cash.burst.Burst +import kotlin.test.BeforeTest import kotlin.test.Test @Burst -class CoffeeTest { +class CoffeeTest( + private val espresso: Espresso, +) { + @BeforeTest + fun setUp() { + println("set up $espresso") + } + @Test - fun test(espresso: Espresso, dairy: Dairy) { + fun test(dairy: Dairy) { println("running $espresso $dairy") } } diff --git a/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/BurstApis.kt b/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/BurstApis.kt index e629f10..6cf53e5 100644 --- a/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/BurstApis.kt +++ b/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/BurstApis.kt @@ -57,7 +57,7 @@ private val burstAnnotationClassId = burstFqPackage.classId("Burst") val junitPackage = FqPackageName("org.junit") val junitTestClassId = junitPackage.classId("Test") -val kotlinTestPackage = FqPackageName("kotlin.text") +val kotlinTestPackage = FqPackageName("kotlin.test") val kotlinTestClassId = kotlinTestPackage.classId("Test") internal val IrAnnotationContainer.hasAtTest: Boolean diff --git a/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/ClassSpecializer.kt b/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/ClassSpecializer.kt index 23d1c31..fe55b8f 100644 --- a/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/ClassSpecializer.kt +++ b/burst-kotlin-plugin/src/main/kotlin/app/cash/burst/kotlin/ClassSpecializer.kt @@ -16,7 +16,8 @@ package app.cash.burst.kotlin import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext -import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.PROTECTED +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.PUBLIC import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.builders.declarations.addConstructor import org.jetbrains.kotlin.ir.builders.declarations.buildClass @@ -96,7 +97,7 @@ internal class ClassSpecializer( // Add @Ignore and open the class // TODO: don't double-add @Ignore original.modality = Modality.OPEN - onlyConstructor.visibility = DescriptorVisibilities.PROTECTED + onlyConstructor.visibility = PROTECTED // Add a no-args constructor that calls the only constructor as the default specialization. createNoArgsConstructor( @@ -121,6 +122,7 @@ internal class ClassSpecializer( ) { val specialization = original.factory.buildClass { initDefaults(original) + visibility = PUBLIC name = Name.identifier(name("${original.name.identifier}_", arguments)) }.apply { superTypes = listOf(original.defaultType) @@ -161,6 +163,7 @@ internal class ClassSpecializer( ) { original.addConstructor { initDefaults(original) + isPrimary = false }.apply { irConstructorBody(pluginContext) { statements -> statements += irDelegatingConstructorCall(