From 5f62bf0916fad2efba1927e0b88be6440c630dac Mon Sep 17 00:00:00 2001 From: Daniel Jakobsen Date: Fri, 12 May 2017 16:09:05 +0300 Subject: [PATCH 1/6] better exceptions for incorrect types --- .../graphql/schema/idl/SchemaGenerator.java | 20 +++++-- .../idl/errors/NotAnInputTypeError.java | 12 ++++ .../idl/errors/NotAnOutputTypeError.java | 12 ++++ .../schema/idl/SchemaGeneratorTest.groovy | 55 +++++++++++++++++++ 4 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java create mode 100644 src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java diff --git a/src/main/java/graphql/schema/idl/SchemaGenerator.java b/src/main/java/graphql/schema/idl/SchemaGenerator.java index ef1379d1c2..a3903a3a73 100644 --- a/src/main/java/graphql/schema/idl/SchemaGenerator.java +++ b/src/main/java/graphql/schema/idl/SchemaGenerator.java @@ -22,7 +22,6 @@ import graphql.language.Type; import graphql.language.TypeDefinition; import graphql.language.TypeExtensionDefinition; -import graphql.language.TypeName; import graphql.language.UnionTypeDefinition; import graphql.language.Value; import graphql.schema.DataFetcher; @@ -42,6 +41,8 @@ import graphql.schema.PropertyDataFetcher; import graphql.schema.TypeResolver; import graphql.schema.TypeResolverProxy; +import graphql.schema.idl.errors.NotAnInputTypeError; +import graphql.schema.idl.errors.NotAnOutputTypeError; import graphql.schema.idl.errors.SchemaProblem; import java.util.Collections; @@ -135,7 +136,9 @@ public SchemaGenerator() { * * @param typeRegistry this can be obtained via {@link SchemaCompiler#compile(String)} * @param wiring this can be built using {@link RuntimeWiring#newRuntimeWiring()} + * * @return an executable schema + * * @throws SchemaProblem if there are problems in assembling a schema such as missing type resolvers or no operations defined */ public GraphQLSchema makeExecutableSchema(TypeDefinitionRegistry typeRegistry, RuntimeWiring wiring) throws SchemaProblem { @@ -184,6 +187,7 @@ private GraphQLObjectType buildOperation(BuildContext buildCtx, OperationTypeDef * * @param buildCtx the context we need to work out what we are doing * @param rawType the type to be built + * * @return an output type */ @SuppressWarnings("unchecked") @@ -213,8 +217,11 @@ private T buildOutputType(BuildContext buildCtx, T outputType = buildUnionType(buildCtx, (UnionTypeDefinition) typeDefinition); } else if (typeDefinition instanceof EnumTypeDefinition) { outputType = buildEnumType((EnumTypeDefinition) typeDefinition); - } else { + } else if (typeDefinition instanceof ScalarTypeDefinition){ outputType = buildScalar(buildCtx, (ScalarTypeDefinition) typeDefinition); + } else { + // typeDefinition is not a valid output type + throw new NotAnOutputTypeError(typeDefinition); } buildCtx.put(outputType); @@ -243,8 +250,11 @@ private GraphQLInputType buildInputType(BuildContext buildCtx, Type rawType) { inputType = buildInputObjectType(buildCtx, (InputObjectTypeDefinition) typeDefinition); } else if (typeDefinition instanceof EnumTypeDefinition) { inputType = buildEnumType((EnumTypeDefinition) typeDefinition); - } else { + } else if (typeDefinition instanceof ScalarTypeDefinition){ inputType = buildScalar(buildCtx, (ScalarTypeDefinition) typeDefinition); + } else { + // typeDefinition is not a valid InputType + throw new NotAnInputTypeError(typeDefinition); } buildCtx.put(inputType); @@ -331,7 +341,9 @@ private GraphQLUnionType buildUnionType(BuildContext buildCtx, UnionTypeDefiniti builder.typeResolver(getTypeResolver(buildCtx, typeDefinition.getName())); typeDefinition.getMemberTypes().forEach(mt -> { - builder.possibleType(new GraphQLTypeReference(((TypeName) mt).getName())); + TypeDefinition memberTypeDef = buildCtx.getTypeDefinition(mt); + GraphQLObjectType objectType = buildObjectType(buildCtx, (ObjectTypeDefinition) memberTypeDef); + builder.possibleType(objectType); }); return builder.build(); } diff --git a/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java b/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java new file mode 100644 index 0000000000..da1f2c5b23 --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java @@ -0,0 +1,12 @@ +package graphql.schema.idl.errors; + +import graphql.language.TypeDefinition; + +import static java.lang.String.format; + +public class NotAnInputTypeError extends BaseError { + + public NotAnInputTypeError(TypeDefinition typeDefinition) { + super(typeDefinition, format("The %s type is used as an InputType, but is not declared as one", typeDefinition.getName())); + } +} diff --git a/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java b/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java new file mode 100644 index 0000000000..c62b0ffbac --- /dev/null +++ b/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java @@ -0,0 +1,12 @@ +package graphql.schema.idl.errors; + +import graphql.language.TypeDefinition; + +import static java.lang.String.format; + +public class NotAnOutputTypeError extends BaseError { + + public NotAnOutputTypeError(TypeDefinition typeDefinition) { + super(typeDefinition, format("The %s type is used as an OutputType, but is not declared as one", typeDefinition.getName())); + } +} diff --git a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy index 039c2b05a1..6be993f22c 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy @@ -2,6 +2,8 @@ package graphql.schema.idl import graphql.TypeResolutionEnvironment import graphql.schema.* +import graphql.schema.idl.errors.NotAnInputTypeError +import graphql.schema.idl.errors.NotAnOutputTypeError import spock.lang.Specification import java.util.function.UnaryOperator @@ -479,8 +481,61 @@ class SchemaGeneratorTest extends Specification { type.interfaces.size() == 1 type.interfaces[0].name == "Character" + } + + def "Type used as inputType should throw appropriate error #425"() { + when: + def spec = """ + schema { + query: Query + } + + type Query { + findCharacter(character: CharacterInput!): Boolean + } + + # CharacterInput must be an input, but is a type + type CharacterInput { + firstName: String + lastName: String + family: Boolean + } + """ + def wiring = RuntimeWiring.newRuntimeWiring() + .build() + + generateSchema(spec, wiring) + then: + def err = thrown(NotAnInputTypeError.class) + err.message == "The CharacterInput type is used as an InputType, but is not declared as one" + } + + def "InputType used as type should throw appropriate error #425"() { + when: + def spec = """ + schema { + query: Query + } + + type Query { + findCharacter: CharacterInput + } + + # CharacterInput must be an input, but is a type + input CharacterInput { + firstName: String + lastName: String + family: Boolean + } + """ + def wiring = RuntimeWiring.newRuntimeWiring() + .build() + generateSchema(spec, wiring) + then: + def err = thrown(NotAnOutputTypeError.class) + err.message == "The CharacterInput type is used as an OutputType, but is not declared as one" } } From d7dada8314889845ce0ab4b67687109895229088 Mon Sep 17 00:00:00 2001 From: Daniel Jakobsen Date: Fri, 12 May 2017 16:15:05 +0300 Subject: [PATCH 2/6] rebase from master --- src/main/java/graphql/schema/idl/SchemaGenerator.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/graphql/schema/idl/SchemaGenerator.java b/src/main/java/graphql/schema/idl/SchemaGenerator.java index a3903a3a73..e67db07658 100644 --- a/src/main/java/graphql/schema/idl/SchemaGenerator.java +++ b/src/main/java/graphql/schema/idl/SchemaGenerator.java @@ -22,6 +22,7 @@ import graphql.language.Type; import graphql.language.TypeDefinition; import graphql.language.TypeExtensionDefinition; +import graphql.language.TypeName; import graphql.language.UnionTypeDefinition; import graphql.language.Value; import graphql.schema.DataFetcher; @@ -136,9 +137,7 @@ public SchemaGenerator() { * * @param typeRegistry this can be obtained via {@link SchemaCompiler#compile(String)} * @param wiring this can be built using {@link RuntimeWiring#newRuntimeWiring()} - * * @return an executable schema - * * @throws SchemaProblem if there are problems in assembling a schema such as missing type resolvers or no operations defined */ public GraphQLSchema makeExecutableSchema(TypeDefinitionRegistry typeRegistry, RuntimeWiring wiring) throws SchemaProblem { @@ -187,7 +186,6 @@ private GraphQLObjectType buildOperation(BuildContext buildCtx, OperationTypeDef * * @param buildCtx the context we need to work out what we are doing * @param rawType the type to be built - * * @return an output type */ @SuppressWarnings("unchecked") @@ -341,9 +339,7 @@ private GraphQLUnionType buildUnionType(BuildContext buildCtx, UnionTypeDefiniti builder.typeResolver(getTypeResolver(buildCtx, typeDefinition.getName())); typeDefinition.getMemberTypes().forEach(mt -> { - TypeDefinition memberTypeDef = buildCtx.getTypeDefinition(mt); - GraphQLObjectType objectType = buildObjectType(buildCtx, (ObjectTypeDefinition) memberTypeDef); - builder.possibleType(objectType); + builder.possibleType(new GraphQLTypeReference(((TypeName) mt).getName())); }); return builder.build(); } @@ -472,4 +468,4 @@ private String buildDescription(Node node) { } return sb.toString(); } -} +} \ No newline at end of file From 41519ef43dd86269ab422f3e60d8434bbc2b3689 Mon Sep 17 00:00:00 2001 From: Daniel Jakobsen Date: Fri, 12 May 2017 23:18:20 +0300 Subject: [PATCH 3/6] phrase better exception messages --- .../java/graphql/schema/idl/errors/NotAnInputTypeError.java | 2 +- .../java/graphql/schema/idl/errors/NotAnOutputTypeError.java | 2 +- src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java b/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java index da1f2c5b23..129cf8e532 100644 --- a/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java @@ -7,6 +7,6 @@ public class NotAnInputTypeError extends BaseError { public NotAnInputTypeError(TypeDefinition typeDefinition) { - super(typeDefinition, format("The %s type is used as an InputType, but is not declared as one", typeDefinition.getName())); + super(typeDefinition, format("expected InputType, but found %s type", typeDefinition.getName())); } } diff --git a/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java b/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java index c62b0ffbac..44183bc19a 100644 --- a/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java @@ -7,6 +7,6 @@ public class NotAnOutputTypeError extends BaseError { public NotAnOutputTypeError(TypeDefinition typeDefinition) { - super(typeDefinition, format("The %s type is used as an OutputType, but is not declared as one", typeDefinition.getName())); + super(typeDefinition, format("expected OutputType, but found %s type", typeDefinition.getName())); } } diff --git a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy index 6be993f22c..d11cb771d6 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy @@ -508,7 +508,7 @@ class SchemaGeneratorTest extends Specification { then: def err = thrown(NotAnInputTypeError.class) - err.message == "The CharacterInput type is used as an InputType, but is not declared as one" + err.message == "expected InputType, but found CharacterInput type" } def "InputType used as type should throw appropriate error #425"() { @@ -536,6 +536,6 @@ class SchemaGeneratorTest extends Specification { then: def err = thrown(NotAnOutputTypeError.class) - err.message == "The CharacterInput type is used as an OutputType, but is not declared as one" + err.message == "expected OutputType, but found CharacterInput type" } } From 0072285940210f7d9873b2ba49be01cbd72e908d Mon Sep 17 00:00:00 2001 From: Daniel Jakobsen Date: Tue, 16 May 2017 00:15:18 +0300 Subject: [PATCH 4/6] add lincol to exception --- .../java/graphql/schema/idl/errors/NotAnInputTypeError.java | 2 +- .../java/graphql/schema/idl/errors/NotAnOutputTypeError.java | 2 +- src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java b/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java index 129cf8e532..76e1edc12a 100644 --- a/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/NotAnInputTypeError.java @@ -7,6 +7,6 @@ public class NotAnInputTypeError extends BaseError { public NotAnInputTypeError(TypeDefinition typeDefinition) { - super(typeDefinition, format("expected InputType, but found %s type", typeDefinition.getName())); + super(typeDefinition, format("expected InputType, but found %s type %s", typeDefinition.getName(), lineCol(typeDefinition))); } } diff --git a/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java b/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java index 44183bc19a..d233a3507a 100644 --- a/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java +++ b/src/main/java/graphql/schema/idl/errors/NotAnOutputTypeError.java @@ -7,6 +7,6 @@ public class NotAnOutputTypeError extends BaseError { public NotAnOutputTypeError(TypeDefinition typeDefinition) { - super(typeDefinition, format("expected OutputType, but found %s type", typeDefinition.getName())); + super(typeDefinition, format("expected OutputType, but found %s type %s", typeDefinition.getName(), lineCol(typeDefinition))); } } diff --git a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy index d11cb771d6..22b9a9da56 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy @@ -508,7 +508,7 @@ class SchemaGeneratorTest extends Specification { then: def err = thrown(NotAnInputTypeError.class) - err.message == "expected InputType, but found CharacterInput type" + err.message == "expected InputType, but found CharacterInput type [@11:13]" } def "InputType used as type should throw appropriate error #425"() { @@ -536,6 +536,6 @@ class SchemaGeneratorTest extends Specification { then: def err = thrown(NotAnOutputTypeError.class) - err.message == "expected OutputType, but found CharacterInput type" + err.message == "expected OutputType, but found CharacterInput type [@11:13]" } } From 3063d3b54dbfa6bd6d4dc4fb4809b876dc6b62ce Mon Sep 17 00:00:00 2001 From: Daniel Jakobsen Date: Tue, 16 May 2017 00:29:32 +0300 Subject: [PATCH 5/6] fix merge --- .../graphql/schema/idl/SchemaGeneratorTest.groovy | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy index 9a1455893d..bbbcaabe95 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy @@ -2,6 +2,8 @@ package graphql.schema.idl import graphql.TypeResolutionEnvironment import graphql.schema.* +import graphql.schema.idl.errors.NotAnInputTypeError +import graphql.schema.idl.errors.NotAnOutputTypeError import spock.lang.Specification import java.util.function.UnaryOperator @@ -22,7 +24,7 @@ class SchemaGeneratorTest extends Specification { GraphQLSchema generateSchema(String schemaSpec, RuntimeWiring wiring) { - def typeRegistry = new SchemaCompiler().compile(schemaSpec) + def typeRegistry = new SchemaParser().parse(schemaSpec) def result = new SchemaGenerator().makeExecutableSchema(typeRegistry, wiring) result } @@ -241,9 +243,9 @@ class SchemaGeneratorTest extends Specification { } """ - def typeRegistry1 = new SchemaCompiler().compile(schemaSpec1) - def typeRegistry2 = new SchemaCompiler().compile(schemaSpec2) - def typeRegistry3 = new SchemaCompiler().compile(schemaSpec3) + def typeRegistry1 = new SchemaParser().parse(schemaSpec1) + def typeRegistry2 = new SchemaParser().parse(schemaSpec2) + def typeRegistry3 = new SchemaParser().parse(schemaSpec3) typeRegistry1.merge(typeRegistry2).merge(typeRegistry3) From ccecbef2c158ada8af28ec8c3e38dfb40699799b Mon Sep 17 00:00:00 2001 From: Daniel Jakobsen Date: Tue, 16 May 2017 00:32:52 +0300 Subject: [PATCH 6/6] fix merge --- .../schema/idl/SchemaGeneratorTest.groovy | 158 +++++++++++++++--- 1 file changed, 136 insertions(+), 22 deletions(-) diff --git a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy index bbbcaabe95..856fc97c7b 100644 --- a/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy +++ b/src/test/groovy/graphql/schema/idl/SchemaGeneratorTest.groovy @@ -72,7 +72,6 @@ class SchemaGeneratorTest extends Specification { assert authorField.arguments.get(0).type instanceof GraphQLNonNull assert unwrap(authorField.arguments.get(0).type).name == "Int" - //type Post { // id: Int! // title: String @@ -131,7 +130,6 @@ class SchemaGeneratorTest extends Specification { } - def "test simple schema generate"() { def schemaSpec = """ @@ -187,6 +185,7 @@ class SchemaGeneratorTest extends Specification { commonSchemaAsserts(schema) } + def "schema can come from multiple sources and be bound together"() { def schemaSpec1 = """ type Author { @@ -209,7 +208,6 @@ class SchemaGeneratorTest extends Specification { """ def schemaSpec3 = """ - # the schema allows the following query # to be made type Query { @@ -256,13 +254,123 @@ class SchemaGeneratorTest extends Specification { commonSchemaAsserts(schema) + } + + def "union type: union member used two times "() { + def spec = """ + type Query { + foobar: FooOrBar + foo: Foo + } + + type Foo { + name: String + } + + type Bar { + other: String + } + + union FooOrBar = Foo | Bar + + schema { + query: Query + } + """ + + def schema = generateSchema(spec, RuntimeWiring.newRuntimeWiring() + .type("FooOrBar", buildResolver()) + .build()) + + + expect: + + def foobar = schema.getQueryType().getFieldDefinition("foobar") + foobar.type instanceof GraphQLUnionType + def types = ((GraphQLUnionType) foobar.type).getTypes(); + types.size() == 2 + types[0].name == "Foo" + types[1].name == "Bar" } - def "enum types are handled"() { + def "union type: union members only used once"() { + def spec = """ + type Query { + foobar: FooOrBar + } + + type Foo { + name: String + } + + type Bar { + other: String + } + + union FooOrBar = Foo | Bar + + schema { + query: Query + } + """ + def schema = generateSchema(spec, RuntimeWiring.newRuntimeWiring() + .type("FooOrBar", buildResolver()) + .build()) + + + expect: + + def foobar = schema.getQueryType().getFieldDefinition("foobar") + foobar.type instanceof GraphQLUnionType + def types = ((GraphQLUnionType) foobar.type).getTypes(); + types.size() == 2 + types[0].name == "Foo" + types[1].name == "Bar" + + } + + def "union type: union declared before members"() { def spec = """ + union FooOrBar = Foo | Bar + + type Foo { + name: String + } + + type Bar { + other: String + } + + type Query { + foobar: FooOrBar + } + + schema { + query: Query + } + """ + def schema = generateSchema(spec, RuntimeWiring.newRuntimeWiring() + .type("FooOrBar", buildResolver()) + .build()) + + + expect: + + def foobar = schema.getQueryType().getFieldDefinition("foobar") + foobar.type instanceof GraphQLUnionType + def types = ((GraphQLUnionType) foobar.type).getTypes(); + types.size() == 2 + types[0].name == "Foo" + types[1].name == "Bar" + + } + + def "enum types are handled"() { + + def spec = """ enum RGB { RED GREEN @@ -276,7 +384,6 @@ class SchemaGeneratorTest extends Specification { schema { query: Query } - """ def schema = generateSchema(spec, RuntimeWiring.newRuntimeWiring().build()) @@ -294,7 +401,6 @@ class SchemaGeneratorTest extends Specification { def "interface types are handled"() { def spec = """ - interface Foo { is_foo : Boolean } @@ -311,7 +417,6 @@ class SchemaGeneratorTest extends Specification { schema { query: Query } - """ def wiring = RuntimeWiring.newRuntimeWiring() @@ -334,21 +439,17 @@ class SchemaGeneratorTest extends Specification { def "type extensions can be specified multiple times #406"() { def spec = """ - interface Interface1 { extraField1 : String } - interface Interface2 { extraField1 : String extraField2 : Int } - interface Interface3 { extraField1 : String extraField3 : ID } - type BaseType { baseField : String } @@ -356,25 +457,20 @@ class SchemaGeneratorTest extends Specification { extend type BaseType implements Interface1 { extraField1 : String } - extend type BaseType implements Interface2 { extraField1 : String extraField2 : Int } - extend type BaseType implements Interface3 { extraField1 : String extraField3 : ID } - extend type BaseType { extraField4 : Boolean } - extend type BaseType { extraField5 : Boolean! } - # # if we repeat a definition, that's ok as long as its the same types as before # they will be de-duped since the effect is the same @@ -386,7 +482,6 @@ class SchemaGeneratorTest extends Specification { schema { query: BaseType } - """ def wiring = RuntimeWiring.newRuntimeWiring() @@ -433,11 +528,9 @@ class SchemaGeneratorTest extends Specification { def "read me type example makes sense"() { def spec = """ - schema { query: Human } - type Episode { name : String } @@ -450,12 +543,10 @@ class SchemaGeneratorTest extends Specification { id: ID! name: String! } - extend type Human implements Character { name: String! friends: [Character] } - extend type Human { appearsIn: [Episode]! homePlanet: String @@ -538,4 +629,27 @@ class SchemaGeneratorTest extends Specification { def err = thrown(NotAnOutputTypeError.class) err.message == "expected OutputType, but found CharacterInput type [@11:13]" } -} + + def "schema with subscription"() { + given: + def spec = """ + schema { + query: Query + subscription: Subscription + } + type Query { + foo: String + } + + type Subscription { + foo: String + } + """ + when: + def wiring = RuntimeWiring.newRuntimeWiring() + .build() + def schema = generateSchema(spec, wiring) + then: + schema.getSubscriptionType().name == "Subscription" + } +} \ No newline at end of file