Skip to content

Commit

Permalink
fix passing doc string as format parameter (#1024)
Browse files Browse the repository at this point in the history
closes #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.
  • Loading branch information
brennantaylor authored Jan 22, 2021
1 parent a851521 commit 4873c3d
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ internal fun generatePropertySpecs(
}
}
fieldDefinition.description?.content?.let { kdoc ->
propertySpecBuilder.addKdoc(kdoc)
propertySpecBuilder.addKdoc("%L", kdoc)
}
propertySpecBuilder.build()
}
Original file line number Diff line number Diff line change
@@ -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<TestQuery.Result> = 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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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"
Expand Down

0 comments on commit 4873c3d

Please sign in to comment.