Skip to content

Commit dd42897

Browse files
committed
added argument support to graphql schema checking on interfaces
1 parent 3ffe2fb commit dd42897

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

src/main/java/graphql/schema/validation/ObjectsImplementInterfaces.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package graphql.schema.validation;
22

3+
import graphql.schema.GraphQLArgument;
34
import graphql.schema.GraphQLFieldDefinition;
45
import graphql.schema.GraphQLInterfaceType;
56
import graphql.schema.GraphQLObjectType;
@@ -63,9 +64,42 @@ private void checkFieldTypeEquivalence(GraphQLObjectType objectTyoe, GraphQLInte
6364
validationErrorCollector.addError(
6465
error(format("object type '%s' does not implement interface '%s' because field '%s' is defined as '%s' type and not as '%s' type",
6566
objectTyoe.getName(), interfaceType.getName(), interfaceFieldDef.getName(), objectFieldDefStr, interfaceFieldDefStr)));
67+
} else {
68+
checkFieldArgumentEquivalence(objectTyoe, interfaceType, validationErrorCollector, interfaceFieldDef, objectFieldDef);
6669
}
6770
}
6871

72+
private void checkFieldArgumentEquivalence(GraphQLObjectType objectTyoe, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector, GraphQLFieldDefinition interfaceFieldDef, GraphQLFieldDefinition objectFieldDef) {
73+
List<GraphQLArgument> interfaceArgs = interfaceFieldDef.getArguments();
74+
List<GraphQLArgument> objectArgs = objectFieldDef.getArguments();
75+
if (interfaceArgs.size() != objectArgs.size()) {
76+
validationErrorCollector.addError(
77+
error(format("object type '%s' does not implement interface '%s' because field '%s' has a different number of arguments",
78+
objectTyoe.getName(), interfaceType.getName(), interfaceFieldDef.getName())));
79+
} else {
80+
for (int i = 0; i < interfaceArgs.size(); i++) {
81+
GraphQLArgument interfaceArg = interfaceArgs.get(i);
82+
GraphQLArgument objectArg = objectArgs.get(i);
83+
84+
String interfaceArgStr = makeArgStr(interfaceArg);
85+
String objectArgStr = makeArgStr(objectArg);
86+
87+
if (!interfaceArgStr.equals(objectArgStr)) {
88+
validationErrorCollector.addError(
89+
error(format("object type '%s' does not implement interface '%s' because field '%s' argument '%s' is defined differently",
90+
objectTyoe.getName(), interfaceType.getName(), interfaceFieldDef.getName(), interfaceArg.getName())));
91+
}
92+
}
93+
}
94+
}
95+
96+
private String makeArgStr(GraphQLArgument argument) {
97+
return argument.getName() +
98+
":" +
99+
getUnwrappedTypeName(argument.getType());
100+
101+
}
102+
69103
private SchemaValidationError error(String msg) {
70104
return new SchemaValidationError(ObjectDoesNotImplementItsInterfaces, msg);
71105
}

src/test/groovy/graphql/schema/validation/ObjectsImplementInterfacesTest.groovy

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import graphql.schema.GraphQLObjectType
66
import graphql.schema.TypeResolver
77
import spock.lang.Specification
88

9-
import static graphql.Scalars.GraphQLInt
10-
import static graphql.Scalars.GraphQLString
9+
import static SchemaValidationErrorType.ObjectDoesNotImplementItsInterfaces
10+
import static graphql.Scalars.*
11+
import static graphql.schema.GraphQLArgument.newArgument
1112
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition
1213
import static graphql.schema.GraphQLInterfaceType.newInterface
1314
import static graphql.schema.GraphQLList.list
1415
import static graphql.schema.GraphQLNonNull.nonNull
15-
import static SchemaValidationErrorType.ObjectDoesNotImplementItsInterfaces
1616

1717
class ObjectsImplementInterfacesTest extends Specification {
1818

@@ -30,6 +30,18 @@ class ObjectsImplementInterfacesTest extends Specification {
3030
.field(newFieldDefinition().name("friends").type(list(GraphQLString)))
3131
.field(newFieldDefinition().name("age").type(GraphQLInt))
3232
.field(newFieldDefinition().name("address").type(list(GraphQLString)))
33+
34+
.field(newFieldDefinition().name("argField1").type(GraphQLString)
35+
.argument(newArgument().name("arg1").type(GraphQLString))
36+
.argument(newArgument().name("arg2").type(GraphQLInt))
37+
.argument(newArgument().name("arg3").type(GraphQLBoolean))
38+
)
39+
40+
.field(newFieldDefinition().name("argField2").type(GraphQLString)
41+
.argument(newArgument().name("arg1").type(GraphQLString))
42+
.argument(newArgument().name("arg2").type(GraphQLInt))
43+
.argument(newArgument().name("arg3").type(GraphQLBoolean))
44+
)
3345
.typeResolver(typeResolver)
3446
.build()
3547

@@ -44,6 +56,17 @@ class ObjectsImplementInterfacesTest extends Specification {
4456
.field(newFieldDefinition().name("missing").type(list(GraphQLString)))
4557
.field(newFieldDefinition().name("age").type(GraphQLString))
4658
.field(newFieldDefinition().name("address").type(list(nonNull(GraphQLString))))
59+
60+
.field(newFieldDefinition().name("argField1").type(GraphQLString)
61+
.argument(newArgument().name("arg1").type(GraphQLInt))
62+
.argument(newArgument().name("arg2").type(GraphQLInt))
63+
.argument(newArgument().name("arg3").type(GraphQLInt))
64+
)
65+
66+
.field(newFieldDefinition().name("argField2").type(GraphQLString)
67+
.argument(newArgument().name("arg1").type(GraphQLString))
68+
)
69+
4770
.build()
4871

4972
when:
@@ -53,12 +76,18 @@ class ObjectsImplementInterfacesTest extends Specification {
5376

5477
errorCollector.containsValidationError(ObjectDoesNotImplementItsInterfaces)
5578
def errors = errorCollector.getErrors()
56-
errors.size() == 3
79+
errors.size() == 6
5780
errors.contains(new SchemaValidationError(ObjectDoesNotImplementItsInterfaces,
5881
"object type 'obj' does not implement interface 'Interface' because field 'friends' is missing"))
5982
errors.contains(new SchemaValidationError(ObjectDoesNotImplementItsInterfaces,
6083
"object type 'obj' does not implement interface 'Interface' because field 'age' is defined as 'String' type and not as 'Int' type"))
6184
errors.contains(new SchemaValidationError(ObjectDoesNotImplementItsInterfaces,
6285
"object type 'obj' does not implement interface 'Interface' because field 'address' is defined as '[String!]' type and not as '[String]' type"))
86+
errors.contains(new SchemaValidationError(ObjectDoesNotImplementItsInterfaces,
87+
"object type 'obj' does not implement interface 'Interface' because field 'address' is defined as '[String!]' type and not as '[String]' type"))
88+
errors.contains(new SchemaValidationError(ObjectDoesNotImplementItsInterfaces,
89+
"object type 'obj' does not implement interface 'Interface' because field 'argField1' argument 'arg1' is defined differently"))
90+
errors.contains(new SchemaValidationError(ObjectDoesNotImplementItsInterfaces,
91+
"object type 'obj' does not implement interface 'Interface' because field 'argField2' has a different number of arguments"))
6392
}
6493
}

0 commit comments

Comments
 (0)