Skip to content

Commit

Permalink
Merge branch 'Netflix:master' into feature/389-cusomt-generated-class…
Browse files Browse the repository at this point in the history
…-name-templates
  • Loading branch information
BlasiusSecundus authored Jun 20, 2023
2 parents 2cb13d9 + f890f36 commit 938bf05
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ class InterfaceGenerator(private val config: CodeGenConfig, private val document
.filter { node -> node.implements.any { it.isEqualTo(TypeName(definition.name)) } }
.map { node ->
val nodeName = if (config.generateInterfaces) "I${node.name}" else node.name
ClassName.get(packageName, nodeName)
typeUtils.findJavaInterfaceName(nodeName, packageName)
}
.filterIsInstance<ClassName>()
.toList()

if (implementations.isNotEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ class KotlinInterfaceTypeGenerator(private val config: CodeGenConfig, private va

val implementations = document.getDefinitionsOfType(ObjectTypeDefinition::class.java).asSequence()
.filter { node -> node.implements.any { it.isEqualTo(TypeName(definition.name)) } }
.map { node -> ClassName(packageName, node.name) }
.map { node -> typeUtils.findKtInterfaceName(node.name, packageName) }
.filterIsInstance<ClassName>()
.toList()

if (implementations.isNotEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,61 @@ class CodeGenTest {
assertThat(dataTypes[0].typeSpec.fieldSpecs[0].type.toString()).isEqualTo("mypackage.Person")
}

@Test
fun `Use mapped type name when the type implements not-mapped interface`() {
val schema = """
interface Pet {
name: ID!
}
type Cat implements Pet {
name: ID!
}
type Dog implements Pet {
name: ID!
}
""".trimIndent()

val codeGenResult = CodeGen(
CodeGenConfig(
schemas = setOf(schema),
packageName = basePackageName,
language = Language.JAVA,
typeMapping = mapOf(
"Cat" to "mypackage.Cat"
)
)
).generate()
val interfaces = codeGenResult.javaInterfaces

assertThat(interfaces.size).isEqualTo(1)
assertThat(interfaces[0].toString()).isEqualTo(
"""
|package com.netflix.graphql.dgs.codegen.tests.generated.types;
|
|import com.fasterxml.jackson.annotation.JsonSubTypes;
|import com.fasterxml.jackson.annotation.JsonTypeInfo;
|import java.lang.String;
|import mypackage.Cat;
|
|@JsonTypeInfo(
| use = JsonTypeInfo.Id.NAME,
| include = JsonTypeInfo.As.PROPERTY,
| property = "__typename"
|)
|@JsonSubTypes({
| @JsonSubTypes.Type(value = Cat.class, name = "Cat"),
| @JsonSubTypes.Type(value = Dog.class, name = "Dog")
|})
|public interface Pet {
| String getName();
|
| void setName(String name);
|}
|
""".trimMargin()
)
}

@Test
fun `Use mapped type name when the type is mapped for interface`() {
val schema = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,61 @@ class KotlinCodeGenTest {
assertThat((dataTypes[0].members[0] as TypeSpec).propertySpecs[0].type.toString()).isEqualTo("mypackage.Person?")
}

@Test
fun `Use mapped type name when the type implements not-mapped interface`() {
val schema = """
interface Pet {
name: ID!
}
type Cat implements Pet {
name: ID!
}
type Dog implements Pet {
name: ID!
}
""".trimIndent()

val codeGenResult = CodeGen(
CodeGenConfig(
schemas = setOf(schema),
packageName = basePackageName,
language = Language.KOTLIN,
typeMapping = mapOf(
"Cat" to "mypackage.Cat"
)
)
).generate()
val interfaces = codeGenResult.kotlinInterfaces

assertThat(interfaces.size).isEqualTo(1)
assertThat(interfaces[0].toString()).isEqualTo(
"""
|package com.netflix.graphql.dgs.codegen.tests.generated.types
|
|import com.fasterxml.jackson.`annotation`.JsonSubTypes
|import com.fasterxml.jackson.`annotation`.JsonTypeInfo
|import kotlin.String
|import mypackage.Cat
|
|@JsonTypeInfo(
| use = JsonTypeInfo.Id.NAME,
| include = JsonTypeInfo.As.PROPERTY,
| property = "__typename",
|)
|@JsonSubTypes(value = [
| JsonSubTypes.Type(value = Cat::class, name = "Cat"),
| JsonSubTypes.Type(value = Dog::class, name = "Dog")
|])
|public interface Pet {
| public val name: String
|
| public companion object
|}
|
""".trimMargin()
)
}

class MappedTypesTestCases : ArgumentsProvider {
override fun provideArguments(context: ExtensionContext): Stream<out Arguments> = of(
arguments("java.time.LocalDateTime", "java.time.LocalDateTime"),
Expand Down
1 change: 1 addition & 0 deletions graphql-dgs-codegen-gradle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ apply plugin: 'java-gradle-plugin'

dependencies {
api project(":graphql-dgs-codegen-core")
compileOnly "com.netflix.nebula:gradle-dependency-lock-plugin:latest.release"
compileOnly "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.KOTLIN_VERSION}"

testApi gradleTestKit()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.netflix.graphql.dgs.codegen.gradle

import nebula.plugin.dependencylock.DependencyLockExtension
import org.gradle.api.Project
import org.gradle.api.logging.Logging
import java.io.FileNotFoundException
Expand All @@ -29,6 +30,7 @@ object ClientUtilsConventions {

private const val CLIENT_UTILS_ARTIFACT_GROUP = "com.netflix.graphql.dgs.codegen"
private const val CLIENT_UTILS_ARTIFACT_NAME = "graphql-dgs-codegen-shared-core"
private const val CLIENT_UTILS_NEBULA_LOCK_ID = "com.netflix.nebula.dependency-lock"

private val logger = Logging.getLogger(ClientUtilsConventions::class.java)

Expand All @@ -38,10 +40,23 @@ object ClientUtilsConventions {
optionalCodeClientDependencyScope: Optional<String> = Optional.empty()
) {
clientCoreArtifact(optionalCodeUtilsVersion).ifPresent { dependencyString ->
val dependencyLockString = dependencyString.split(":").take(2).joinToString(":")

val dependencyConfiguration = optionalCodeClientDependencyScope.orElse(GRADLE_CLASSPATH_CONFIGURATION)
val configurationDependencies = project.configurations.getByName(dependencyConfiguration).dependencies
configurationDependencies.add(project.dependencies.create(dependencyString))
logger.info("DGS CodeGen added [{}] to the {} dependencies.", dependencyString, dependencyConfiguration)

project.dependencyLocking.ignoredDependencies.add(dependencyLockString)
logger.info("DGS CodeGen added [{}] to the ignoredDependencies.", dependencyLockString, dependencyConfiguration)

project.plugins.withId(CLIENT_UTILS_NEBULA_LOCK_ID) {
val extension = project.extensions.getByType(DependencyLockExtension::class.java)
if (extension != null) {
extension.skippedDependencies.add(dependencyLockString)
logger.info("DGS CodeGen added [{}] to the skippedDependencies.", dependencyLockString, dependencyConfiguration)
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class GraphQLQueryRequest @JvmOverloads constructor(
class GraphQLQueryRequestOptions(val scalars: Map<Class<*>, Coercing<*, *>> = emptyMap()) {
// When enabled, input values that are derived from properties
// whose values are null will be serialized in the query request
val allowNullablePropertyInputValues = false
var allowNullablePropertyInputValues = false
}

val inputValueSerializer =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.netflix.graphql.dgs.client.codegen

import com.netflix.graphql.dgs.client.codegen.GraphQLQueryRequest.GraphQLQueryRequestOptions
import com.netflix.graphql.dgs.client.codegen.exampleprojection.EntitiesProjectionRoot
import graphql.language.OperationDefinition
import graphql.language.StringValue
Expand Down Expand Up @@ -379,6 +380,28 @@ class GraphQLQueryRequestTest {
)
}

@Test
fun serializeWithNullableInputValueSerializer() {
val query = TestGraphQLQuery().apply {
input["movie"] = Movie(1234, "name", null)
}
val options = GraphQLQueryRequestOptions().apply {
allowNullablePropertyInputValues = true
}
val request = GraphQLQueryRequest(query, MovieProjection().name().movieId(), options)
val result = request.serialize()
assertValidQuery(result)
assertThat(result).isEqualTo(
"""{
| test(movie: {movieId : 1234, name : "name", window : null}) {
| name
| movieId
| }
|}
""".trimMargin()
)
}

/**
* Assert that the GraphQL query is syntactically valid.
*/
Expand Down

0 comments on commit 938bf05

Please sign in to comment.