Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/graphql/language/SDLExtensionDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import graphql.PublicApi;

/**
* An marker interface for Schema Definition Language (SDL) extension definitions.
* A marker interface for Schema Definition Language (SDL) extension definitions.
*/
@PublicApi
public interface SDLExtensionDefinition {
Expand Down
22 changes: 14 additions & 8 deletions src/main/java/graphql/schema/idl/SchemaGeneratorHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -909,10 +909,13 @@ void buildOperations(BuildContext buildCtx, GraphQLSchema.Builder schemaBuilder)

Optional<OperationTypeDefinition> mutationOperation = getOperationNamed("mutation", operationTypeDefs);
if (!mutationOperation.isPresent()) {
Optional<TypeDefinition> mutationTypeDef = typeRegistry.getType("Mutation");
if (mutationTypeDef.isPresent()) {
mutation = buildOutputType(buildCtx, TypeName.newTypeName().name(mutationTypeDef.get().getName()).build());
schemaBuilder.mutation(mutation);
if (!typeRegistry.schemaDefinition().isPresent()) {
// If no schema definition, then there is no schema keyword. Default to using type called Mutation
Optional<TypeDefinition> mutationTypeDef = typeRegistry.getType("Mutation");
if (mutationTypeDef.isPresent()) {
mutation = buildOutputType(buildCtx, TypeName.newTypeName().name(mutationTypeDef.get().getName()).build());
schemaBuilder.mutation(mutation);
}
}
} else {
mutation = buildOperation(buildCtx, mutationOperation.get());
Expand All @@ -921,10 +924,13 @@ void buildOperations(BuildContext buildCtx, GraphQLSchema.Builder schemaBuilder)

Optional<OperationTypeDefinition> subscriptionOperation = getOperationNamed("subscription", operationTypeDefs);
if (!subscriptionOperation.isPresent()) {
Optional<TypeDefinition> subscriptionTypeDef = typeRegistry.getType("Subscription");
if (subscriptionTypeDef.isPresent()) {
subscription = buildOutputType(buildCtx, TypeName.newTypeName().name(subscriptionTypeDef.get().getName()).build());
schemaBuilder.subscription(subscription);
if (!typeRegistry.schemaDefinition().isPresent()) {
// If no schema definition, then there is no schema keyword. Default to using type called Subscription
Optional<TypeDefinition> subscriptionTypeDef = typeRegistry.getType("Subscription");
if (subscriptionTypeDef.isPresent()) {
subscription = buildOutputType(buildCtx, TypeName.newTypeName().name(subscriptionTypeDef.get().getName()).build());
schemaBuilder.subscription(subscription);
}
}
} else {
subscription = buildOperation(buildCtx, subscriptionOperation.get());
Expand Down
119 changes: 119 additions & 0 deletions src/test/groovy/graphql/schema/idl/SchemaParserTest.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package graphql.schema.idl

import graphql.TestUtil
import graphql.language.EnumTypeDefinition
import graphql.language.InterfaceTypeDefinition
import graphql.language.ObjectTypeDefinition
Expand All @@ -9,6 +10,8 @@ import graphql.schema.idl.errors.SchemaProblem
import spock.lang.Specification
import spock.lang.Unroll

import static graphql.schema.idl.SchemaPrinter.Options.defaultOptions

/**
* We don't want to retest the base GraphQL parser since it has its own testing
* but we do want to test our aspects of it
Expand Down Expand Up @@ -361,4 +364,120 @@ class SchemaParserTest extends Specification {
e.errors[0].message.contains("parsing has been cancelled")

}

def "correctly parses schema keyword block, include Query, does not include Mutation type"() {
// From RFC to clarify spec https://github.com/graphql/graphql-spec/pull/987
when:
def schema = """schema {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funky indentation is required for schema printing comparison

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comparing via strings will often result in funky indents - its the nature of the game

query: Query
}

type Mutation {
geneSequence: String!
name: String!
}

type Query {
viruses: [Virus!]
}

type Virus {
knownMutations: [Mutation!]!
name: String!
}
"""
def graphQL = TestUtil.graphQL(schema).build()

then:
graphQL.graphQLSchema.definition.operationTypeDefinitions.size() == 1
graphQL.graphQLSchema.definition.operationTypeDefinitions.first().name == "query"
graphQL.graphQLSchema.queryType != null
graphQL.graphQLSchema.mutationType == null

when:
// Verify that the printed schema is the same as the original
def options = defaultOptions()
.includeIntrospectionTypes(false)
.includeScalarTypes(false)
.includeDirectiveDefinitions(false)
.includeSchemaDefinition(true)

then:
def printedSchema = new SchemaPrinter(options).print(graphQL.graphQLSchema)
printedSchema == schema
}

def "correctly parses schema keyword block, include Query, does not include Subscription type"() {
// From RFC to clarify spec https://github.com/graphql/graphql-spec/pull/987
when:
def schema = """schema {
query: Query
}

type Query {
viruses: [Virus!]
}

type Subscription {
newspaper: String!
}

type Virus {
name: String!
}
"""
def graphQL = TestUtil.graphQL(schema).build()

then:
graphQL.graphQLSchema.definition.operationTypeDefinitions.size() == 1
graphQL.graphQLSchema.definition.operationTypeDefinitions.first().name == "query"
graphQL.graphQLSchema.queryType != null
graphQL.graphQLSchema.subscriptionType == null

when:
// Verify that the printed schema is the same as the original
def options = defaultOptions()
.includeIntrospectionTypes(false)
.includeScalarTypes(false)
.includeDirectiveDefinitions(false)
.includeSchemaDefinition(true)

then:
def printedSchema = new SchemaPrinter(options).print(graphQL.graphQLSchema)
printedSchema == schema
}

def "correctly parses schema that does not contain a schema definition block, includes Query and Mutation types"() {
when:
def schema = """type Mutation {
geneSequence: String!
name: String!
}

type Query {
viruses: [Virus!]
}

type Virus {
name: String!
}
"""
def graphQL = TestUtil.graphQL(schema).build()

then:
graphQL.graphQLSchema.definition == null // No SchemaDefinition
graphQL.graphQLSchema.queryType != null
graphQL.graphQLSchema.mutationType != null

when:
// Verify that the printed schema is the same as the original
def options = defaultOptions()
.includeIntrospectionTypes(false)
.includeScalarTypes(false)
.includeDirectiveDefinitions(false)

then:
def printedSchema = new SchemaPrinter(options).print(graphQL.graphQLSchema)
printedSchema == schema
}
}