func TestPrinter_PrintsMinimalAST(t *testing.T) { astDoc := ast.NewField(&ast.Field{ Name: ast.NewName(&ast.Name{ Value: "foo", }), }) results := printer.Print(astDoc) expected := "foo" if !reflect.DeepEqual(results, expected) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, results)) } }
func TestSchemaPrinter_PrintsMinimalAST(t *testing.T) { astDoc := ast.NewScalarTypeDefinition(&ast.ScalarTypeDefinition{ Name: ast.NewName(&ast.Name{ Value: "foo", }), }) results := printer.Print(astDoc) expected := "scalar foo" if !reflect.DeepEqual(results, expected) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, results)) } }
func TestPrinter_PrintsKitchenSink(t *testing.T) { b, err := ioutil.ReadFile("./../parser/kitchen-sink.graphql") if err != nil { t.Fatalf("unable to load kitchen-sink.graphql") } query := string(b) astDoc := parse(t, query) expected := `query namedQuery($foo: ComplexFooType, $bar: Bar = DefaultBarValue) { customUser: user(id: [987, 654]) { id ... on User @defer { field2 { id alias: field1(first: 10, after: $foo) @include(if: $foo) { id ...frag } } } } } mutation favPost { fav(post: 123) @defer { post { id } } } fragment frag on Follower { foo(size: $size, bar: $b, obj: {key: "value"}) } { unnamed(truthyVal: true, falseyVal: false) query } ` results := printer.Print(astDoc) if !reflect.DeepEqual(expected, results) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(results, expected)) } }
func TestSchemaPrinter_PrintsKitchenSink(t *testing.T) { b, err := ioutil.ReadFile("./../parser/schema-kitchen-sink.graphql") if err != nil { t.Fatalf("unable to load schema-kitchen-sink.graphql") } query := string(b) astDoc := parse(t, query) expected := `type Foo implements Bar { one: Type two(argument: InputType!): Type three(argument: InputType, other: String): Int four(argument: String = "string"): String five(argument: [String] = ["string", "string"]): String six(argument: InputType = {key: "value"}): Type } interface Bar { one: Type four(argument: String = "string"): String } union Feed = Story | Article | Advert scalar CustomScalar enum Site { DESKTOP MOBILE } input InputType { key: String! answer: Int = 42 } extend type Foo { seven(argument: [String]): Type } ` results := printer.Print(astDoc) if !reflect.DeepEqual(expected, results) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(results, expected)) } }
func TestPrinter_DoesNotAlterAST(t *testing.T) { b, err := ioutil.ReadFile("./../parser/kitchen-sink.graphql") if err != nil { t.Fatalf("unable to load kitchen-sink.graphql") } query := string(b) astDoc := parse(t, query) astDocBefore := testutil.ASTToJSON(t, astDoc) _ = printer.Print(astDoc) astDocAfter := testutil.ASTToJSON(t, astDoc) _ = testutil.ASTToJSON(t, astDoc) if !reflect.DeepEqual(astDocAfter, astDocBefore) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(astDocAfter, astDocBefore)) } }
func init() { __TypeKind = NewGraphQLEnumType(GraphQLEnumTypeConfig{ Name: "__TypeKind", Description: "An enum describing what kind of type a given __Type is", Values: GraphQLEnumValueConfigMap{ "SCALAR": &GraphQLEnumValueConfig{ Value: TypeKindScalar, Description: "Indicates this type is a scalar.", }, "OBJECT": &GraphQLEnumValueConfig{ Value: TypeKindObject, Description: "Indicates this type is an object. " + "`fields` and `interfaces` are valid fields.", }, "INTERFACE": &GraphQLEnumValueConfig{ Value: TypeKindInterface, Description: "Indicates this type is an interface. " + "`fields` and `possibleTypes` are valid fields.", }, "UNION": &GraphQLEnumValueConfig{ Value: TypeKindUnion, Description: "Indicates this type is a union. " + "`possibleTypes` is a valid field.", }, "ENUM": &GraphQLEnumValueConfig{ Value: TypeKindEnum, Description: "Indicates this type is an enum. " + "`enumValues` is a valid field.", }, "INPUT_OBJECT": &GraphQLEnumValueConfig{ Value: TypeKindInputObject, Description: "Indicates this type is an input object. " + "`inputFields` is a valid field.", }, "LIST": &GraphQLEnumValueConfig{ Value: TypeKindList, Description: "Indicates this type is a list. " + "`ofType` is a valid field.", }, "NON_NULL": &GraphQLEnumValueConfig{ Value: TypeKindNonNull, Description: "Indicates this type is a non-null. " + "`ofType` is a valid field.", }, }, }) // Note: some fields (for e.g "fields", "interfaces") are defined later due to cyclic reference __Type = NewGraphQLObjectType(GraphQLObjectTypeConfig{ Name: "__Type", Fields: GraphQLFieldConfigMap{ "kind": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(__TypeKind), Resolve: func(p GQLFRParams) interface{} { switch p.Source.(type) { case *GraphQLScalarType: return TypeKindScalar case *GraphQLObjectType: return TypeKindObject case *GraphQLInterfaceType: return TypeKindInterface case *GraphQLUnionType: return TypeKindUnion case *GraphQLEnumType: return TypeKindEnum case *GraphQLInputObjectType: return TypeKindInputObject case *GraphQLList: return TypeKindList case *GraphQLNonNull: return TypeKindNonNull } panic(fmt.Sprintf("Unknown kind of type: %v", p.Source)) }, }, "name": &GraphQLFieldConfig{ Type: GraphQLString, }, "description": &GraphQLFieldConfig{ Type: GraphQLString, }, "fields": &GraphQLFieldConfig{}, "interfaces": &GraphQLFieldConfig{}, "possibleTypes": &GraphQLFieldConfig{}, "enumValues": &GraphQLFieldConfig{}, "inputFields": &GraphQLFieldConfig{}, "ofType": &GraphQLFieldConfig{}, }, }) __InputValue = NewGraphQLObjectType(GraphQLObjectTypeConfig{ Name: "__InputValue", Fields: GraphQLFieldConfigMap{ "name": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLString), }, "description": &GraphQLFieldConfig{ Type: GraphQLString, }, "type": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(__Type), }, "defaultValue": &GraphQLFieldConfig{ Type: GraphQLString, Resolve: func(p GQLFRParams) interface{} { if inputVal, ok := p.Source.(*GraphQLArgument); ok { if inputVal.DefaultValue == nil { return nil } astVal := astFromValue(inputVal.DefaultValue, inputVal) return printer.Print(astVal) } if inputVal, ok := p.Source.(*InputObjectField); ok { if inputVal.DefaultValue == nil { return nil } astVal := astFromValue(inputVal.DefaultValue, inputVal) return printer.Print(astVal) } return nil }, }, }, }) __Field = NewGraphQLObjectType(GraphQLObjectTypeConfig{ Name: "__Field", Fields: GraphQLFieldConfigMap{ "name": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLString), }, "description": &GraphQLFieldConfig{ Type: GraphQLString, }, "args": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(NewGraphQLList(NewGraphQLNonNull(__InputValue))), Resolve: func(p GQLFRParams) interface{} { if field, ok := p.Source.(*GraphQLFieldDefinition); ok { return field.Args } return []interface{}{} }, }, "type": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(__Type), }, "isDeprecated": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLBoolean), Resolve: func(p GQLFRParams) interface{} { if field, ok := p.Source.(*GraphQLFieldDefinition); ok { return (field.DeprecationReason != "") } return false }, }, "deprecationReason": &GraphQLFieldConfig{ Type: GraphQLString, }, }, }) __Directive = NewGraphQLObjectType(GraphQLObjectTypeConfig{ Name: "__Directive", Fields: GraphQLFieldConfigMap{ "name": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLString), }, "description": &GraphQLFieldConfig{ Type: GraphQLString, }, "args": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(NewGraphQLList( NewGraphQLNonNull(__InputValue), )), }, "onOperation": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLBoolean), }, "onFragment": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLBoolean), }, "onField": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLBoolean), }, }, }) __Schema = NewGraphQLObjectType(GraphQLObjectTypeConfig{ Name: "__Schema", Description: `A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query and mutation operations.`, Fields: GraphQLFieldConfigMap{ "types": &GraphQLFieldConfig{ Description: "A list of all types supported by this server.", Type: NewGraphQLNonNull(NewGraphQLList( NewGraphQLNonNull(__Type), )), Resolve: func(p GQLFRParams) interface{} { if schema, ok := p.Source.(GraphQLSchema); ok { results := []GraphQLType{} for _, ttype := range schema.GetTypeMap() { results = append(results, ttype) } return results } return []GraphQLType{} }, }, "queryType": &GraphQLFieldConfig{ Description: "The type that query operations will be rooted at.", Type: NewGraphQLNonNull(__Type), Resolve: func(p GQLFRParams) interface{} { if schema, ok := p.Source.(GraphQLSchema); ok { return schema.GetQueryType() } return nil }, }, "mutationType": &GraphQLFieldConfig{ Description: `If this server supports mutation, the type that ` + `mutation operations will be rooted at.`, Type: __Type, Resolve: func(p GQLFRParams) interface{} { if schema, ok := p.Source.(GraphQLSchema); ok { if schema.GetMutationType() != nil { return schema.GetMutationType() } } return nil }, }, "directives": &GraphQLFieldConfig{ Description: `A list of all directives supported by this server.`, Type: NewGraphQLNonNull(NewGraphQLList( NewGraphQLNonNull(__Directive), )), Resolve: func(p GQLFRParams) interface{} { if schema, ok := p.Source.(GraphQLSchema); ok { return schema.GetDirectives() } return nil }, }, }, }) __EnumValue = NewGraphQLObjectType(GraphQLObjectTypeConfig{ Name: "__EnumValue", Fields: GraphQLFieldConfigMap{ "name": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLString), }, "description": &GraphQLFieldConfig{ Type: GraphQLString, }, "isDeprecated": &GraphQLFieldConfig{ Type: NewGraphQLNonNull(GraphQLBoolean), Resolve: func(p GQLFRParams) interface{} { if field, ok := p.Source.(*GraphQLEnumValueDefinition); ok { return (field.DeprecationReason != "") } return false }, }, "deprecationReason": &GraphQLFieldConfig{ Type: GraphQLString, }, }, }) // Again, adding field configs to __Type that have cyclic reference here // because golang don't like them too much during init/compile-time __Type.AddFieldConfig("fields", &GraphQLFieldConfig{ Type: NewGraphQLList(NewGraphQLNonNull(__Field)), Args: GraphQLFieldConfigArgumentMap{ "includeDeprecated": &GraphQLArgumentConfig{ Type: GraphQLBoolean, DefaultValue: false, }, }, Resolve: func(p GQLFRParams) interface{} { includeDeprecated, _ := p.Args["includeDeprecated"].(bool) switch ttype := p.Source.(type) { case *GraphQLObjectType: if ttype == nil { return nil } fields := []*GraphQLFieldDefinition{} for _, field := range ttype.GetFields() { if !includeDeprecated && field.DeprecationReason != "" { continue } fields = append(fields, field) } return fields case *GraphQLInterfaceType: if ttype == nil { return nil } fields := []*GraphQLFieldDefinition{} for _, field := range ttype.GetFields() { if !includeDeprecated && field.DeprecationReason != "" { continue } fields = append(fields, field) } return fields } return nil }, }) __Type.AddFieldConfig("interfaces", &GraphQLFieldConfig{ Type: NewGraphQLList(NewGraphQLNonNull(__Type)), Resolve: func(p GQLFRParams) interface{} { switch ttype := p.Source.(type) { case *GraphQLObjectType: return ttype.GetInterfaces() } return nil }, }) __Type.AddFieldConfig("possibleTypes", &GraphQLFieldConfig{ Type: NewGraphQLList(NewGraphQLNonNull(__Type)), Resolve: func(p GQLFRParams) interface{} { switch ttype := p.Source.(type) { case *GraphQLInterfaceType: return ttype.GetPossibleTypes() case *GraphQLUnionType: return ttype.GetPossibleTypes() } return nil }, }) __Type.AddFieldConfig("enumValues", &GraphQLFieldConfig{ Type: NewGraphQLList(NewGraphQLNonNull(__EnumValue)), Args: GraphQLFieldConfigArgumentMap{ "includeDeprecated": &GraphQLArgumentConfig{ Type: GraphQLBoolean, DefaultValue: false, }, }, Resolve: func(p GQLFRParams) interface{} { includeDeprecated, _ := p.Args["includeDeprecated"].(bool) switch ttype := p.Source.(type) { case *GraphQLEnumType: if includeDeprecated { return ttype.GetValues() } values := []*GraphQLEnumValueDefinition{} for _, value := range ttype.GetValues() { if value.DeprecationReason != "" { continue } values = append(values, value) } return values } return nil }, }) __Type.AddFieldConfig("inputFields", &GraphQLFieldConfig{ Type: NewGraphQLList(NewGraphQLNonNull(__InputValue)), Resolve: func(p GQLFRParams) interface{} { switch ttype := p.Source.(type) { case *GraphQLInputObjectType: fields := []*InputObjectField{} for _, field := range ttype.GetFields() { fields = append(fields, field) } return fields } return nil }, }) __Type.AddFieldConfig("ofType", &GraphQLFieldConfig{ Type: __Type, }) /** * Note that these are GraphQLFieldDefinition and not GraphQLFieldConfig, * so the format for args is different. */ SchemaMetaFieldDef = &GraphQLFieldDefinition{ Name: "__schema", Type: NewGraphQLNonNull(__Schema), Description: "Access the current type schema of this server.", Args: []*GraphQLArgument{}, Resolve: func(p GQLFRParams) interface{} { return p.Info.Schema }, } TypeMetaFieldDef = &GraphQLFieldDefinition{ Name: "__type", Type: __Type, Description: "Request the type information of a single type.", Args: []*GraphQLArgument{ &GraphQLArgument{ Name: "name", Type: NewGraphQLNonNull(GraphQLString), }, }, Resolve: func(p GQLFRParams) interface{} { name, ok := p.Args["name"].(string) if !ok { return nil } return p.Info.Schema.GetType(name) }, } TypeNameMetaFieldDef = &GraphQLFieldDefinition{ Name: "__typename", Type: NewGraphQLNonNull(GraphQLString), Description: "The name of the current Object type at runtime.", Args: []*GraphQLArgument{}, Resolve: func(p GQLFRParams) interface{} { return p.Info.ParentType.GetName() }, } }