Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions src/main/java/graphql/schema/GraphQLInterfaceType.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package graphql.schema;

import com.google.common.collect.ImmutableList;
import graphql.Assert;
import graphql.AssertException;
import graphql.DirectivesUtil;
import graphql.Internal;
Expand All @@ -20,7 +21,6 @@

import static graphql.Assert.assertNotNull;
import static graphql.Assert.assertValidName;
import static graphql.schema.GraphqlTypeComparators.asIsOrder;
import static graphql.schema.GraphqlTypeComparators.sortTypes;
import static graphql.util.FpKit.getByName;
import static graphql.util.FpKit.valuesToList;
Expand Down Expand Up @@ -200,7 +200,7 @@ public GraphQLInterfaceType withNewChildren(SchemaElementChildrenContainer newCh
return transform(builder ->
builder.replaceDirectives(newChildren.getChildren(CHILD_DIRECTIVES))
.replaceFields(newChildren.getChildren(CHILD_FIELD_DEFINITIONS))
.replaceInterfaces(newChildren.getChildren(CHILD_INTERFACES))
.replaceInterfacesOrReferences(newChildren.getChildren(CHILD_INTERFACES))
);
}

Expand Down Expand Up @@ -401,21 +401,29 @@ public Builder clearDirectives() {
return this;
}

public Builder withInterface(GraphQLInterfaceType interfaceType) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shifting this down to be adjacent to the other withInterface method

assertNotNull(interfaceType, () -> "interfaceType can't be null");
this.interfaces.put(interfaceType.getName(), interfaceType);
return this;
public Builder replaceInterfaces(List<GraphQLInterfaceType> interfaces) {
return replaceInterfacesOrReferences(interfaces);
}

public Builder replaceInterfaces(List<GraphQLInterfaceType> interfaces) {
assertNotNull(interfaces, () -> "interfaces can't be null");
public Builder replaceInterfacesOrReferences(List<? extends GraphQLNamedOutputType> interfacesOrReferences) {
assertNotNull(interfacesOrReferences, () -> "interfaces can't be null");
this.interfaces.clear();
for (GraphQLInterfaceType interfaceType : interfaces) {
this.interfaces.put(interfaceType.getName(), interfaceType);
for (GraphQLNamedOutputType schemaElement : interfacesOrReferences) {
if (schemaElement instanceof GraphQLInterfaceType || schemaElement instanceof GraphQLTypeReference) {
this.interfaces.put(schemaElement.getName(), schemaElement);
} else {
Assert.assertShouldNeverHappen("Unexpected type " + (schemaElement != null ? schemaElement.getClass() : "null"));
}
}
return this;
}

public Builder withInterface(GraphQLInterfaceType interfaceType) {
assertNotNull(interfaceType, () -> "interfaceType can't be null");
this.interfaces.put(interfaceType.getName(), interfaceType);
return this;
}

public Builder withInterface(GraphQLTypeReference reference) {
assertNotNull(reference, () -> "reference can't be null");
this.interfaces.put(reference.getName(), reference);
Expand All @@ -429,6 +437,12 @@ public Builder withInterfaces(GraphQLInterfaceType... interfaceType) {
return this;
}

public Builder withInterfaces(GraphQLTypeReference... references) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add for completeness

for (GraphQLTypeReference reference : references) {
withInterface(reference);
}
return this;
}

public GraphQLInterfaceType build() {
return new GraphQLInterfaceType(
Expand Down
48 changes: 48 additions & 0 deletions src/test/groovy/graphql/schema/GraphQLInterfaceTypeTest.groovy
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package graphql.schema

import graphql.util.TraversalControl
import graphql.util.TraverserContext
import spock.lang.Specification

import static graphql.Scalars.GraphQLBoolean
import static graphql.Scalars.GraphQLInt
import static graphql.Scalars.GraphQLString
import static graphql.schema.GraphQLCodeRegistry.newCodeRegistry
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition
import static graphql.schema.GraphQLInterfaceType.newInterface
import static graphql.schema.GraphQLObjectType.newObject
import static graphql.schema.GraphQLSchema.newSchema
import static graphql.schema.GraphQLTypeReference.typeRef

class GraphQLInterfaceTypeTest extends Specification {

Expand Down Expand Up @@ -59,4 +65,46 @@ class GraphQLInterfaceTypeTest extends Specification {
objectType2.getFieldDefinition("Str").getType() == GraphQLBoolean
}

def "schema transformer accepts interface with type reference"() {
given:
def iFace = newInterface().name("iFace")
.field(builder -> builder.type(GraphQLString).name("field"))
.withInterface(typeRef("iFace2"))
.build()

def iFace2 = newInterface().name("iFace2")
.field(builder -> builder.type(GraphQLString).name("field"))
.build()

def impl = newObject().name("impl")
.field(builder -> builder.type(GraphQLString).name("field"))
.withInterfaces(typeRef("iFace"))
.withInterfaces(typeRef("iFace2"))
.build()

def codeRegBuilder = newCodeRegistry().typeResolver(iFace, env -> impl)
.typeResolver(iFace2, env -> impl)

def schema = newSchema()
.codeRegistry(codeRegBuilder.build())
.additionalType(iFace).additionalType(iFace2)
.query(newObject()
.name("test")
.field(builder -> builder.name("iFaceField").type(impl))
).build()

when:
SchemaTransformer.transformSchema(schema, new GraphQLTypeVisitorStub() {
@Override
TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext<GraphQLSchemaElement> context) {
GraphQLFieldDefinition transform = node.transform(
builder -> builder.argument(builder1 -> builder1.name("arg").type(GraphQLString)))
changeNode(context, transform)
return super.visitGraphQLFieldDefinition(node, context)
}
})

then:
noExceptionThrown()
}
}