func TestTypeSystem_InterfaceTypesMustBeResolvable_AcceptsAnInterfaceTypeDefiningResolveTypeWithImplementingTypeDefiningIsTypeOf(t *testing.T) { anotherInterfaceType := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "AnotherInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) _, err := schemaWithFieldType(types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "SomeObject", Interfaces: []*types.GraphQLInterfaceType{anotherInterfaceType}, IsTypeOf: func(value interface{}, info types.GraphQLResolveInfo) bool { return true }, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, })) if err != nil { t.Fatalf("unexpected error: %v", err) } }
func TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectWithADifferentlyModifiedInterfaceFieldType(t *testing.T) { anotherInterface := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "AnotherInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "field": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) anotherObject := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "AnotherObject", Interfaces: []*types.GraphQLInterfaceType{anotherInterface}, Fields: types.GraphQLFieldConfigMap{ "field": &types.GraphQLFieldConfig{ Type: types.NewGraphQLNonNull(types.GraphQLString), }, }, }) _, err := schemaWithObjectFieldOfType(anotherObject) expectedError := `AnotherInterface.field expects type "String" but AnotherObject.field provides type "String!".` if err == nil || err.Error() != expectedError { t.Fatalf("Expected error: %v, got %v", expectedError, err) } }
func TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWithAnEquivalentlyModifiedInterfaceField(t *testing.T) { anotherInterface := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "AnotherInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "field": &types.GraphQLFieldConfig{ Type: types.NewGraphQLNonNull(types.NewGraphQLList(types.GraphQLString)), }, }, }) anotherObject := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "AnotherObject", Interfaces: []*types.GraphQLInterfaceType{anotherInterface}, Fields: types.GraphQLFieldConfigMap{ "field": &types.GraphQLFieldConfig{ Type: types.NewGraphQLNonNull(types.NewGraphQLList(types.GraphQLString)), }, }, }) _, err := schemaWithObjectFieldOfType(anotherObject) if err != nil { t.Fatalf(`unexpected error: %v for type "%v"`, err, anotherObject) } }
func TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectMissingAnInterfaceArgument(t *testing.T) { anotherInterface := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "AnotherInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "field": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Args: types.GraphQLFieldConfigArgumentMap{ "input": &types.GraphQLArgumentConfig{ Type: types.GraphQLString, }, }, }, }, }) anotherObject := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "AnotherObject", Interfaces: []*types.GraphQLInterfaceType{anotherInterface}, Fields: types.GraphQLFieldConfigMap{ "field": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) _, err := schemaWithObjectFieldOfType(anotherObject) expectedError := `AnotherInterface.field expects argument "input" but AnotherObject.field does not provide it.` if err == nil || err.Error() != expectedError { t.Fatalf("Expected error: %v, got %v", expectedError, err) } }
func TestTypeSystem_ObjectInterfacesMustBeArray_AcceptsAnObjectTypeWithInterfacesAsFunctionReturningAnArray(t *testing.T) { anotherInterfaceType := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "AnotherInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) _, err := schemaWithFieldType(types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "SomeObject", Interfaces: []*types.GraphQLInterfaceType{anotherInterfaceType}, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, })) if err != nil { t.Fatalf("unexpected error: %v", err) } }
func TestTypeSystem_SchemaMustContainUniquelyNamedTypes_RejectsASchemaWhichHaveSameNamedObjectsImplementingAnInterface(t *testing.T) { anotherInterface := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "AnotherInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) _ = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "BadObject", Interfaces: []*types.GraphQLInterfaceType{ anotherInterface, }, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) _ = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "BadObject", Interfaces: []*types.GraphQLInterfaceType{ anotherInterface, }, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) queryType := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Query", Fields: types.GraphQLFieldConfigMap{ "iface": &types.GraphQLFieldConfig{ Type: anotherInterface, }, }, }) _, err := types.NewGraphQLSchema(types.GraphQLSchemaConfig{ Query: queryType, }) expectedError := `Schema must contain unique named types but contains multiple types named "BadObject".` if err == nil || err.Error() != expectedError { t.Fatalf("Expected error: %v, got %v", expectedError, err) } }
func TestTypeSystem_ObjectsCanOnlyImplementInterfaces_AcceptsAnObjectImplementingAnInterface(t *testing.T) { anotherInterfaceType := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "AnotherInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) _, err := schemaWithObjectImplementingType(anotherInterfaceType) if err != nil { t.Fatalf(`unexpected error: %v"`, err) } }
func TestTypeSystem_DefinitionExample_IncludesInterfacesThunkSubtypesInTheTypeMap(t *testing.T) { someInterface := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "SomeInterface", Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLInt, }, }, }) someSubType := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "SomeSubtype", Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLInt, }, }, Interfaces: (types.GraphQLInterfacesThunk)(func() []*types.GraphQLInterfaceType { return []*types.GraphQLInterfaceType{someInterface} }), IsTypeOf: func(value interface{}, info types.GraphQLResolveInfo) bool { return true }, }) schema, err := types.NewGraphQLSchema(types.GraphQLSchemaConfig{ Query: types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Query", Fields: types.GraphQLFieldConfigMap{ "iface": &types.GraphQLFieldConfig{ Type: someInterface, }, }, }), }) if err != nil { t.Fatalf("unexpected error, got: %v", err) } if schema.GetType("SomeSubtype") != someSubType { t.Fatalf(`schema.GetType("SomeSubtype") expected to equal someSubType, got: %v`, schema.GetType("SomeSubtype")) } }
func schemaWithInterfaceFieldOfType(ttype types.GraphQLType) (types.GraphQLSchema, error) { badInterfaceType := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "BadInterface", Fields: types.GraphQLFieldConfigMap{ "badField": &types.GraphQLFieldConfig{ Type: ttype, }, }, }) return types.NewGraphQLSchema(types.GraphQLSchemaConfig{ Query: types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Query", Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: badInterfaceType, }, }, }), }) }
/* Given a function to map from an ID to an underlying object, and a function to map from an underlying object to the concrete GraphQLObjectType it corresponds to, constructs a `Node` interface that objects can implement, and a field config for a `node` root field. If the typeResolver is omitted, object resolution on the interface will be handled with the `isTypeOf` method on object types, as with any GraphQL interface without a provided `resolveType` method. */ func NewNodeDefinitions(config NodeDefinitionsConfig) *NodeDefinitions { nodeInterface := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "Node", Description: "An object with an ID", Fields: types.GraphQLFieldConfigMap{ "id": &types.GraphQLFieldConfig{ Type: types.NewGraphQLNonNull(types.GraphQLID), Description: "The id of the object", }, }, ResolveType: config.TypeResolve, }) nodeField := &types.GraphQLFieldConfig{ Name: "Node", Description: "Fetches an object given its ID", Type: nodeInterface, Args: types.GraphQLFieldConfigArgumentMap{ "id": &types.GraphQLArgumentConfig{ Type: types.NewGraphQLNonNull(types.GraphQLID), Description: "The ID of an object", }, }, Resolve: func(p types.GQLFRParams) interface{} { if config.IdFetcher == nil { return nil } id := "" if iid, ok := p.Args["id"]; ok { id = fmt.Sprintf("%v", iid) } fetchedId := config.IdFetcher(id, p.Info) return fetchedId }, } return &NodeDefinitions{ NodeInterface: nodeInterface, NodeField: nodeField, } }
func TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWhichImplementsAnInterfaceAlongWithMoreFields(t *testing.T) { anotherInterface := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "AnotherInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "field": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Args: types.GraphQLFieldConfigArgumentMap{ "input": &types.GraphQLArgumentConfig{ Type: types.GraphQLString, }, }, }, }, }) anotherObject := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "AnotherObject", Interfaces: []*types.GraphQLInterfaceType{anotherInterface}, Fields: types.GraphQLFieldConfigMap{ "field": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Args: types.GraphQLFieldConfigArgumentMap{ "input": &types.GraphQLArgumentConfig{ Type: types.GraphQLString, }, }, }, "anotherfield": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) _, err := schemaWithObjectFieldOfType(anotherObject) if err != nil { t.Fatalf(`unexpected error: %v for type "%v"`, err, anotherObject) } }
}) var someUnionType = types.NewGraphQLUnionType(types.GraphQLUnionTypeConfig{ Name: "SomeUnion", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Types: []*types.GraphQLObjectType{ someObjectType, }, }) var someInterfaceType = types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "SomeInterface", ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { return nil }, Fields: types.GraphQLFieldConfigMap{ "f": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) var someEnumType = types.NewGraphQLEnumType(types.GraphQLEnumTypeConfig{ Name: "SomeEnum", Values: types.GraphQLEnumValueConfigMap{ "ONLY": &types.GraphQLEnumValueConfig{}, }, }) var someInputObject = types.NewGraphQLInputObjectType(types.InputObjectConfig{ Name: "SomeInputObject", Fields: types.InputObjectConfigFieldMap{ "f": &types.InputObjectFieldConfig{
Name: "Mutation", Fields: types.GraphQLFieldConfigMap{ "writeArticle": &types.GraphQLFieldConfig{ Type: blogArticle, }, }, }) var objectType = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Object", IsTypeOf: func(value interface{}, info types.GraphQLResolveInfo) bool { return true }, }) var interfaceType = types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "Interface", }) var unionType = types.NewGraphQLUnionType(types.GraphQLUnionTypeConfig{ Name: "Union", Types: []*types.GraphQLObjectType{ objectType, }, }) var enumType = types.NewGraphQLEnumType(types.GraphQLEnumTypeConfig{ Name: "Enum", Values: types.GraphQLEnumValueConfigMap{ "foo": &types.GraphQLEnumValueConfig{}, }, }) var inputObjectType = types.NewGraphQLInputObjectType(types.InputObjectConfig{ Name: "InputObject",
func init() { Luke = StarWarsChar{ Id: "1000", Name: "Luke Skywalker", AppearsIn: []int{4, 5, 6}, HomePlanet: "Tatooine", } Vader = StarWarsChar{ Id: "1001", Name: "Darth Vader", AppearsIn: []int{4, 5, 6}, HomePlanet: "Tatooine", } Han = StarWarsChar{ Id: "1002", Name: "Han Solo", AppearsIn: []int{4, 5, 6}, } Leia = StarWarsChar{ Id: "1003", Name: "Leia Organa", AppearsIn: []int{4, 5, 6}, HomePlanet: "Alderaa", } Tarkin = StarWarsChar{ Id: "1004", Name: "Wilhuff Tarkin", AppearsIn: []int{4}, } Threepio = StarWarsChar{ Id: "2000", Name: "C-3PO", AppearsIn: []int{4, 5, 6}, PrimaryFunction: "Protocol", } Artoo = StarWarsChar{ Id: "2001", Name: "R2-D2", AppearsIn: []int{4, 5, 6}, PrimaryFunction: "Astromech", } Luke.Friends = append(Luke.Friends, []StarWarsChar{Han, Leia, Threepio, Artoo}...) Vader.Friends = append(Luke.Friends, []StarWarsChar{Tarkin}...) Han.Friends = append(Han.Friends, []StarWarsChar{Luke, Leia, Artoo}...) Leia.Friends = append(Leia.Friends, []StarWarsChar{Luke, Han, Threepio, Artoo}...) Tarkin.Friends = append(Tarkin.Friends, []StarWarsChar{Vader}...) Threepio.Friends = append(Threepio.Friends, []StarWarsChar{Luke, Han, Leia, Artoo}...) Artoo.Friends = append(Artoo.Friends, []StarWarsChar{Luke, Han, Leia}...) HumanData = map[int]StarWarsChar{ 1000: Luke, 1001: Vader, 1002: Han, 1003: Leia, 1004: Tarkin, } DroidData = map[int]StarWarsChar{ 2000: Threepio, 2001: Artoo, } episodeEnum := types.NewGraphQLEnumType(types.GraphQLEnumTypeConfig{ Name: "Episode", Description: "One of the films in the Star Wars Trilogy", Values: types.GraphQLEnumValueConfigMap{ "NEWHOPE": &types.GraphQLEnumValueConfig{ Value: 4, Description: "Released in 1977.", }, "EMPIRE": &types.GraphQLEnumValueConfig{ Value: 5, Description: "Released in 1980.", }, "JEDI": &types.GraphQLEnumValueConfig{ Value: 6, Description: "Released in 1983.", }, }, }) characterInterface := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "Character", Description: "A character in the Star Wars Trilogy", Fields: types.GraphQLFieldConfigMap{ "id": &types.GraphQLFieldConfig{ Type: types.NewGraphQLNonNull(types.GraphQLString), Description: "The id of the character.", }, "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Description: "The name of the character.", }, "appearsIn": &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(episodeEnum), Description: "Which movies they appear in.", }, }, ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { if character, ok := value.(StarWarsChar); ok { id, _ := strconv.Atoi(character.Id) human := GetHuman(id) if human.Id != "" { return humanType } } return droidType }, }) characterInterface.AddFieldConfig("friends", &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(characterInterface), Description: "The friends of the character, or an empty list if they have none.", }) humanType = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Human", Description: "A humanoid creature in the Star Wars universe.", Fields: types.GraphQLFieldConfigMap{ "id": &types.GraphQLFieldConfig{ Type: types.NewGraphQLNonNull(types.GraphQLString), Description: "The id of the human.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if human, ok := p.Source.(StarWarsChar); ok { return human.Id } return nil }, }, "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Description: "The name of the human.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if human, ok := p.Source.(StarWarsChar); ok { return human.Name } return nil }, }, "friends": &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(characterInterface), Description: "The friends of the human, or an empty list if they have none.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if human, ok := p.Source.(StarWarsChar); ok { return human.Friends } return []interface{}{} }, }, "appearsIn": &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(episodeEnum), Description: "Which movies they appear in.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if human, ok := p.Source.(StarWarsChar); ok { return human.AppearsIn } return nil }, }, "homePlanet": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Description: "The home planet of the human, or null if unknown.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if human, ok := p.Source.(StarWarsChar); ok { return human.HomePlanet } return nil }, }, }, Interfaces: []*types.GraphQLInterfaceType{ characterInterface, }, }) droidType = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Droid", Description: "A mechanical creature in the Star Wars universe.", Fields: types.GraphQLFieldConfigMap{ "id": &types.GraphQLFieldConfig{ Type: types.NewGraphQLNonNull(types.GraphQLString), Description: "The id of the droid.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if droid, ok := p.Source.(StarWarsChar); ok { return droid.Id } return nil }, }, "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Description: "The name of the droid.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if droid, ok := p.Source.(StarWarsChar); ok { return droid.Name } return nil }, }, "friends": &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(characterInterface), Description: "The friends of the droid, or an empty list if they have none.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if droid, ok := p.Source.(StarWarsChar); ok { friends := []map[string]interface{}{} for _, friend := range droid.Friends { friends = append(friends, map[string]interface{}{ "name": friend.Name, "id": friend.Id, }) } return droid.Friends } return []interface{}{} }, }, "appearsIn": &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(episodeEnum), Description: "Which movies they appear in.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if droid, ok := p.Source.(StarWarsChar); ok { return droid.AppearsIn } return nil }, }, "primaryFunction": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Description: "The primary function of the droid.", Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} { if droid, ok := p.Source.(StarWarsChar); ok { return droid.PrimaryFunction } return nil }, }, }, Interfaces: []*types.GraphQLInterfaceType{ characterInterface, }, }) queryType := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Query", Fields: types.GraphQLFieldConfigMap{ "hero": &types.GraphQLFieldConfig{ Type: characterInterface, Args: types.GraphQLFieldConfigArgumentMap{ "episode": &types.GraphQLArgumentConfig{ Description: "If omitted, returns the hero of the whole saga. If " + "provided, returns the hero of that particular episode.", Type: episodeEnum, }, }, Resolve: func(ctx context.Context, p types.GQLFRParams) (r interface{}) { return GetHero(p.Args["episode"]) }, }, "human": &types.GraphQLFieldConfig{ Type: humanType, Args: types.GraphQLFieldConfigArgumentMap{ "id": &types.GraphQLArgumentConfig{ Description: "id of the human", Type: types.NewGraphQLNonNull(types.GraphQLString), }, }, Resolve: func(ctx context.Context, p types.GQLFRParams) (r interface{}) { return GetHuman(p.Args["id"].(int)) }, }, "droid": &types.GraphQLFieldConfig{ Type: droidType, Args: types.GraphQLFieldConfigArgumentMap{ "id": &types.GraphQLArgumentConfig{ Description: "id of the droid", Type: types.NewGraphQLNonNull(types.GraphQLString), }, }, Resolve: func(ctx context.Context, p types.GQLFRParams) (r interface{}) { return GetDroid(p.Args["id"].(int)) }, }, }, }) StarWarsSchema, _ = types.NewGraphQLSchema(types.GraphQLSchemaConfig{ Query: queryType, }) }
func TestUnionIntersectionTypes_GetsExecutionInfoInResolver(t *testing.T) { var encounteredSchema *types.GraphQLSchema var encounteredRootValue interface{} var personType2 *types.GraphQLObjectType namedType2 := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "Named", Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { encounteredSchema = &info.Schema encounteredRootValue = info.RootValue return personType2 }, }) personType2 = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Person", Interfaces: []*types.GraphQLInterfaceType{ namedType2, }, Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, "friends": &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(namedType2), }, }, }) schema2, _ := types.NewGraphQLSchema(types.GraphQLSchemaConfig{ Query: personType2, }) john2 := &testPerson{ Name: "John", Friends: []testNamedType{ liz, }, } doc := `{ name, friends { name } }` expected := &types.GraphQLResult{ Data: map[string]interface{}{ "name": "John", "friends": []interface{}{ map[string]interface{}{ "name": "Liz", }, }, }, } // parse query ast := testutil.Parse(t, doc) // execute ep := executor.ExecuteParams{ Schema: schema2, AST: ast, Root: john2, } result := testutil.Execute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
type testCat2 struct { Name string `json:"name"` Meows bool `json:"meows"` } type testPerson struct { Name string `json:"name"` Pets []testPet `json:"pets"` Friends []testNamedType `json:"friends"` } var namedType = types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "Named", Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) var dogType = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Dog", Interfaces: []*types.GraphQLInterfaceType{ namedType, }, Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, "barks": &types.GraphQLFieldConfig{ Type: types.GraphQLBoolean, },
func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) { var dogType *types.GraphQLObjectType var catType *types.GraphQLObjectType var humanType *types.GraphQLObjectType petType := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "Pet", Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, ResolveType: func(value interface{}, info types.GraphQLResolveInfo) *types.GraphQLObjectType { if _, ok := value.(*testCat); ok { return catType } if _, ok := value.(*testDog); ok { return dogType } if _, ok := value.(*testHuman); ok { return humanType } return nil }, }) humanType = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Human", Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Resolve: func(p types.GQLFRParams) interface{} { if human, ok := p.Source.(*testHuman); ok { return human.Name } return nil }, }, }, }) dogType = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Dog", Interfaces: []*types.GraphQLInterfaceType{ petType, }, IsTypeOf: func(value interface{}, info types.GraphQLResolveInfo) bool { _, ok := value.(*testDog) return ok }, Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Resolve: func(p types.GQLFRParams) interface{} { if dog, ok := p.Source.(*testDog); ok { return dog.Name } return nil }, }, "woofs": &types.GraphQLFieldConfig{ Type: types.GraphQLBoolean, Resolve: func(p types.GQLFRParams) interface{} { if dog, ok := p.Source.(*testDog); ok { return dog.Woofs } return nil }, }, }, }) catType = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Cat", Interfaces: []*types.GraphQLInterfaceType{ petType, }, IsTypeOf: func(value interface{}, info types.GraphQLResolveInfo) bool { _, ok := value.(*testCat) return ok }, Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Resolve: func(p types.GQLFRParams) interface{} { if cat, ok := p.Source.(*testCat); ok { return cat.Name } return nil }, }, "meows": &types.GraphQLFieldConfig{ Type: types.GraphQLBoolean, Resolve: func(p types.GQLFRParams) interface{} { if cat, ok := p.Source.(*testCat); ok { return cat.Meows } return nil }, }, }, }) schema, err := types.NewGraphQLSchema(types.GraphQLSchemaConfig{ Query: types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Query", Fields: types.GraphQLFieldConfigMap{ "pets": &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(petType), Resolve: func(p types.GQLFRParams) interface{} { return []interface{}{ &testDog{"Odie", true}, &testCat{"Garfield", false}, &testHuman{"Jon"}, } }, }, }, }), }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } query := `{ pets { name ... on Dog { woofs } ... on Cat { meows } } }` expected := &types.GraphQLResult{ Data: map[string]interface{}{ "pets": []interface{}{ map[string]interface{}{ "name": "Odie", "woofs": bool(true), }, map[string]interface{}{ "name": "Garfield", "meows": bool(false), }, nil, }, }, Errors: []graphqlerrors.GraphQLFormattedError{ graphqlerrors.GraphQLFormattedError{ Message: `Runtime Object type "Human" is not a possible type for "Pet".`, Locations: []location.SourceLocation{}, }, }, } resultChannel := make(chan *types.GraphQLResult) go gql.Graphql(gql.GraphqlParams{ Schema: schema, RequestString: query, }, resultChannel) result := <-resultChannel if len(result.Errors) == 0 { t.Fatalf("wrong result, expected errors: %v, got: %v", len(expected.Errors), len(result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestIsTypeOfUsedToResolveRuntimeTypeForInterface(t *testing.T) { petType := types.NewGraphQLInterfaceType(types.GraphQLInterfaceTypeConfig{ Name: "Pet", Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, }, }, }) // ie declare that Dog belongs to Pet interface _ = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Dog", Interfaces: []*types.GraphQLInterfaceType{ petType, }, IsTypeOf: func(value interface{}, info types.GraphQLResolveInfo) bool { _, ok := value.(*testDog) return ok }, Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Resolve: func(p types.GQLFRParams) interface{} { if dog, ok := p.Source.(*testDog); ok { return dog.Name } return nil }, }, "woofs": &types.GraphQLFieldConfig{ Type: types.GraphQLBoolean, Resolve: func(p types.GQLFRParams) interface{} { if dog, ok := p.Source.(*testDog); ok { return dog.Woofs } return nil }, }, }, }) // ie declare that Cat belongs to Pet interface _ = types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Cat", Interfaces: []*types.GraphQLInterfaceType{ petType, }, IsTypeOf: func(value interface{}, info types.GraphQLResolveInfo) bool { _, ok := value.(*testCat) return ok }, Fields: types.GraphQLFieldConfigMap{ "name": &types.GraphQLFieldConfig{ Type: types.GraphQLString, Resolve: func(p types.GQLFRParams) interface{} { if cat, ok := p.Source.(*testCat); ok { return cat.Name } return nil }, }, "meows": &types.GraphQLFieldConfig{ Type: types.GraphQLBoolean, Resolve: func(p types.GQLFRParams) interface{} { if cat, ok := p.Source.(*testCat); ok { return cat.Meows } return nil }, }, }, }) schema, err := types.NewGraphQLSchema(types.GraphQLSchemaConfig{ Query: types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{ Name: "Query", Fields: types.GraphQLFieldConfigMap{ "pets": &types.GraphQLFieldConfig{ Type: types.NewGraphQLList(petType), Resolve: func(p types.GQLFRParams) interface{} { return []interface{}{ &testDog{"Odie", true}, &testCat{"Garfield", false}, } }, }, }, }), }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } query := `{ pets { name ... on Dog { woofs } ... on Cat { meows } } }` expected := &types.GraphQLResult{ Data: map[string]interface{}{ "pets": []interface{}{ map[string]interface{}{ "name": "Odie", "woofs": bool(true), }, map[string]interface{}{ "name": "Garfield", "meows": bool(false), }, }, }, Errors: nil, } resultChannel := make(chan *types.GraphQLResult) go gql.Graphql(gql.GraphqlParams{ Schema: schema, RequestString: query, }, resultChannel) result := <-resultChannel if len(result.Errors) != 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }