From c70aeb7ef7dfff7e126b16543380676c88a06c39 Mon Sep 17 00:00:00 2001 From: Vlastimil Elias Date: Mon, 31 Aug 2020 14:00:15 +0200 Subject: [PATCH] #281 - added test for mutation and some assertions for generated schema --- .../schema/creator/ReferenceCreator.java | 115 +++++++++++------- .../ClassWithOneGenericsParamToString2.java | 8 ++ .../test_generics/ClassWithoutGenerics.java | 2 +- .../test_generics/ControllerWithGenerics.java | 39 +++--- .../schema/test_generics/GenericsTest.java | 33 +++-- 5 files changed, 127 insertions(+), 70 deletions(-) create mode 100644 common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ClassWithOneGenericsParamToString2.java diff --git a/common/schema-builder/src/main/java/io/smallrye/graphql/schema/creator/ReferenceCreator.java b/common/schema-builder/src/main/java/io/smallrye/graphql/schema/creator/ReferenceCreator.java index 1d6679100..89dbb10bd 100644 --- a/common/schema-builder/src/main/java/io/smallrye/graphql/schema/creator/ReferenceCreator.java +++ b/common/schema-builder/src/main/java/io/smallrye/graphql/schema/creator/ReferenceCreator.java @@ -118,7 +118,8 @@ public Reference createReferenceForSourceArgument(Type argumentType, Annotations * @param annotationsForThisMethod annotations on this method * @return a reference to the type */ - public Reference createReferenceForInterfaceField(Type methodType, Annotations annotationsForThisMethod, Reference parentObjectReference) { + public Reference createReferenceForInterfaceField(Type methodType, Annotations annotationsForThisMethod, + Reference parentObjectReference) { return getReference(Direction.OUT, null, methodType, annotationsForThisMethod, parentObjectReference); } @@ -134,7 +135,8 @@ public Reference createReferenceForInterfaceField(Type methodType, Annotations a * @param parentObjectReference Reference of the parent PoJo use so we can evaluate generics types * @return a reference to the type */ - public Reference createReferenceForPojoField(Direction direction, Type fieldType, Type methodType, Annotations annotations, Reference parentObjectReference) { + public Reference createReferenceForPojoField(Direction direction, Type fieldType, Type methodType, Annotations annotations, + Reference parentObjectReference) { return getReference(direction, fieldType, methodType, annotations, parentObjectReference); } @@ -156,10 +158,11 @@ public Reference createReference(Direction direction, ClassInfo classInfo) { * * @param direction the direction (in or out) * @param classInfo the Java class - * @param createType create the type in the scema + * @param createType create the type in the schema * @return a reference */ - public Reference createReference(Direction direction, ClassInfo classInfo, boolean createType, List parametrizedTypeArguments) { + public Reference createReference(Direction direction, ClassInfo classInfo, boolean createType, + List parametrizedTypeArguments) { // Get the initial reference type. It's either Type or Input depending on the direction. This might change as // we figure out this is actually an enum or interface ReferenceType referenceType = getCorrectReferenceType(direction); @@ -167,7 +170,8 @@ public Reference createReference(Direction direction, ClassInfo classInfo, boole // Now check if this is an interface or enum if (Classes.isInterface(classInfo)) { // Also check that we create all implementations - Collection knownDirectImplementors = ScanningContext.getIndex().getAllKnownImplementors(classInfo.name()); + Collection knownDirectImplementors = ScanningContext.getIndex() + .getAllKnownImplementors(classInfo.name()); for (ClassInfo impl : knownDirectImplementors) { // TODO: First check the class annotations for @Type, if we get one that has that, use it, else any/all // ? @@ -181,16 +185,21 @@ public Reference createReference(Direction direction, ClassInfo classInfo, boole // Now we should have the correct reference type. String className = classInfo.name().toString(); Annotations annotationsForClass = Annotations.getAnnotationsForClass(classInfo); - String name = TypeNameHelper.getAnyTypeName(referenceType, classInfo, annotationsForClass, TypeNameHelper.createParametrizedTypeNameExtension(parametrizedTypeArguments)); + String name = TypeNameHelper.getAnyTypeName(referenceType, classInfo, annotationsForClass, + TypeNameHelper.createParametrizedTypeNameExtension(parametrizedTypeArguments)); Map parametrizedTypeArgumentsReferences = null; - if (parametrizedTypeArguments != null) { + if (parametrizedTypeArguments != null && referenceType != ReferenceType.ENUM) { List tvl = new ArrayList<>(); collectTypeVariables(tvl, classInfo); parametrizedTypeArgumentsReferences = new HashMap<>(); int i = 0; for (Type pat : parametrizedTypeArguments) { - parametrizedTypeArgumentsReferences.put(tvl.get(i++).identifier(), getReference(direction, pat, null, null)); + if(i >= tvl.size()) { + throw new RuntimeException("List of type variables is not correct for class " + classInfo + " and generics argument " + pat); + } else { + parametrizedTypeArgumentsReferences.put(tvl.get(i++).identifier(), getReference(direction, pat, null, null)); + } } } @@ -223,7 +232,8 @@ private Reference getReference(Direction direction, Type fieldType, Type methodT return getReference(direction, fieldType, methodType, annotations, null); } - private Reference getReference(Direction direction, Type fieldType, Type methodType, Annotations annotations, Reference parentObjectReference) { + private Reference getReference(Direction direction, Type fieldType, Type methodType, Annotations annotations, + Reference parentObjectReference) { // In some case, like operations and interfaces, there is not fieldType if (fieldType == null) { @@ -254,14 +264,15 @@ private Reference getReference(Direction direction, Type fieldType, Type methodT } else if (fieldType.kind().equals(Type.Kind.CLASS)) { ClassInfo classInfo = ScanningContext.getIndex().getClassByName(fieldType.name()); if (classInfo != null) { - List parametrizedTypeArguments = null; - if (classInfo.superClassType().kind().equals(Type.Kind.PARAMETERIZED_TYPE)) { - parametrizedTypeArguments = classInfo.superClassType().asParameterizedType().arguments(); - } + List parametrizedTypeArguments = new ArrayList<>(); + collectParametrizedTypeArguments(parametrizedTypeArguments, classInfo); + boolean shouldCreateType = MappingHelper.shouldCreateTypeInSchema(annotations); - return createReference(direction, classInfo, shouldCreateType, parametrizedTypeArguments); + return createReference(direction, classInfo, shouldCreateType, + parametrizedTypeArguments.isEmpty() ? null : parametrizedTypeArguments); } else { - LOG.warn("Class [" + fieldType.name() + "] in not indexed in Jandex. Can not scan Object Type, defaulting to String Scalar"); + LOG.warn("Class [" + fieldType.name() + + "] in not indexed in Jandex. Can not scan Object Type, defaulting to String Scalar"); return Scalars.getScalar(String.class.getName()); // default } } else if (fieldType.kind().equals(Type.Kind.PARAMETERIZED_TYPE)) { @@ -277,34 +288,46 @@ private Reference getReference(Direction direction, Type fieldType, Type methodT boolean shouldCreateType = MappingHelper.shouldCreateTypeInSchema(annotations); return createReference(direction, classInfo, shouldCreateType, parametrizedTypeArguments); } else { - LOG.warn("Class [" + fieldType.name() + "] in not indexed in Jandex. Can not scan Object Type, defaulting to String Scalar"); + LOG.warn("Class [" + fieldType.name() + + "] in not indexed in Jandex. Can not scan Object Type, defaulting to String Scalar"); return Scalars.getScalar(String.class.getName()); // default } } else if (fieldType.kind().equals(Type.Kind.TYPE_VARIABLE)) { if (parentObjectReference == null || parentObjectReference.getParametrizedTypeArguments() == null) { - throw new SchemaBuilderException("Don't know what to do with [" + fieldType + "] of kind [" + fieldType.kind() + "] as parent object reference is missing or incomplete"); + throw new SchemaBuilderException("Don't know what to do with [" + fieldType + "] of kind [" + fieldType.kind() + + "] as parent object reference is missing or incomplete"); } - LOG.warn("Type variable: " + fieldType.asTypeVariable().name() + " identifier: " + fieldType.asTypeVariable().identifier()); + LOG.warn("Type variable: " + fieldType.asTypeVariable().name() + " identifier: " + + fieldType.asTypeVariable().identifier()); Reference ret = parentObjectReference.getParametrizedTypeArguments().get(fieldType.asTypeVariable().identifier()); if (ret == null) { - throw new SchemaBuilderException("Don't know what to do with [" + fieldType + "] of kind [" + fieldType.kind() + "] as parent object reference doesn't contain necessary info"); + throw new SchemaBuilderException("Don't know what to do with [" + fieldType + "] of kind [" + fieldType.kind() + + "] as parent object reference doesn't contain necessary info"); } return ret; } else { - throw new SchemaBuilderException("Don't know what to do with [" + fieldType + "] of kind [" + fieldType.kind() + "]"); + throw new SchemaBuilderException( + "Don't know what to do with [" + fieldType + "] of kind [" + fieldType.kind() + "]"); } } - // private void collectParametrizedTypeArguments(List parametrizedTypeArguments, Type type) { - // if(type.kind().equals(Type.Kind.PARAMETERIZED_TYPE)) { - // parametrizedTypeArguments.addAll(type.asParameterizedType().arguments()); - // } - // if(type.) - // } + private void collectParametrizedTypeArguments(List parametrizedTypeArguments, ClassInfo classInfo) { + if (classInfo == null) + return; + if (classInfo.superClassType() != null) { + + if (classInfo.superClassType().kind().equals(Type.Kind.PARAMETERIZED_TYPE)) { + parametrizedTypeArguments.addAll(classInfo.superClassType().asParameterizedType().arguments()); + } + + collectParametrizedTypeArguments(parametrizedTypeArguments, + ScanningContext.getIndex().getClassByName(classInfo.superName())); + } + } private void putIfAbsent(String key, Reference reference, ReferenceType referenceType) { Map map = getReferenceMap(referenceType); @@ -317,31 +340,31 @@ private void putIfAbsent(String key, Reference reference, ReferenceType referenc private Map getReferenceMap(ReferenceType referenceType) { switch (referenceType) { - case ENUM: - return enumReferenceMap; - case INPUT: - return inputReferenceMap; - case INTERFACE: - return interfaceReferenceMap; - case TYPE: - return typeReferenceMap; - default: - return null; + case ENUM: + return enumReferenceMap; + case INPUT: + return inputReferenceMap; + case INTERFACE: + return interfaceReferenceMap; + case TYPE: + return typeReferenceMap; + default: + return null; } } private Queue getReferenceQueue(ReferenceType referenceType) { switch (referenceType) { - case ENUM: - return enumReferenceQueue; - case INPUT: - return inputReferenceQueue; - case INTERFACE: - return interfaceReferenceQueue; - case TYPE: - return typeReferenceQueue; - default: - return null; + case ENUM: + return enumReferenceQueue; + case INPUT: + return inputReferenceQueue; + case INTERFACE: + return interfaceReferenceQueue; + case TYPE: + return typeReferenceQueue; + default: + return null; } } diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ClassWithOneGenericsParamToString2.java b/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ClassWithOneGenericsParamToString2.java new file mode 100644 index 000000000..b8bff1348 --- /dev/null +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ClassWithOneGenericsParamToString2.java @@ -0,0 +1,8 @@ +package io.smallrye.graphql.schema.test_generics; + +public class ClassWithOneGenericsParamToString2 extends ClassWithOneGenericsParamToString { + + public String getMe() { + return null; + } +} diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ClassWithoutGenerics.java b/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ClassWithoutGenerics.java index a508e754f..5106b2d1b 100644 --- a/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ClassWithoutGenerics.java +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ClassWithoutGenerics.java @@ -5,7 +5,7 @@ public class ClassWithoutGenerics { public String getName() { return null; } - + public int getAge() { return 42; } diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ControllerWithGenerics.java b/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ControllerWithGenerics.java index 12f116e49..5e1ef0546 100644 --- a/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ControllerWithGenerics.java +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/ControllerWithGenerics.java @@ -1,24 +1,26 @@ package io.smallrye.graphql.schema.test_generics; import org.eclipse.microprofile.graphql.GraphQLApi; +import org.eclipse.microprofile.graphql.Mutation; import org.eclipse.microprofile.graphql.Query; @GraphQLApi public class ControllerWithGenerics { - @Query public String getString() { - return null; - } - - @Query - public ClassWithoutGenerics getClassWithoutGenerics(){ - return null; - } - - @Query - public ClassWithOneGenericsParam getClassWithOneGenericsParamInControllerString(){ - return null; - } + @Query + public String getString() { + return null; + } + + @Query + public ClassWithoutGenerics getClassWithoutGenerics() { + return null; + } + + @Query + public ClassWithOneGenericsParam getClassWithOneGenericsParamInControllerString() { + return null; + } @Query public ClassWithTwoGenericsParams> getClassWithTwoGenericsParamsWithNestedOneGenericsParamInControllerString() { @@ -29,14 +31,19 @@ public ClassWithTwoGenericsParams> ge public InterfaceWithOneGenericsParam getInterfaceWithOneGenericsParamInControllerString() { return null; } - + @Query public InterfaceWithOneGenericsParam getInterfaceWithOneGenericsParamInControllerInteger() { return null; } - + @Query - public ClassWithOneGenericsParamToString getClassWithOneGenericsParamToString() { + public ClassWithOneGenericsParamToString2 getClassWithOneGenericsParamToString() { + return null; + } + + @Mutation + public InterfaceWithOneGenericsParam setClassWithOneGenericsParamInControllerString(ClassWithOneGenericsParam param1) { return null; } } diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/GenericsTest.java b/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/GenericsTest.java index 6d392bf20..37ebb1cc1 100644 --- a/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/GenericsTest.java +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/schema/test_generics/GenericsTest.java @@ -1,6 +1,7 @@ package io.smallrye.graphql.schema.test_generics; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.jboss.jandex.Index; import org.jboss.jandex.Indexer; @@ -12,22 +13,40 @@ import io.smallrye.graphql.schema.model.Schema; public class GenericsTest { - + private static final Logger LOG = Logger.getLogger(GenericsTest.class.getName()); @Test - public void testNonNullString() throws Exception { - + public void testSchemaString() throws Exception { + Indexer indexer = new Indexer(); SchemaBuilderTest.indexDirectory(indexer, "io/smallrye/graphql/schema/test_generics"); Index index = indexer.complete(); - Schema schema = SchemaBuilder.build(index); - LOG.info(SchemaBuilderTest.toString(schema)); assertNotNull(schema); - - } + String schemaString = SchemaBuilderTest.toString(schema); + LOG.info(schemaString); + + assertTrue(schemaString.contains("io.smallrye.graphql.schema.test_generics.InterfaceWithOneGenericsParam")); + assertTrue(schemaString.contains("InterfaceWithOneGenericsParam_Int")); + assertTrue(schemaString.contains("InterfaceWithOneGenericsParam_String")); + + assertTrue(schemaString.contains("io.smallrye.graphql.schema.test_generics.ClassWithoutGenerics")); + assertTrue(schemaString.contains("ClassWithoutGenerics")); + + assertTrue(schemaString.contains("io.smallrye.graphql.schema.test_generics.ClassWithOneGenericsParamToString2")); + assertTrue(schemaString.contains("ClassWithOneGenericsParamToString2_String")); + + assertTrue(schemaString.contains("io.smallrye.graphql.schema.test_generics.ClassWithOneGenericsParam")); + assertTrue(schemaString.contains("ClassWithOneGenericsParam_String")); + assertTrue(schemaString.contains("ClassWithOneGenericsParam_Int")); + assertTrue(schemaString.contains("ClassWithOneGenericsParam_StringInput")); + + assertTrue(schemaString.contains("io.smallrye.graphql.schema.test_generics.ClassWithTwoGenericsParams")); + assertTrue(schemaString.contains("ClassWithTwoGenericsParams_String_ClassWithOneGenericsParam_Integer")); + + } }