Skip to content

Commit

Permalink
Schema Builder doesn't support inheriting interface field with subtype (
Browse files Browse the repository at this point in the history
#2122)

* Add schema-builder tests

* Fix type in comment

* Define Method Ordering in TypeCreator

* Address reviews: Change Map to List of List
  • Loading branch information
zche-theScore authored Jun 6, 2024
1 parent 09aacd1 commit fb1c3f3
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package io.smallrye.graphql.schema.creator.type;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -45,28 +40,34 @@ public TypeCreator(ReferenceCreator referenceCreator, FieldCreator fieldCreator,
@Override
protected void addFields(Type type, ClassInfo classInfo, Reference reference) {
// Fields
List<MethodInfo> allMethods = new ArrayList<>();
List<List<MethodInfo>> allMethods = new LinkedList<>();
Map<String, FieldInfo> allFields = new HashMap<>();

// Find all methods and properties up the tree
for (ClassInfo c = classInfo; c != null; c = ScanningContext.getIndex().getClassByName(c.superName())) {
List<MethodInfo> listMethods = new ArrayList<>();

if (InterfaceCreator.canAddInterfaceIntoScheme(c.toString())) { // Not java objects
List<MethodInfo> classMethods = filterOutBridgeMethod(c.methods());
allMethods.addAll(classMethods);
allMethods.addAll(getAllInterfaceMethods(c, classMethods
listMethods.addAll(getAllInterfaceMethods(c, classMethods
.stream()
.map(MethodInfo::toString)
.collect(Collectors.toSet())));
listMethods.addAll(classMethods);
for (FieldInfo fieldInfo : c.fields()) {
allFields.putIfAbsent(fieldInfo.name(), fieldInfo);
}
}

allMethods.add(0, listMethods);
}
for (MethodInfo methodInfo : allMethods) {
if (MethodHelper.isPropertyMethod(Direction.OUT, methodInfo)) {
String fieldName = MethodHelper.getPropertyName(Direction.OUT, methodInfo.name());
FieldInfo fieldInfo = allFields.remove(fieldName);
fieldCreator.createFieldForPojo(Direction.OUT, fieldInfo, methodInfo, reference).ifPresent(type::addField);
for (List<MethodInfo> listMethods : allMethods) {
for (MethodInfo methodInfo : listMethods) {
if (MethodHelper.isPropertyMethod(Direction.OUT, methodInfo)) {
String fieldName = MethodHelper.getPropertyName(Direction.OUT, methodInfo.name());
FieldInfo fieldInfo = allFields.remove(fieldName);
fieldCreator.createFieldForPojo(Direction.OUT, fieldInfo, methodInfo, reference).ifPresent(type::addField);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,28 @@ public void testSchemaWithBatchSourceFieldNameDuplicates() {
}
}

@Test
public void testSchemaWithInheritFieldBySubtype() {
Indexer indexer = new Indexer();
indexDirectory(indexer, "io/smallrye/graphql/index/inherit/");

IndexView index = indexer.complete();
Schema schema = SchemaBuilder.build(index);
// Get Types
Map<String, Type> types = schema.getTypes();
Map<String, Type> interfaces = schema.getInterfaces();
Type containerType = types.get("ContainerType");
Field containerTypeField = containerType.getFields().get("inheritField");
Type containerInterface = interfaces.get("ContainerInterface");
Field containerInterfaceField = containerInterface.getFields().get("inheritField");

// Should be FieldType according to GraphQL Spec: https://spec.graphql.org/October2021/#sec-Objects.Type-Validation
assertEquals("io.smallrye.graphql.index.inherit.FieldType",
containerTypeField.getReference().getClassName());
assertEquals("io.smallrye.graphql.index.inherit.FieldInterface",
containerInterfaceField.getReference().getClassName());
}

@Test
public void testSchemaWithDirectives() throws IOException {
Indexer indexer = new Indexer();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.smallrye.graphql.index.inherit;

public interface ContainerInterface {
FieldInterface getInheritField();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.smallrye.graphql.index.inherit;

public class ContainerType implements ContainerInterface {

public FieldType getInheritField() {
return new FieldType();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.smallrye.graphql.index.inherit;

public interface FieldInterface {
String getVal();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.smallrye.graphql.index.inherit;

public class FieldType implements FieldInterface {
public String getVal() {
return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.smallrye.graphql.index.inherit;

import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Query;

@GraphQLApi
public class InheritAPI {
@Query
public ContainerInterface getContainer() {
return null;
}
}

0 comments on commit fb1c3f3

Please sign in to comment.