From 8bbb7bc755470ecb45e267b7b7ab07cfd6a7a1d0 Mon Sep 17 00:00:00 2001 From: Tobias Kammerer Date: Mon, 15 Feb 2021 20:05:34 +0100 Subject: [PATCH 1/3] interface type can have non-empty interface lists --- .../graphql/kickstart/tools/SchemaParser.kt | 5 ++ .../kickstart/tools/SchemaParserSpec.groovy | 66 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt b/src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt index c93fccab..ee1d217a 100644 --- a/src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt +++ b/src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt @@ -234,6 +234,11 @@ class SchemaParser internal constructor( builder.field { field -> createField(field, fieldDefinition, inputObjects) } } + interfaceDefinition.implements.forEach { implementsDefinition -> + val interfaceName = (implementsDefinition as TypeName).name + builder.withInterface(GraphQLTypeReference(interfaceName)) + } + return schemaGeneratorDirectiveHelper.onInterface(builder.build(), schemaDirectiveParameters) } diff --git a/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy b/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy index d141a903..0b3c7e9e 100644 --- a/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy +++ b/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy @@ -2,6 +2,7 @@ package graphql.kickstart.tools import graphql.kickstart.tools.resolver.FieldResolverError import graphql.language.SourceLocation +import graphql.schema.GraphQLInterfaceType import graphql.schema.GraphQLSchema import org.springframework.aop.framework.ProxyFactory import spock.lang.Specification @@ -418,6 +419,71 @@ class SchemaParserSpec extends Specification { noExceptionThrown() } + def "interface implementing an interface should have non-empty interface list"() { + when: + GraphQLSchema schema = SchemaParser.newParser().schemaString('''\ + interface Trait { + id: ID! + } + interface MammalTrait implements Trait { + id: ID! + } + type PoodleTrait implements Trait & MammalTrait { + id: ID! + } + + interface Animal { + id: ID! + traits: [Trait] + } + interface Dog implements Animal { + id: ID! + traits: [MammalTrait] + } + type Poodle implements Animal & Dog { + id: ID! + traits: [PoodleTrait] + } + + type Query { test: [Poodle] }'''.stripIndent()) + .resolvers(new GraphQLQueryResolver() { + static abstract class Trait { + String id; + } + + static abstract class MammalTrait extends Trait { + String id; + } + + static class PoodleTrait extends MammalTrait { + String id; + } + + static abstract class Animal { + String id; + abstract List traits; + } + + static abstract class Dog extends Animal { + abstract List traits; + } + + static class Poodle extends Dog { + List traits; + } + + List test() { return new ArrayList(); } + }) + .build() + .makeExecutableSchema() + GraphQLInterfaceType traitInterface = schema.getType("MammalTrait") as GraphQLInterfaceType + GraphQLInterfaceType dogInterface = schema.getType("Dog") as GraphQLInterfaceType + + then: + !traitInterface.interfaces.empty + !dogInterface.interfaces.empty + } + enum EnumType { TEST } From 30418ba1853a597659e7a8232773c36d48c104b4 Mon Sep 17 00:00:00 2001 From: Tobias Kammerer Date: Tue, 16 Feb 2021 19:56:14 +0100 Subject: [PATCH 2/3] integrated PR comments --- .../kickstart/tools/SchemaParserSpec.groovy | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy b/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy index 0b3c7e9e..08cbb001 100644 --- a/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy +++ b/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy @@ -3,6 +3,7 @@ package graphql.kickstart.tools import graphql.kickstart.tools.resolver.FieldResolverError import graphql.language.SourceLocation import graphql.schema.GraphQLInterfaceType +import graphql.schema.GraphQLObjectType import graphql.schema.GraphQLSchema import org.springframework.aop.framework.ProxyFactory import spock.lang.Specification @@ -445,7 +446,8 @@ class SchemaParserSpec extends Specification { traits: [PoodleTrait] } - type Query { test: [Poodle] }'''.stripIndent()) + type Query { test: [Poodle] } + '''.stripIndent()) .resolvers(new GraphQLQueryResolver() { static abstract class Trait { String id; @@ -476,12 +478,20 @@ class SchemaParserSpec extends Specification { }) .build() .makeExecutableSchema() - GraphQLInterfaceType traitInterface = schema.getType("MammalTrait") as GraphQLInterfaceType + GraphQLInterfaceType traitInterface = schema.getType("Trait") as GraphQLInterfaceType + GraphQLInterfaceType animalInterface = schema.getType("Animal") as GraphQLInterfaceType + GraphQLInterfaceType mammalTraitInterface = schema.getType("MammalTrait") as GraphQLInterfaceType GraphQLInterfaceType dogInterface = schema.getType("Dog") as GraphQLInterfaceType + GraphQLObjectType poodleObject = schema.getType("Poodle") as GraphQLObjectType + GraphQLObjectType poodleTraitObject = schema.getType("PoodleTrait") as GraphQLObjectType then: - !traitInterface.interfaces.empty - !dogInterface.interfaces.empty + poodleObject.interfaces.containsAll([dogInterface, animalInterface]) + poodleTraitObject.interfaces.containsAll([mammalTraitInterface, traitInterface]) + dogInterface.interfaces.contains(animalInterface) + mammalTraitInterface.interfaces.contains(traitInterface) + traitInterface.interfaces.empty + animalInterface.interfaces.empty } enum EnumType { From 9dce44da28ad650c61991578d20664581392a150 Mon Sep 17 00:00:00 2001 From: Oryan M Date: Fri, 5 Mar 2021 12:56:25 -0500 Subject: [PATCH 3/3] Add test back after merge --- .../kickstart/tools/SchemaParserSpec.groovy | 0 .../kickstart/tools/SchemaParserTest.kt | 77 +++++++++++++++++++ 2 files changed, 77 insertions(+) delete mode 100644 src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy diff --git a/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy b/src/test/groovy/graphql/kickstart/tools/SchemaParserSpec.groovy deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/kotlin/graphql/kickstart/tools/SchemaParserTest.kt b/src/test/kotlin/graphql/kickstart/tools/SchemaParserTest.kt index 06854b6d..3b6c3783 100644 --- a/src/test/kotlin/graphql/kickstart/tools/SchemaParserTest.kt +++ b/src/test/kotlin/graphql/kickstart/tools/SchemaParserTest.kt @@ -1,6 +1,8 @@ package graphql.kickstart.tools import graphql.kickstart.tools.resolver.FieldResolverError +import graphql.schema.GraphQLInterfaceType +import graphql.schema.GraphQLObjectType import org.junit.Before import org.junit.Rule import org.junit.Test @@ -402,6 +404,81 @@ class SchemaParserTest { .makeExecutableSchema() } + @Test + fun `interface implementing an interface should have non-empty interface list`() { + val schema = SchemaParser.newParser() + .schemaString( + """ + interface Trait { + id: ID! + } + interface MammalTrait implements Trait { + id: ID! + } + type PoodleTrait implements Trait & MammalTrait { + id: ID! + } + + interface Animal { + id: ID! + traits: [Trait] + } + interface Dog implements Animal { + id: ID! + traits: [MammalTrait] + } + type Poodle implements Animal & Dog { + id: ID! + traits: [PoodleTrait] + } + + type Query { test: [Poodle] } + """) + .resolvers(MultiLevelInterfaceResolver()) + .build() + .makeExecutableSchema() + val traitInterface = schema.getType("Trait") as GraphQLInterfaceType + val animalInterface = schema.getType("Animal") as GraphQLInterfaceType + val mammalTraitInterface = schema.getType("MammalTrait") as GraphQLInterfaceType + val dogInterface = schema.getType("Dog") as GraphQLInterfaceType + val poodleObject = schema.getType("Poodle") as GraphQLObjectType + val poodleTraitObject = schema.getType("PoodleTrait") as GraphQLObjectType + + assert(poodleObject.interfaces.containsAll(listOf(dogInterface, animalInterface))) + assert(poodleTraitObject.interfaces.containsAll(listOf(mammalTraitInterface, traitInterface))) + assert(dogInterface.interfaces.contains(animalInterface)) + assert(mammalTraitInterface.interfaces.contains(traitInterface)) + assert(traitInterface.definition.implements.isEmpty()) + assert(animalInterface.definition.implements.isEmpty()) + } + + class MultiLevelInterfaceResolver : GraphQLQueryResolver { + fun test(): List = listOf() + + interface Trait { + var id: String + } + + interface MammalTrait : Trait { + override var id: String + } + + interface PoodleTrait : MammalTrait { + override var id: String + } + + abstract class Animal { + var id: String? = null + abstract var traits: List + } + + abstract class Dog : Animal() { + abstract override var traits: List + } + + class Poodle(override var traits: List) : Dog() + } + enum class EnumType { TEST }