From 76a96104f8e63e163e712525916439ca9ae8ebe7 Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Tue, 1 Oct 2024 13:43:06 -0400 Subject: [PATCH] Don't forget that snapshot tests must start with 'test' --- build-support-ksp-processor/build.gradle.kts | 7 +++ .../buildsupportksp/RedwoodSymbolProcessor.kt | 31 +++++++++++++ .../RedwoodSymbolProcessorProvider.kt | 24 ++++++++++ .../buildsupportksp/SnapshotTestProcessor.kt | 46 +++++++++++++++++++ ...ols.ksp.processing.SymbolProcessorProvider | 1 + build-support/build.gradle | 1 + .../buildsupport/RedwoodBuildExtension.kt | 3 ++ .../buildsupport/RedwoodBuildPlugin.kt | 5 ++ gradle/libs.versions.toml | 3 ++ redwood-layout-shared-test/build.gradle | 1 + .../layout/AbstractFlexContainerTest.kt | 2 +- redwood-lazylayout-shared-test/build.gradle | 1 + redwood-widget-shared-test/build.gradle | 1 + settings.gradle | 1 + 14 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 build-support-ksp-processor/build.gradle.kts create mode 100644 build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/RedwoodSymbolProcessor.kt create mode 100644 build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/RedwoodSymbolProcessorProvider.kt create mode 100644 build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/SnapshotTestProcessor.kt create mode 100644 build-support-ksp-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider diff --git a/build-support-ksp-processor/build.gradle.kts b/build-support-ksp-processor/build.gradle.kts new file mode 100644 index 0000000000..7d91f9f205 --- /dev/null +++ b/build-support-ksp-processor/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + kotlin("jvm") +} + +dependencies { + implementation(libs.kotlin.kspApi) +} diff --git a/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/RedwoodSymbolProcessor.kt b/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/RedwoodSymbolProcessor.kt new file mode 100644 index 0000000000..67b28a8b2e --- /dev/null +++ b/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/RedwoodSymbolProcessor.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package app.cash.redwood.buildsupportksp + +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.symbol.KSAnnotated + +class RedwoodSymbolProcessor( + private val environment: SymbolProcessorEnvironment, +) : SymbolProcessor { + override fun process(resolver: Resolver): List { + SnapshotTestProcessor(environment).process(resolver) + + return listOf() // No more rounds of annotation processing. + } +} diff --git a/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/RedwoodSymbolProcessorProvider.kt b/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/RedwoodSymbolProcessorProvider.kt new file mode 100644 index 0000000000..55b492df92 --- /dev/null +++ b/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/RedwoodSymbolProcessorProvider.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package app.cash.redwood.buildsupportksp + +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.processing.SymbolProcessorProvider + +class RedwoodSymbolProcessorProvider : SymbolProcessorProvider { + override fun create(environment: SymbolProcessorEnvironment) = + RedwoodSymbolProcessor(environment) +} diff --git a/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/SnapshotTestProcessor.kt b/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/SnapshotTestProcessor.kt new file mode 100644 index 0000000000..c1eca2be0b --- /dev/null +++ b/build-support-ksp-processor/src/main/kotlin/app/cash/redwood/buildsupportksp/SnapshotTestProcessor.kt @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package app.cash.redwood.buildsupportksp + +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.symbol.KSFunctionDeclaration + +/** Confirm all snapshot `@Test` functions also have names starting with `test`. */ +internal class SnapshotTestProcessor( + private val environment: SymbolProcessorEnvironment, +) { + fun process(resolver: Resolver) { + // Only run on the first round. + if (!resolver.getNewFiles().iterator().hasNext()) return + + checkAllTests(resolver) + } + + private fun checkAllTests(resolver: Resolver) { + for (symbol in resolver.getSymbolsWithAnnotation("org.junit.Test")) { + when { + symbol !is KSFunctionDeclaration -> { + environment.logger.info("Unexpected @Test", symbol) + } + + !symbol.simpleName.asString().startsWith("test") -> { + environment.logger.error("Expected @Test to start with 'test'", symbol) + } + } + } + } +} diff --git a/build-support-ksp-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/build-support-ksp-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider new file mode 100644 index 0000000000..f92cf20e0e --- /dev/null +++ b/build-support-ksp-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -0,0 +1 @@ +app.cash.redwood.buildsupportksp.RedwoodSymbolProcessorProvider diff --git a/build-support/build.gradle b/build-support/build.gradle index d74fb4b045..abd2f050e6 100644 --- a/build-support/build.gradle +++ b/build-support/build.gradle @@ -28,6 +28,7 @@ apply plugin: 'com.android.lint' dependencies { compileOnly gradleApi() implementation libs.kotlin.gradlePlugin + implementation libs.kotlin.kspGradlePlugin implementation libs.gradleMavenPublishPlugin implementation libs.dokkaPlugin implementation libs.spotlessPlugin diff --git a/build-support/src/main/kotlin/app/cash/redwood/buildsupport/RedwoodBuildExtension.kt b/build-support/src/main/kotlin/app/cash/redwood/buildsupport/RedwoodBuildExtension.kt index 5d51036d20..e116ba0734 100644 --- a/build-support/src/main/kotlin/app/cash/redwood/buildsupport/RedwoodBuildExtension.kt +++ b/build-support/src/main/kotlin/app/cash/redwood/buildsupport/RedwoodBuildExtension.kt @@ -46,6 +46,9 @@ interface RedwoodBuildExtension { fun TaskContainer.generateComposeHelpers(packageName: String): TaskProvider fun TaskContainer.generateFlexboxHelpers(packageName: String): TaskProvider + + /** Confirm all snapshot `@Test` functions also have names starting with `test`. */ + fun sharedSnapshotTests() } enum class TargetGroup { diff --git a/build-support/src/main/kotlin/app/cash/redwood/buildsupport/RedwoodBuildPlugin.kt b/build-support/src/main/kotlin/app/cash/redwood/buildsupport/RedwoodBuildPlugin.kt index cc37bf76b0..f2e89f6bd2 100644 --- a/build-support/src/main/kotlin/app/cash/redwood/buildsupport/RedwoodBuildPlugin.kt +++ b/build-support/src/main/kotlin/app/cash/redwood/buildsupport/RedwoodBuildPlugin.kt @@ -647,6 +647,11 @@ private class RedwoodBuildExtensionImpl(private val project: Project) : RedwoodB it.packageName.set(packageName) } } + + override fun sharedSnapshotTests() { + project.plugins.apply("com.google.devtools.ksp") + project.dependencies.add("kspJvm", project.project(":build-support-ksp-processor")) + } } private val ziplineAttribute = Attribute.of("zipline", String::class.java) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 624bc935a9..2fbbe1b506 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,6 +5,7 @@ kotlinx-serialization = "1.7.3" androidx-activity = "1.9.2" androidx-compose-ui = "1.7.2" jbCompose = "1.6.11" +ksp = "2.0.20-1.0.25" lint = "31.6.1" paparazzi = "1.3.2" zipline = "1.17.0" @@ -16,6 +17,8 @@ kotlin-compiler = { module = "org.jetbrains.kotlin:kotlin-compiler", version.ref kotlin-compilerEmbeddable = { module = "org.jetbrains.kotlin:kotlin-compiler-embeddable", version.ref = "kotlin" } kotlin-composePlugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" } kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-kspApi = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } +kotlin-kspGradlePlugin = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" } kotlin-serializationPlugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } diff --git a/redwood-layout-shared-test/build.gradle b/redwood-layout-shared-test/build.gradle index 837f4b6dc7..a1afd1f4a0 100644 --- a/redwood-layout-shared-test/build.gradle +++ b/redwood-layout-shared-test/build.gradle @@ -2,6 +2,7 @@ import static app.cash.redwood.buildsupport.TargetGroup.ToolkitAllWithoutAndroid redwoodBuild { targets(ToolkitAllWithoutAndroid) + sharedSnapshotTests() } kotlin { diff --git a/redwood-layout-shared-test/src/commonMain/kotlin/app/cash/redwood/layout/AbstractFlexContainerTest.kt b/redwood-layout-shared-test/src/commonMain/kotlin/app/cash/redwood/layout/AbstractFlexContainerTest.kt index dd4ee56b18..fbe5f93a04 100644 --- a/redwood-layout-shared-test/src/commonMain/kotlin/app/cash/redwood/layout/AbstractFlexContainerTest.kt +++ b/redwood-layout-shared-test/src/commonMain/kotlin/app/cash/redwood/layout/AbstractFlexContainerTest.kt @@ -245,7 +245,7 @@ abstract class AbstractFlexContainerTest { snapshotter(container.value).snapshot() } - @Test fun columnWithUpdatedCrossAxisAlignment() { + @Test fun testColumnWithUpdatedCrossAxisAlignment() { val container = flexContainer(FlexDirection.Column) val snapshotter = snapshotter(container.value) container.width(Constraint.Fill) diff --git a/redwood-lazylayout-shared-test/build.gradle b/redwood-lazylayout-shared-test/build.gradle index 08566161bc..3e75798bd4 100644 --- a/redwood-lazylayout-shared-test/build.gradle +++ b/redwood-lazylayout-shared-test/build.gradle @@ -2,6 +2,7 @@ import static app.cash.redwood.buildsupport.TargetGroup.ToolkitAllWithoutAndroid redwoodBuild { targets(ToolkitAllWithoutAndroid) + sharedSnapshotTests() } kotlin { diff --git a/redwood-widget-shared-test/build.gradle b/redwood-widget-shared-test/build.gradle index fad8ab84bd..85cf8bfc4a 100644 --- a/redwood-widget-shared-test/build.gradle +++ b/redwood-widget-shared-test/build.gradle @@ -2,6 +2,7 @@ import static app.cash.redwood.buildsupport.TargetGroup.ToolkitAllWithoutAndroid redwoodBuild { targets(ToolkitAllWithoutAndroid) + sharedSnapshotTests() } kotlin { diff --git a/settings.gradle b/settings.gradle index 05d666ffc1..e1a5edf165 100644 --- a/settings.gradle +++ b/settings.gradle @@ -43,6 +43,7 @@ enableFeaturePreview('TYPESAFE_PROJECT_ACCESSORS') rootProject.name = 'redwood' +include ':build-support-ksp-processor' include ':redwood-bom' include ':redwood-compose' include ':redwood-composeui'