From 387e2e54aeb99dddac99af19a5abce09c25b363c Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Fri, 13 Jun 2025 13:49:49 +0200 Subject: [PATCH 1/5] v5 tests and compatibility --- gradle/repositories.gradle.kts | 1 + .../internal/CacheSchemaCodeGenerator.kt | 21 +++- .../internal/getMaxAges.kt | 19 ++- .../internal/ApolloVersionTest.kt | 114 ++++++++++++++++-- .../internal/GetMaxAgesTest.kt | 38 ++---- .../test-data/testProject/build.gradle.kts | 6 + .../src/main/graphql/schema.graphqls | 7 +- .../testProject/src/test/kotlin/MainTest.kt | 10 ++ 8 files changed, 168 insertions(+), 48 deletions(-) create mode 100644 normalized-cache-apollo-compiler-plugin/test-data/testProject/src/test/kotlin/MainTest.kt diff --git a/gradle/repositories.gradle.kts b/gradle/repositories.gradle.kts index ab0f8166..51fb288a 100644 --- a/gradle/repositories.gradle.kts +++ b/gradle/repositories.gradle.kts @@ -3,6 +3,7 @@ listOf(pluginManagement.repositories, dependencyResolutionManagement.repositorie // mavenLocal() // maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") // maven("https://storage.googleapis.com/apollo-previews/m2/") + mavenLocal() mavenCentral() google() gradlePluginPortal() diff --git a/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt b/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt index 505a600a..7664239e 100644 --- a/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt +++ b/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt @@ -6,7 +6,9 @@ import com.apollographql.apollo.annotations.ApolloExperimental import com.apollographql.apollo.ast.GQLDocument import com.apollographql.apollo.ast.Schema import com.apollographql.apollo.ast.toSchema +import com.apollographql.apollo.compiler.ApolloCompiler import com.apollographql.apollo.compiler.ApolloCompilerPluginEnvironment +import com.apollographql.apollo.compiler.ApolloCompilerPluginLogger import com.apollographql.apollo.compiler.SchemaCodeGenerator import com.apollographql.cache.apollocompilerplugin.VERSION import com.squareup.kotlinpoet.ClassName @@ -58,8 +60,25 @@ internal class CacheSchemaCodeGenerator( file.writeTo(outputDirectory) } + private fun ApolloCompilerPluginEnvironment.logger(): ApolloCompiler.Logger { + val method = this::class.java.methods.first { it.name == "getLogger" } + if (method.returnType.name == "com.apollographql.apollo.compiler.ApolloCompiler\$Logger") { + return method.invoke(this) as ApolloCompiler.Logger + } + + return logger.toApolloCompilerLogger() + } + + private fun ApolloCompilerPluginLogger.toApolloCompilerLogger(): ApolloCompiler.Logger { + return object : ApolloCompiler.Logger { + override fun warning(message: String) { + return this@toApolloCompilerLogger.error(message) + } + } + } + private fun maxAgeProperty(schema: Schema): PropertySpec { - val maxAges = schema.getMaxAges(environment.logger) + val maxAges = schema.getMaxAges(environment.logger()) val initializer = CodeBlock.builder().apply { add("mapOf(\n") withIndent { diff --git a/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/getMaxAges.kt b/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/getMaxAges.kt index 5c7ce88f..e9b2daca 100644 --- a/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/getMaxAges.kt +++ b/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/getMaxAges.kt @@ -11,10 +11,12 @@ import com.apollographql.apollo.ast.GQLTypeDefinition import com.apollographql.apollo.ast.Schema import com.apollographql.apollo.ast.SourceLocation import com.apollographql.apollo.ast.pretty +import com.apollographql.apollo.compiler.ApolloCompiler import com.apollographql.apollo.compiler.ApolloCompilerPluginLogger +import java.lang.reflect.Method @OptIn(ApolloExperimental::class) -internal fun Schema.getMaxAges(logger: ApolloCompilerPluginLogger): Map { +internal fun Schema.getMaxAges(logger: ApolloCompiler.Logger): Map { var hasIssues = false val typeDefinitions = this.typeDefinitions fun GQLDirective.maxAgeAndInherit(): Pair { @@ -83,9 +85,20 @@ internal fun Schema.getMaxAges(logger: ApolloCompilerPluginLogger): Map Unit): File { + val workingDir = File("build/testProject") + + workingDir.deleteRecursively() + File("test-data/testProject").copyRecursively(workingDir) + block(workingDir) + return workingDir +} + +private fun File.addBadCacheControl() { + resolve("src/main/graphql/schema.graphqls").replace("# DIRECTIVE_PLACEHOLDER", "@cacheControl(maxAge: -10)") +} + +private fun File.version(version: String) { + resolve("build.gradle.kts").replace("4.2.0", version) +} +private fun File.assertFailure(taskName: String, onFailure: (UnexpectedBuildFailure) -> Unit) { + newRunner().assertFailure(taskName, onFailure) +} + +private fun File.assertSuccess(taskName: String) { + newRunner().assertSuccess(taskName) +} + +private fun File.newRunner(): GradleRunner { + return GradleRunner.create() + .withProjectDir(this) + .withDebug(true) +} + +private fun GradleRunner.assertFailure(taskName: String, onFailure: (UnexpectedBuildFailure) -> Unit) { + try { + withArguments(taskName) + .build() + } catch (e: UnexpectedBuildFailure) { + onFailure(e) + } +} + +private fun GradleRunner.assertSuccess(taskName: String) { + withArguments(taskName) + .build().apply { + assertEquals(TaskOutcome.SUCCESS, task(":$taskName")!!.outcome) + } +} + +private fun File.replace(str: String, replacement: String) { + writeText(readText().replace(str, replacement)) } \ No newline at end of file diff --git a/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/GetMaxAgesTest.kt b/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/GetMaxAgesTest.kt index 93858946..247a7f11 100644 --- a/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/GetMaxAgesTest.kt +++ b/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/GetMaxAgesTest.kt @@ -8,6 +8,8 @@ import com.apollographql.apollo.ast.builtinForeignSchemas import com.apollographql.apollo.ast.internal.SchemaValidationOptions import com.apollographql.apollo.ast.parseAsGQLDocument import com.apollographql.apollo.ast.validateAsSchema +import com.apollographql.apollo.compiler.ApolloCompiler +import com.apollographql.apollo.compiler.ApolloCompilerPlugin import com.apollographql.apollo.compiler.ApolloCompilerPluginLogger import kotlin.test.Test import kotlin.test.assertEquals @@ -70,20 +72,8 @@ class GetMaxAgesTest { ) .getOrThrow() .getMaxAges( - object : ApolloCompilerPluginLogger { - override fun error(message: String) { - fail() - } - - override fun info(message: String) { - fail() - } - - override fun logging(message: String) { - fail() - } - - override fun warn(message: String) { + object : ApolloCompiler.Logger { + override fun warning(message: String) { fail() } } @@ -152,23 +142,11 @@ class GetMaxAgesTest { ) .getOrThrow() .getMaxAges( - object : ApolloCompilerPluginLogger { - override fun error(message: String) { - errors += message - } - - override fun info(message: String) { - fail() - } - - override fun logging(message: String) { - fail() - } - - override fun warn(message: String) { - fail() - } + object : ApolloCompiler.Logger { + override fun warning(message: String) { + fail() } + } ) } val expectedErrors = listOf( diff --git a/normalized-cache-apollo-compiler-plugin/test-data/testProject/build.gradle.kts b/normalized-cache-apollo-compiler-plugin/test-data/testProject/build.gradle.kts index b7d37123..8a935c3d 100644 --- a/normalized-cache-apollo-compiler-plugin/test-data/testProject/build.gradle.kts +++ b/normalized-cache-apollo-compiler-plugin/test-data/testProject/build.gradle.kts @@ -11,3 +11,9 @@ apollo { } } } + +dependencies { + implementation("com.apollographql.apollo:apollo-api") + implementation("com.apollographql.cache:normalized-cache") + testImplementation(libs.kotlin.test) +} \ No newline at end of file diff --git a/normalized-cache-apollo-compiler-plugin/test-data/testProject/src/main/graphql/schema.graphqls b/normalized-cache-apollo-compiler-plugin/test-data/testProject/src/main/graphql/schema.graphqls index 7c1bb33f..3a6ec7d4 100644 --- a/normalized-cache-apollo-compiler-plugin/test-data/testProject/src/main/graphql/schema.graphqls +++ b/normalized-cache-apollo-compiler-plugin/test-data/testProject/src/main/graphql/schema.graphqls @@ -1,9 +1,14 @@ +extend schema @link(url: "https://specs.apollo.dev/cache/v0.1/", import: ["@cacheControl"]) + type Query { product: Product foo: Int } -type Product @typePolicy(keyFields: "id"){ +type Product + @typePolicy(keyFields: "id") + # DIRECTIVE_PLACEHOLDER +{ id: ID! price: Float } \ No newline at end of file diff --git a/normalized-cache-apollo-compiler-plugin/test-data/testProject/src/test/kotlin/MainTest.kt b/normalized-cache-apollo-compiler-plugin/test-data/testProject/src/test/kotlin/MainTest.kt new file mode 100644 index 00000000..5d6936c1 --- /dev/null +++ b/normalized-cache-apollo-compiler-plugin/test-data/testProject/src/test/kotlin/MainTest.kt @@ -0,0 +1,10 @@ +import com.example.cache.Cache +import kotlin.test.Test +import kotlin.test.assertEquals + +class MainTest { + @Test + fun mainTest() { + assertEquals("id", Cache.typePolicies.get("Product")?.keyFields?.single()) + } +} \ No newline at end of file From 48472cc4a9806563993bcdfca1c23be54739a584 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Fri, 13 Jun 2025 13:54:17 +0200 Subject: [PATCH 2/5] remove mavenLocal(), add comment --- gradle/repositories.gradle.kts | 1 - .../internal/CacheSchemaCodeGenerator.kt | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gradle/repositories.gradle.kts b/gradle/repositories.gradle.kts index 51fb288a..ab0f8166 100644 --- a/gradle/repositories.gradle.kts +++ b/gradle/repositories.gradle.kts @@ -3,7 +3,6 @@ listOf(pluginManagement.repositories, dependencyResolutionManagement.repositorie // mavenLocal() // maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") // maven("https://storage.googleapis.com/apollo-previews/m2/") - mavenLocal() mavenCentral() google() gradlePluginPortal() diff --git a/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt b/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt index 7664239e..73da6871 100644 --- a/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt +++ b/normalized-cache-apollo-compiler-plugin/src/main/kotlin/com/apollographql/cache/apollocompilerplugin/internal/CacheSchemaCodeGenerator.kt @@ -63,6 +63,11 @@ internal class CacheSchemaCodeGenerator( private fun ApolloCompilerPluginEnvironment.logger(): ApolloCompiler.Logger { val method = this::class.java.methods.first { it.name == "getLogger" } if (method.returnType.name == "com.apollographql.apollo.compiler.ApolloCompiler\$Logger") { + /** + * The code is running on v5 where logger was converted to return directly ApolloCompiler.Logger. + * + * See https://github.com/apollographql/apollo-kotlin-normalized-cache/pull/178 + */ return method.invoke(this) as ApolloCompiler.Logger } From ebc118fbffc0c9107c5fa38424c3b9dc28b0590f Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Fri, 13 Jun 2025 14:05:02 +0200 Subject: [PATCH 3/5] restore missing import --- .../cache/apollocompilerplugin/internal/ApolloVersionTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloVersionTest.kt b/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloVersionTest.kt index 74895899..95e653af 100644 --- a/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloVersionTest.kt +++ b/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloVersionTest.kt @@ -5,6 +5,7 @@ import org.gradle.testkit.runner.TaskOutcome import org.gradle.testkit.runner.UnexpectedBuildFailure import java.io.File import kotlin.test.Test +import kotlin.test.Ignore import kotlin.test.assertEquals import kotlin.test.assertTrue From e5e820a4f4a6cc95d800a1fc2762ebf84e31d034 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Fri, 13 Jun 2025 14:25:38 +0200 Subject: [PATCH 4/5] unbreak test --- .../cache/apollocompilerplugin/internal/GetMaxAgesTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/GetMaxAgesTest.kt b/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/GetMaxAgesTest.kt index 247a7f11..79bfbd6c 100644 --- a/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/GetMaxAgesTest.kt +++ b/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/GetMaxAgesTest.kt @@ -144,7 +144,7 @@ class GetMaxAgesTest { .getMaxAges( object : ApolloCompiler.Logger { override fun warning(message: String) { - fail() + errors += message } } ) From a794893f8bb42163bc3b2573ef0ebdd6caee0930 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Fri, 13 Jun 2025 14:46:54 +0200 Subject: [PATCH 5/5] Use a local maven repo instead of included builds because included builds makes tests flakys --- build-logic/src/main/kotlin/lib.kt | 17 +++++++++++++++++ .../build.gradle.kts | 7 ++++++- .../internal/ApolloVersionTest.kt | 1 - .../test-data/testProject/build.gradle.kts | 6 ++++-- .../test-data/testProject/settings.gradle.kts | 17 +++++++++++++++-- normalized-cache-sqlite/build.gradle.kts | 2 +- normalized-cache/build.gradle.kts | 4 +--- 7 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 build-logic/src/main/kotlin/lib.kt diff --git a/build-logic/src/main/kotlin/lib.kt b/build-logic/src/main/kotlin/lib.kt new file mode 100644 index 00000000..7920d03c --- /dev/null +++ b/build-logic/src/main/kotlin/lib.kt @@ -0,0 +1,17 @@ +import com.gradleup.librarian.gradle.Librarian +import org.gradle.api.Project +import org.gradle.api.publish.PublishingExtension +import java.net.URI + +fun Project.lib() { + Librarian.module(this) + + extensions.findByType(PublishingExtension::class.java)?.apply { + repositories { + maven { + name = "local" + url = URI("file://" + rootProject.layout.buildDirectory.dir("m2").get().asFile.path) + } + } + } +} \ No newline at end of file diff --git a/normalized-cache-apollo-compiler-plugin/build.gradle.kts b/normalized-cache-apollo-compiler-plugin/build.gradle.kts index f45b9dab..f82f844c 100644 --- a/normalized-cache-apollo-compiler-plugin/build.gradle.kts +++ b/normalized-cache-apollo-compiler-plugin/build.gradle.kts @@ -4,7 +4,7 @@ plugins { id("org.jetbrains.kotlin.jvm") } -Librarian.module(project) +lib() dependencies { compileOnly(libs.apollo.compiler) @@ -14,3 +14,8 @@ dependencies { implementation(libs.kotlin.poet) testImplementation(libs.kotlin.test) } + +tasks.withType(Test::class.java).configureEach { + dependsOn("publishAllPublicationsToLocalRepository") + dependsOn(":normalized-cache:publishAllPublicationsToLocalRepository") +} \ No newline at end of file diff --git a/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloVersionTest.kt b/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloVersionTest.kt index 95e653af..13ad5074 100644 --- a/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloVersionTest.kt +++ b/normalized-cache-apollo-compiler-plugin/src/test/kotlin/com/apollographql/cache/apollocompilerplugin/internal/ApolloVersionTest.kt @@ -92,7 +92,6 @@ private fun File.assertSuccess(taskName: String) { private fun File.newRunner(): GradleRunner { return GradleRunner.create() .withProjectDir(this) - .withDebug(true) } private fun GradleRunner.assertFailure(taskName: String, onFailure: (UnexpectedBuildFailure) -> Unit) { diff --git a/normalized-cache-apollo-compiler-plugin/test-data/testProject/build.gradle.kts b/normalized-cache-apollo-compiler-plugin/test-data/testProject/build.gradle.kts index 8a935c3d..a5ec379c 100644 --- a/normalized-cache-apollo-compiler-plugin/test-data/testProject/build.gradle.kts +++ b/normalized-cache-apollo-compiler-plugin/test-data/testProject/build.gradle.kts @@ -6,7 +6,9 @@ plugins { apollo { service("service") { packageName.set("com.example") - plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin") { + // We use + as a version here to avoid having to share the version with the main build + // There is also an exclusiveContent filter installed to make sure we resolve the local artifacts + plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin:+") { argument("packageName", packageName.get()) } } @@ -14,6 +16,6 @@ apollo { dependencies { implementation("com.apollographql.apollo:apollo-api") - implementation("com.apollographql.cache:normalized-cache") + implementation("com.apollographql.cache:normalized-cache:+") testImplementation(libs.kotlin.test) } \ No newline at end of file diff --git a/normalized-cache-apollo-compiler-plugin/test-data/testProject/settings.gradle.kts b/normalized-cache-apollo-compiler-plugin/test-data/testProject/settings.gradle.kts index ffb34c0b..df2ba1f0 100644 --- a/normalized-cache-apollo-compiler-plugin/test-data/testProject/settings.gradle.kts +++ b/normalized-cache-apollo-compiler-plugin/test-data/testProject/settings.gradle.kts @@ -1,3 +1,16 @@ -apply(from = "gradle/repositories.gradle.kts") +dependencyResolutionManagement { + repositories { + exclusiveContent { + // Make sure the cache artifacts are the ones from the local maven repo + forRepository{ + maven("../../../build/m2") + } + filter { + includeGroup("com.apollographql.cache") + } + } + + mavenCentral() + } +} -includeBuild("../../..") \ No newline at end of file diff --git a/normalized-cache-sqlite/build.gradle.kts b/normalized-cache-sqlite/build.gradle.kts index 23acae2a..01371899 100644 --- a/normalized-cache-sqlite/build.gradle.kts +++ b/normalized-cache-sqlite/build.gradle.kts @@ -6,7 +6,7 @@ plugins { id("app.cash.sqldelight") } -Librarian.module(project) +lib() kotlin { configureKmp( diff --git a/normalized-cache/build.gradle.kts b/normalized-cache/build.gradle.kts index 69fafb8d..72d5cfed 100644 --- a/normalized-cache/build.gradle.kts +++ b/normalized-cache/build.gradle.kts @@ -1,11 +1,9 @@ -import com.gradleup.librarian.gradle.Librarian - plugins { id("org.jetbrains.kotlin.multiplatform") id("org.jetbrains.kotlin.plugin.atomicfu") } -Librarian.module(project) +lib() kotlin { configureKmp(