diff --git a/src/main/java/graphql/annotations/processor/retrievers/GraphQLObjectInfoRetriever.java b/src/main/java/graphql/annotations/processor/retrievers/GraphQLObjectInfoRetriever.java index ed3a8800..fbc611cd 100644 --- a/src/main/java/graphql/annotations/processor/retrievers/GraphQLObjectInfoRetriever.java +++ b/src/main/java/graphql/annotations/processor/retrievers/GraphQLObjectInfoRetriever.java @@ -23,7 +23,9 @@ import java.lang.reflect.Method; import java.util.Arrays; import java.util.Comparator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import static graphql.annotations.processor.util.NamingKit.toGraphqlName; @@ -36,12 +38,29 @@ public String getTypeName(Class objectClass) { return toGraphqlName(name == null ? objectClass.getSimpleName() : name.value()); } - public List getOrderedMethods(Class c) { - return Arrays.stream(c.getMethods()) + public List getOrderedMethods(Class c) { + var methods = new LinkedHashMap(); + collectMethods(c, methods); + return methods.values().stream() .sorted(Comparator.comparing(Method::getName)) .collect(Collectors.toList()); } + private void collectMethods(Class c, Map methods) { + if (c == null) { + return; + } + + Arrays.stream(c.getDeclaredMethods()) + .forEach(method -> methods.putIfAbsent(method.getName(), method)); + + for (Class iface : c.getInterfaces()) { + collectMethods(iface, methods); + } + + collectMethods(c.getSuperclass(), methods); + } + public Boolean isGraphQLField(AnnotatedElement element) { GraphQLField annotation = element.getAnnotation(GraphQLField.class); if (annotation == null) { @@ -50,5 +69,4 @@ public Boolean isGraphQLField(AnnotatedElement element) { return annotation.value(); } - } diff --git a/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java b/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java index 7e98c3f9..9ab8d4f6 100644 --- a/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java +++ b/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java @@ -96,6 +96,63 @@ public void build_Mutation_SchemaIsCreatedWithMutation() { assertThat(mutationType.getFieldDefinitions().size(), is(1)); } + public interface BaseQuery { + @GraphQLField + int baseQuery(); + } + + public interface IntermediateQuery extends BaseQuery { + @GraphQLField + int intermediateQuery(); + } + + public interface InheritedQuery extends IntermediateQuery { + @GraphQLField + int inheritedQuery(); + } + + public interface BaseMutation { + @GraphQLField + int baseMutation(); + } + + public static class ParentMutation implements BaseMutation { + @Override + public int baseMutation() { + return 6; + } + + @GraphQLField + public int parentMutation() { + return 7; + } + } + + public static class InheritedMutation extends ParentMutation { + @GraphQLField + public int inheritedMutation() { + return 8; + } + } + + @Test + public void build_QueryAndMutationWithInheritedTypes_SchemaContainsInheritedFields() { + // arrange + act + GraphQLSchema schema = builder.query(InheritedQuery.class).mutation(InheritedMutation.class).build(); + GraphQLObjectType queryType = schema.getQueryType(); + GraphQLObjectType mutationType = schema.getMutationType(); + + // assert + assertThat(queryType.getFieldDefinition("baseQuery"), notNullValue()); + assertThat(queryType.getFieldDefinition("intermediateQuery"), notNullValue()); + assertThat(queryType.getFieldDefinition("inheritedQuery"), notNullValue()); + assertThat(queryType.getFieldDefinitions().size(), is(3)); + assertThat(mutationType.getFieldDefinition("baseMutation"), notNullValue()); + assertThat(mutationType.getFieldDefinition("parentMutation"), notNullValue()); + assertThat(mutationType.getFieldDefinition("inheritedMutation"), notNullValue()); + assertThat(mutationType.getFieldDefinitions().size(), is(3)); + } + public static class SubscriptionTest { @GraphQLField public int subscribe() {