From 4873c3d2b3f4b95cbcbf2297dd973384c2929e4a Mon Sep 17 00:00:00 2001 From: Brennan Taylor Date: Fri, 22 Jan 2021 12:55:03 -0800 Subject: [PATCH] fix passing doc string as format parameter (#1024) closes https://github.com/ExpediaGroup/graphql-kotlin/issues/1023 The kotlin poet api takes as first argument a format parameter for `addKdoc()`. So comments with percent signs would cause the format argument parser to error. --- .../generateGraphQLCustomScalarTypeAlias.kt | 2 +- .../generateGraphQLCustomScalarTypeSpec.kt | 2 +- .../types/generateGraphQLEnumTypeSpec.kt | 6 +- .../generateGraphQLInputObjectTypeSpec.kt | 4 +- .../types/generateGraphQLObjectTypeSpec.kt | 2 +- .../types/generateInterfaceTypeSpec.kt | 4 +- .../generator/types/generatePropertySpecs.kt | 2 +- .../generator/types/GenerateGraphQLDocsIT.kt | 55 +++++++++++++++++++ .../src/test/resources/testSchema.graphql | 7 +++ 9 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 plugins/client/graphql-kotlin-client-generator/src/test/kotlin/com/expediagroup/graphql/plugin/client/generator/types/GenerateGraphQLDocsIT.kt diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLCustomScalarTypeAlias.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLCustomScalarTypeAlias.kt index b0e3f67ab8..3f32db8356 100755 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLCustomScalarTypeAlias.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLCustomScalarTypeAlias.kt @@ -28,7 +28,7 @@ import graphql.language.ScalarTypeDefinition internal fun generateGraphQLCustomScalarTypeAlias(context: GraphQLClientGeneratorContext, scalarTypeDefinition: ScalarTypeDefinition): TypeAliasSpec { val typeAliasSpec = TypeAliasSpec.builder(scalarTypeDefinition.name, String::class) scalarTypeDefinition.description?.content?.let { kdoc -> - typeAliasSpec.addKdoc(kdoc) + typeAliasSpec.addKdoc("%L", kdoc) } val typeAlias = typeAliasSpec.build() diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLCustomScalarTypeSpec.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLCustomScalarTypeSpec.kt index f6da43d80d..9df791c8ae 100644 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLCustomScalarTypeSpec.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLCustomScalarTypeSpec.kt @@ -41,7 +41,7 @@ internal fun generateGraphQLCustomScalarTypeSpec(context: GraphQLClientGenerator val scalarTypeSpec = TypeSpec.classBuilder(customScalarName) scalarTypeSpec.addModifiers(KModifier.DATA) scalarTypeDefinition.description?.content?.let { kdoc -> - scalarTypeSpec.addKdoc(kdoc) + scalarTypeSpec.addKdoc("%L", kdoc) } val scalarValue = PropertySpec.builder("value", converterMapping.type.toClassName()) diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLEnumTypeSpec.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLEnumTypeSpec.kt index 164ee76f51..b0776a1e46 100644 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLEnumTypeSpec.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLEnumTypeSpec.kt @@ -30,12 +30,12 @@ import graphql.language.StringValue internal fun generateGraphQLEnumTypeSpec(context: GraphQLClientGeneratorContext, enumDefinition: EnumTypeDefinition): TypeSpec { val enumTypeSpecBuilder = TypeSpec.enumBuilder(enumDefinition.name) enumDefinition.description?.content?.let { kdoc -> - enumTypeSpecBuilder.addKdoc(kdoc) + enumTypeSpecBuilder.addKdoc("%L", kdoc) } enumDefinition.enumValueDefinitions.forEach { enumValueDefinition -> val enumValueTypeSpecBuilder = TypeSpec.anonymousClassBuilder() enumValueDefinition.description?.content?.let { kdoc -> - enumValueTypeSpecBuilder.addKdoc(kdoc) + enumValueTypeSpecBuilder.addKdoc("%L", kdoc) } val deprecatedDirective = enumValueDefinition.getDirectives(DeprecatedDirective.name).firstOrNull() if (deprecatedDirective != null) { @@ -51,7 +51,7 @@ internal fun generateGraphQLEnumTypeSpec(context: GraphQLClientGeneratorContext, } val unkownTypeSpec = TypeSpec.anonymousClassBuilder() - .addKdoc("This is a default enum value that will be used when attempting to deserialize unknown value.") + .addKdoc("%L", "This is a default enum value that will be used when attempting to deserialize unknown value.") .addAnnotation(JsonEnumDefaultValue::class) .build() diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLInputObjectTypeSpec.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLInputObjectTypeSpec.kt index 5ff0e3f38d..a3b9dc5977 100644 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLInputObjectTypeSpec.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLInputObjectTypeSpec.kt @@ -31,7 +31,7 @@ internal fun generateGraphQLInputObjectTypeSpec(context: GraphQLClientGeneratorC val inputObjectTypeSpecBuilder = TypeSpec.classBuilder(inputObjectDefinition.name) inputObjectTypeSpecBuilder.modifiers.add(KModifier.DATA) inputObjectDefinition.description?.content?.let { kdoc -> - inputObjectTypeSpecBuilder.addKdoc(kdoc) + inputObjectTypeSpecBuilder.addKdoc("%L", kdoc) } val constructorBuilder = FunSpec.constructorBuilder() @@ -42,7 +42,7 @@ internal fun generateGraphQLInputObjectTypeSpec(context: GraphQLClientGeneratorC val inputPropertySpecBuilder = PropertySpec.builder(fieldName, kotlinFieldType) .initializer(fieldName) fieldDefinition.description?.content?.let { kdoc -> - inputPropertySpecBuilder.addKdoc(kdoc) + inputPropertySpecBuilder.addKdoc("%L", kdoc) } val inputPropertySpec = inputPropertySpecBuilder.build() diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLObjectTypeSpec.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLObjectTypeSpec.kt index fa559f50a8..bfab5ad562 100644 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLObjectTypeSpec.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateGraphQLObjectTypeSpec.kt @@ -43,7 +43,7 @@ internal fun generateGraphQLObjectTypeSpec( val objectTypeSpecBuilder = TypeSpec.classBuilder(typeName) objectTypeSpecBuilder.modifiers.add(KModifier.DATA) objectDefinition.description?.content?.let { kdoc -> - objectTypeSpecBuilder.addKdoc(kdoc) + objectTypeSpecBuilder.addKdoc("%L", kdoc) } val constructorBuilder = FunSpec.constructorBuilder() diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateInterfaceTypeSpec.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateInterfaceTypeSpec.kt index b466bbee58..d01be24316 100755 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateInterfaceTypeSpec.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateInterfaceTypeSpec.kt @@ -58,7 +58,7 @@ internal fun generateInterfaceTypeSpec( ): TypeSpec { val interfaceTypeSpec = TypeSpec.interfaceBuilder(interfaceName) if (kdoc != null) { - interfaceTypeSpec.addKdoc(kdoc) + interfaceTypeSpec.addKdoc("%L", kdoc) } val namedFragments = selectionSet.getSelectionsOfType(FragmentSpread::class.java).map { fragment -> @@ -163,7 +163,7 @@ private fun updateImplementationTypeSpecWithSuperInformation(context: GraphQLCli val builder = TypeSpec.classBuilder(implementationTypeSpec.name!!) builder.addModifiers(implementationTypeSpec.modifiers) - builder.addKdoc(implementationTypeSpec.kdoc) + builder.addKdoc("%L", implementationTypeSpec.kdoc) // TODO is there a better way to lookup interface class name? // - cannot use typeNameCache as it was not populated yet diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generatePropertySpecs.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generatePropertySpecs.kt index f202a70100..8ec8c93589 100755 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generatePropertySpecs.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generatePropertySpecs.kt @@ -66,7 +66,7 @@ internal fun generatePropertySpecs( } } fieldDefinition.description?.content?.let { kdoc -> - propertySpecBuilder.addKdoc(kdoc) + propertySpecBuilder.addKdoc("%L", kdoc) } propertySpecBuilder.build() } diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/kotlin/com/expediagroup/graphql/plugin/client/generator/types/GenerateGraphQLDocsIT.kt b/plugins/client/graphql-kotlin-client-generator/src/test/kotlin/com/expediagroup/graphql/plugin/client/generator/types/GenerateGraphQLDocsIT.kt new file mode 100644 index 0000000000..bac6c9ac0b --- /dev/null +++ b/plugins/client/graphql-kotlin-client-generator/src/test/kotlin/com/expediagroup/graphql/plugin/client/generator/types/GenerateGraphQLDocsIT.kt @@ -0,0 +1,55 @@ +package com.expediagroup.graphql.plugin.client.generator.types + +import com.expediagroup.graphql.plugin.client.generator.verifyGeneratedFileSpecContents +import org.junit.jupiter.api.Test + +class GenerateGraphQLDocsIT { + @Test + fun `verify docs with format params do not blow up`() { + val expected = + """ + package com.expediagroup.graphql.plugin.generator.integration + + import com.expediagroup.graphql.client.GraphQLClient + import com.expediagroup.graphql.client.execute + import com.expediagroup.graphql.types.GraphQLResponse + import kotlin.Int + import kotlin.String + + const val TEST_QUERY: String = "query TestQuery {\n docQuery {\n id\n }\n}" + + class TestQuery( + private val graphQLClient: GraphQLClient + ) { + suspend fun execute(): GraphQLResponse = graphQLClient.execute(TEST_QUERY, + "TestQuery", null) + + /** + * Doc object with % and $ floating around + */ + data class DocObject( + /** + * An id with a comment containing % and $ as well + */ + val id: Int + ) + + data class Result( + /** + * Query to test doc strings + */ + val docQuery: TestQuery.DocObject + ) + } + """.trimIndent() + val query = + """ + query TestQuery { + docQuery { + id + } + } + """.trimIndent() + verifyGeneratedFileSpecContents(query, expected) + } +} diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql b/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql index f5bac4c487..0ca455adc1 100755 --- a/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql +++ b/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql @@ -104,6 +104,8 @@ type Query { scalarQuery: ScalarWrapper! "Query returning union" unionQuery: BasicUnion! + "Query to test doc strings" + docQuery: DocObject! } "Wrapper that holds all supported scalar types" type ScalarWrapper { @@ -129,6 +131,11 @@ type SecondInterfaceImplementation implements BasicInterface { "Name of the second implementation" name: String! } +"Doc object with % and $ floating around" +type DocObject { + "An id with a comment containing % and $ as well" + id: Int! +} "Custom enum description" enum CustomEnum { "First enum value"