From d528457f65fab0edbfac797cf6fd307bff67f38b Mon Sep 17 00:00:00 2001 From: Yarin Date: Mon, 14 Oct 2019 21:50:48 +0300 Subject: [PATCH 1/2] add tests, deprecate method and add method to graphql annotations schema creator --- README.md | 2 +- .../annotations/AnnotationsSchemaCreator.java | 15 +++- .../processor/GraphQLAnnotations.java | 17 +---- .../AnnotationsSchemaCreatorTest.java | 72 +++++++++++++++++-- .../GraphQLDirectiveCreationTest.java | 8 +-- ...DirectivesViaAnnotationDefinitionTest.java | 6 +- 6 files changed, 90 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 51432c2f..ee3b76ee 100644 --- a/README.md +++ b/README.md @@ -438,7 +438,7 @@ In order to define a default value for the argument, use the `default` keyword l After you created the class, you will be able to create the ``GraphQLDirective`` object using the following code: ```java -GraphQLDirective directive = graphqlAnnotations.directiveViaAnnotation(Suffix.class); +GraphQLDirective directive = graphqlAnnotations.directive(Suffix.class); ``` #### Using a method declaration diff --git a/src/main/java/graphql/annotations/AnnotationsSchemaCreator.java b/src/main/java/graphql/annotations/AnnotationsSchemaCreator.java index a55c3a45..2b9c48e8 100644 --- a/src/main/java/graphql/annotations/AnnotationsSchemaCreator.java +++ b/src/main/java/graphql/annotations/AnnotationsSchemaCreator.java @@ -36,6 +36,7 @@ public static class Builder { private Class mutationObject; private Class subscriptionObject; private Set> directivesObjectList = new HashSet<>(); + private Set> directiveContainerClasses = new HashSet<>(); private Set> additionalTypesList = new HashSet<>(); private Set> typeExtensions = new HashSet<>(); private Set typeFunctions = new HashSet<>(); @@ -113,6 +114,16 @@ public Builder directives(Set> directiveClasses) { return this; } + /** + * Add directive declaration class to create directives for the graphql schema + * @param directiveContainerClass a directive container class (directives are defined as methods inside the class) + * @return the builder after adding the directive container class to the list of directive container classes + */ + public Builder directives(Class directiveContainerClass){ + this.directiveContainerClasses.add(directiveContainerClass); + return this; + } + /** * Add a directive to the graphql schema * This method will generate a GraphQL Directive type out of your java class using the annotations processor @@ -223,6 +234,8 @@ public GraphQLSchema build() { } Set directives = directivesObjectList.stream().map(dir -> graphQLAnnotations.directive(dir)).collect(Collectors.toSet()); + directiveContainerClasses.forEach(dir->directives.addAll(graphQLAnnotations.directives(dir))); + Set additionalTypes = additionalTypesList.stream().map(additionalType -> additionalType.isInterface() ? graphQLAnnotations.generateInterface(additionalType) : graphQLAnnotations.object(additionalType)).collect(Collectors.toSet()); @@ -234,7 +247,7 @@ public GraphQLSchema build() { if (this.subscriptionObject != null) { this.graphqlSchemaBuilder.subscription(graphQLAnnotations.object(subscriptionObject)); } - if (!this.directivesObjectList.isEmpty()) { + if (!directives.isEmpty()) { graphqlSchemaBuilder.additionalDirectives(directives); } this.graphqlSchemaBuilder.additionalTypes(additionalTypes).additionalType(Relay.pageInfoType) diff --git a/src/main/java/graphql/annotations/processor/GraphQLAnnotations.java b/src/main/java/graphql/annotations/processor/GraphQLAnnotations.java index 4efc8e1e..38122693 100644 --- a/src/main/java/graphql/annotations/processor/GraphQLAnnotations.java +++ b/src/main/java/graphql/annotations/processor/GraphQLAnnotations.java @@ -34,7 +34,6 @@ import graphql.schema.GraphQLInterfaceType; import graphql.schema.GraphQLObjectType; -import java.lang.annotation.Retention; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashSet; @@ -159,21 +158,9 @@ public GraphQLDirective directive(Class object) throws GraphQLAnnotationsExce } } + @Deprecated public GraphQLDirective directiveViaAnnotation(Class annotationClass) { - if (!annotationClass.isAnnotationPresent(GraphQLDirectiveDefinition.class) || !annotationClass.isAnnotationPresent(Retention.class)){ - throw new GraphQLAnnotationsException(String.format("The supplied class %s is not annotated with a GraphQLDirectiveDefinition and/or Retention annotation", annotationClass.getSimpleName()), null); - } - - try { - GraphQLDirective directive = this.directiveCreator.getDirective(annotationClass); - GraphQLDirectiveDefinition annotation = annotationClass.getAnnotation(GraphQLDirectiveDefinition.class); - this.getContainer().getDirectiveRegistry().put(directive.getName(), new DirectiveAndWiring(directive, annotation.wiring())); - return directive; - } catch (GraphQLAnnotationsException e) { - this.getContainer().getProcessing().clear(); - this.getTypeRegistry().clear(); - throw e; - } + return this.directive(annotationClass); } public Set directives(Class directivesDeclarationClass) { diff --git a/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java b/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java index baa095b7..55d4c426 100644 --- a/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java +++ b/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java @@ -1,12 +1,12 @@ /** * Copyright 2016 Yurii Rashkovskii - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,10 +17,10 @@ import graphql.annotations.annotationTypes.GraphQLDescription; import graphql.annotations.annotationTypes.GraphQLField; import graphql.annotations.annotationTypes.GraphQLName; +import graphql.annotations.annotationTypes.directives.definition.DirectiveLocations; import graphql.annotations.annotationTypes.directives.definition.GraphQLDirectiveDefinition; import graphql.annotations.directives.AnnotationsDirectiveWiring; import graphql.annotations.directives.AnnotationsWiringEnvironment; -import graphql.annotations.annotationTypes.directives.definition.DirectiveLocations; import graphql.annotations.processor.GraphQLAnnotations; import graphql.introspection.Introspection; import graphql.schema.GraphQLDirective; @@ -30,6 +30,10 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.HashSet; import java.util.Set; @@ -110,7 +114,7 @@ public void build_Subscription_SchemaIsCreatedWithSubscription() { assertThat(subscriptionType.getFieldDefinitions().size(), is(1)); } - public static class GeneralWiring implements AnnotationsDirectiveWiring{ + public static class GeneralWiring implements AnnotationsDirectiveWiring { @Override public GraphQLFieldDefinition onField(AnnotationsWiringEnvironment environment) { return null; @@ -158,6 +162,62 @@ public void build_MultipleDirectives_SchemaIsCreatedWithDirectives() { assertThat(schema.getDirective("testDirective"), notNullValue()); } + + @GraphQLDirectiveDefinition(wiring = GeneralWiring.class) + @GraphQLName("upper") + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @DirectiveLocations(Introspection.DirectiveLocation.FIELD_DEFINITION) + @interface UpperAnnotation { + boolean isActive() default true; + } + + + @Test + public void build_directiveUsingAnnotation_schemaIsCreatedWithDirective() { + // arrange + act + GraphQLSchema schema = builder.query(QueryTest.class).directive(UpperAnnotation.class).build(); + + // assert + GraphQLDirective testDirective = schema.getDirective("upper"); + assertThat(testDirective, notNullValue()); + assertThat(testDirective.getArguments().size(), is(1)); + assertThat(testDirective.getArgument("isActive"), notNullValue()); + } + + + public static class DirectivesContainer { + @GraphQLName("suffix") + @GraphQLDirectiveDefinition(wiring = GeneralWiring.class) + @DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION, Introspection.DirectiveLocation.ARGUMENT_DEFINITION}) + public static void suffixDirective(@GraphQLName("suffix") String suffix) { + + } + + @GraphQLName("upper") + @GraphQLDirectiveDefinition(wiring = GeneralWiring.class) + @DirectiveLocations({Introspection.DirectiveLocation.FIELD_DEFINITION, Introspection.DirectiveLocation.ARGUMENT_DEFINITION}) + public static void upper() { + + } + } + + + @Test + public void build_directive_UsingDirectivesContainer_schemaIsCreatedWithDirective() { + // arrange + act + GraphQLSchema schema = builder.query(QueryTest.class).directives(DirectivesContainer.class).build(); + + // assert + GraphQLDirective testDirective = schema.getDirective("suffix"); + assertThat(testDirective, notNullValue()); + assertThat(testDirective.getArguments().size(), is(1)); + assertThat(testDirective.getArgument("suffix"), notNullValue()); + + GraphQLDirective upper = schema.getDirective("upper"); + assertThat(upper, notNullValue()); + } + @GraphQLName("additional") public static class AdditionalTypeTest { public int getI() { diff --git a/src/test/java/graphql/annotations/GraphQLDirectiveCreationTest.java b/src/test/java/graphql/annotations/GraphQLDirectiveCreationTest.java index 2e6833a2..e00acbb0 100644 --- a/src/test/java/graphql/annotations/GraphQLDirectiveCreationTest.java +++ b/src/test/java/graphql/annotations/GraphQLDirectiveCreationTest.java @@ -15,10 +15,10 @@ package graphql.annotations; import graphql.annotations.annotationTypes.GraphQLDescription; -import graphql.annotations.annotationTypes.directives.definition.GraphQLDirectiveDefinition; import graphql.annotations.annotationTypes.GraphQLName; -import graphql.annotations.directives.AnnotationsDirectiveWiring; import graphql.annotations.annotationTypes.directives.definition.DirectiveLocations; +import graphql.annotations.annotationTypes.directives.definition.GraphQLDirectiveDefinition; +import graphql.annotations.directives.AnnotationsDirectiveWiring; import graphql.annotations.processor.GraphQLAnnotations; import graphql.annotations.processor.exceptions.GraphQLAnnotationsException; import graphql.introspection.Introspection; @@ -171,7 +171,7 @@ public void directive_suppliedDirectiveMethodContainer_returnCorrectDirective() @Test public void directive_suppliedDirectiveAnnotation_returnCorrectDirective() { // Act - GraphQLDirective upper = this.graphQLAnnotations.directiveViaAnnotation(UpperAnnotation.class); + GraphQLDirective upper = this.graphQLAnnotations.directive(UpperAnnotation.class); // Assert assertEquals(upper.getName(), "upper"); @@ -188,7 +188,7 @@ public void directive_suppliedDirectiveAnnotation_returnCorrectDirective() { @Test(expectedExceptions = GraphQLAnnotationsException.class) public void directive_suppliedNoDirectiveAnnotation_throwException() { // Act - GraphQLDirective upper = this.graphQLAnnotations.directiveViaAnnotation(NoDirectiveAnnotation.class); + GraphQLDirective upper = this.graphQLAnnotations.directive(NoDirectiveAnnotation.class); } diff --git a/src/test/java/graphql/annotations/GraphQLDirectivesViaAnnotationDefinitionTest.java b/src/test/java/graphql/annotations/GraphQLDirectivesViaAnnotationDefinitionTest.java index 8d99786b..78241019 100644 --- a/src/test/java/graphql/annotations/GraphQLDirectivesViaAnnotationDefinitionTest.java +++ b/src/test/java/graphql/annotations/GraphQLDirectivesViaAnnotationDefinitionTest.java @@ -46,9 +46,9 @@ public class GraphQLDirectivesViaAnnotationDefinitionTest { @BeforeMethod public void setUp() { this.graphQLAnnotations = new GraphQLAnnotations(); - this.graphQLAnnotations.directiveViaAnnotation(Upper.class); - this.graphQLAnnotations.directiveViaAnnotation(Suffix.class); - this.graphQLAnnotations.directiveViaAnnotation(DirectiveWithList.class); + this.graphQLAnnotations.directive(Upper.class); + this.graphQLAnnotations.directive(Suffix.class); + this.graphQLAnnotations.directive(DirectiveWithList.class); GraphQLObjectType object = this.graphQLAnnotations.object(Query.class); GraphQLCodeRegistry codeRegistry = graphQLAnnotations.getContainer().getCodeRegistryBuilder().build(); this.schema = newSchema().query(object).codeRegistry(codeRegistry).build(); From 14c1ac1dffaed553a7a61fc6f25b3bd266501b2d Mon Sep 17 00:00:00 2001 From: Yarin Date: Mon, 14 Oct 2019 21:52:40 +0300 Subject: [PATCH 2/2] license --- .../graphql/annotations/AnnotationsSchemaCreatorTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java b/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java index 55d4c426..8b8bcc57 100644 --- a/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java +++ b/src/test/java/graphql/annotations/AnnotationsSchemaCreatorTest.java @@ -1,12 +1,12 @@ /** * Copyright 2016 Yurii Rashkovskii - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.