func TestTypeSystem_DefinitionExample_IncludesNestedInputObjectsInTheMap(t *testing.T) { nestedInputObject := graphql.NewInputObject(graphql.InputObjectConfig{ Name: "NestedInputObject", Fields: graphql.InputObjectConfigFieldMap{ "value": &graphql.InputObjectFieldConfig{ Type: graphql.String, }, }, }) someInputObject := graphql.NewInputObject(graphql.InputObjectConfig{ Name: "SomeInputObject", Fields: graphql.InputObjectConfigFieldMap{ "nested": &graphql.InputObjectFieldConfig{ Type: nestedInputObject, }, }, }) someMutation := graphql.NewObject(graphql.ObjectConfig{ Name: "SomeMutation", Fields: graphql.Fields{ "mutateSomething": &graphql.Field{ Type: blogArticle, Args: graphql.FieldConfigArgument{ "input": &graphql.ArgumentConfig{ Type: someInputObject, }, }, }, }, }) someSubscription := graphql.NewObject(graphql.ObjectConfig{ Name: "SomeSubscription", Fields: graphql.Fields{ "subscribeToSomething": &graphql.Field{ Type: blogArticle, Args: graphql.FieldConfigArgument{ "input": &graphql.ArgumentConfig{ Type: someInputObject, }, }, }, }, }) schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: blogQuery, Mutation: someMutation, Subscription: someSubscription, }) if err != nil { t.Fatalf("unexpected error, got: %v", err) } if schema.Type("NestedInputObject") != nestedInputObject { t.Fatalf(`schema.GetType("NestedInputObject") expected to equal nestedInputObject, got: %v`, schema.Type("NestedInputObject")) } }
func schemaWithInputFieldOfType(ttype graphql.Type) (graphql.Schema, error) { badInputObject := graphql.NewInputObject(graphql.InputObjectConfig{ Name: "BadInputObject", Fields: graphql.InputObjectConfigFieldMap{ "badField": &graphql.InputObjectFieldConfig{ Type: ttype, }, }, }) return graphql.NewSchema(graphql.SchemaConfig{ Query: graphql.NewObject(graphql.ObjectConfig{ Name: "Query", Fields: graphql.Fields{ "f": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "badArg": &graphql.ArgumentConfig{ Type: badInputObject, }, }, }, }, }), }) }
func TestTypeSystem_InputObjectsMustHaveFields_RejectsAnInputObjectTypeWithMissingFields(t *testing.T) { _, err := schemaWithInputObject(graphql.NewInputObject(graphql.InputObjectConfig{ Name: "SomeInputObject", })) expectedError := "SomeInputObject fields must be an object with field names as keys or a function which return such an object." if err == nil || err.Error() != expectedError { t.Fatalf("Expected error: %v, got %v", expectedError, err) } }
func MutationWithClientMutationID(config MutationConfig) *graphql.Field { augmentedInputFields := config.InputFields if augmentedInputFields == nil { augmentedInputFields = graphql.InputObjectConfigFieldMap{} } augmentedInputFields["clientMutationId"] = &graphql.InputObjectFieldConfig{ Type: graphql.NewNonNull(graphql.String), } augmentedOutputFields := config.OutputFields if augmentedOutputFields == nil { augmentedOutputFields = graphql.Fields{} } augmentedOutputFields["clientMutationId"] = &graphql.Field{ Type: graphql.NewNonNull(graphql.String), } inputType := graphql.NewInputObject(graphql.InputObjectConfig{ Name: config.Name + "Input", Fields: augmentedInputFields, }) outputType := graphql.NewObject(graphql.ObjectConfig{ Name: config.Name + "Payload", Fields: augmentedOutputFields, }) return &graphql.Field{ Name: config.Name, Type: outputType, Args: graphql.FieldConfigArgument{ "input": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(inputType), }, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { if config.MutateAndGetPayload == nil { return nil, nil } input := map[string]interface{}{} if inputVal, ok := p.Args["input"]; ok { if inputVal, ok := inputVal.(map[string]interface{}); ok { input = inputVal } } payload, err := config.MutateAndGetPayload(input, p.Info, p.Context) if err != nil { return nil, err } if clientMutationID, ok := input["clientMutationId"]; ok { payload["clientMutationId"] = clientMutationID } return payload, nil }, } }
func TestTypeSystem_InputObjectsMustHaveFields_AcceptsAnInputObjectTypeWithFields(t *testing.T) { _, err := schemaWithInputObject(graphql.NewInputObject(graphql.InputObjectConfig{ Name: "SomeInputObject", Fields: graphql.InputObjectConfigFieldMap{ "f": &graphql.InputObjectFieldConfig{ Type: graphql.String, }, }, })) if err != nil { t.Fatalf("unexpected error: %v", err) } }
func TestIntrospection_ExecutesAnInputObject(t *testing.T) { testInputObject := graphql.NewInputObject(graphql.InputObjectConfig{ Name: "TestInputObject", Fields: graphql.InputObjectConfigFieldMap{ "a": &graphql.InputObjectFieldConfig{ Type: graphql.String, DefaultValue: "foo", }, "b": &graphql.InputObjectFieldConfig{ Type: graphql.NewList(graphql.String), }, }, }) testType := graphql.NewObject(graphql.ObjectConfig{ Name: "TestType", Fields: graphql.Fields{ "field": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "complex": &graphql.ArgumentConfig{ Type: testInputObject, }, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { return p.Args["complex"], nil }, }, }, }) schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: testType, }) if err != nil { t.Fatalf("Error creating Schema: %v", err.Error()) } query := ` { __schema { types { kind name inputFields { name type { ...TypeRef } defaultValue } } } } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name } } } } ` expectedDataSubSet := map[string]interface{}{ "__schema": map[string]interface{}{ "types": []interface{}{ map[string]interface{}{ "kind": "INPUT_OBJECT", "name": "TestInputObject", "inputFields": []interface{}{ map[string]interface{}{ "name": "a", "type": map[string]interface{}{ "kind": "SCALAR", "name": "String", "ofType": nil, }, "defaultValue": `"foo"`, }, map[string]interface{}{ "name": "b", "type": map[string]interface{}{ "kind": "LIST", "name": nil, "ofType": map[string]interface{}{ "kind": "SCALAR", "name": "String", "ofType": nil, }, }, "defaultValue": nil, }, }, }, }, }, } result := g(t, graphql.Params{ Schema: schema, RequestString: query, }) if !testutil.ContainSubset(result.Data.(map[string]interface{}), expectedDataSubSet) { t.Fatalf("unexpected, result does not contain subset of expected data") } }
if astValue, ok := astValue.(string); ok && astValue == "SerializedValue" { return "DeserializedValue" } return nil }, }) var testInputObject *graphql.InputObject = graphql.NewInputObject(graphql.InputObjectConfig{ Name: "TestInputObject", Fields: graphql.InputObjectConfigFieldMap{ "a": &graphql.InputObjectFieldConfig{ Type: graphql.String, }, "b": &graphql.InputObjectFieldConfig{ Type: graphql.NewList(graphql.String), }, "c": &graphql.InputObjectFieldConfig{ Type: graphql.NewNonNull(graphql.String), }, "d": &graphql.InputObjectFieldConfig{ Type: testComplexScalar, }, }, }) var testNestedInputObject *graphql.InputObject = graphql.NewInputObject(graphql.InputObjectConfig{ Name: "TestNestedInputObject", Fields: graphql.InputObjectConfigFieldMap{ "na": &graphql.InputObjectFieldConfig{ Type: graphql.NewNonNull(testInputObject), },
func init() { var beingInterface = graphql.NewInterface(graphql.InterfaceConfig{ Name: "Being", Fields: graphql.Fields{ "name": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "surname": &graphql.ArgumentConfig{ Type: graphql.Boolean, }, }, }, }, }) var petInterface = graphql.NewInterface(graphql.InterfaceConfig{ Name: "Pet", Fields: graphql.Fields{ "name": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "surname": &graphql.ArgumentConfig{ Type: graphql.Boolean, }, }, }, }, }) var canineInterface = graphql.NewInterface(graphql.InterfaceConfig{ Name: "Canine", Fields: graphql.Fields{ "name": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "surname": &graphql.ArgumentConfig{ Type: graphql.Boolean, }, }, }, }, }) var dogCommandEnum = graphql.NewEnum(graphql.EnumConfig{ Name: "DogCommand", Values: graphql.EnumValueConfigMap{ "SIT": &graphql.EnumValueConfig{ Value: 0, }, "HEEL": &graphql.EnumValueConfig{ Value: 1, }, "DOWN": &graphql.EnumValueConfig{ Value: 2, }, }, }) var dogType = graphql.NewObject(graphql.ObjectConfig{ Name: "Dog", IsTypeOf: func(p graphql.IsTypeOfParams) bool { return true }, Fields: graphql.Fields{ "name": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "surname": &graphql.ArgumentConfig{ Type: graphql.Boolean, }, }, }, "nickname": &graphql.Field{ Type: graphql.String, }, "barkVolume": &graphql.Field{ Type: graphql.Int, }, "barks": &graphql.Field{ Type: graphql.Boolean, }, "doesKnowCommand": &graphql.Field{ Type: graphql.Boolean, Args: graphql.FieldConfigArgument{ "dogCommand": &graphql.ArgumentConfig{ Type: dogCommandEnum, }, }, }, "isHousetrained": &graphql.Field{ Type: graphql.Boolean, Args: graphql.FieldConfigArgument{ "atOtherHomes": &graphql.ArgumentConfig{ Type: graphql.Boolean, DefaultValue: true, }, }, }, "isAtLocation": &graphql.Field{ Type: graphql.Boolean, Args: graphql.FieldConfigArgument{ "x": &graphql.ArgumentConfig{ Type: graphql.Int, }, "y": &graphql.ArgumentConfig{ Type: graphql.Int, }, }, }, }, Interfaces: []*graphql.Interface{ beingInterface, petInterface, canineInterface, }, }) var furColorEnum = graphql.NewEnum(graphql.EnumConfig{ Name: "FurColor", Values: graphql.EnumValueConfigMap{ "BROWN": &graphql.EnumValueConfig{ Value: 0, }, "BLACK": &graphql.EnumValueConfig{ Value: 1, }, "TAN": &graphql.EnumValueConfig{ Value: 2, }, "SPOTTED": &graphql.EnumValueConfig{ Value: 3, }, }, }) var catType = graphql.NewObject(graphql.ObjectConfig{ Name: "Cat", IsTypeOf: func(p graphql.IsTypeOfParams) bool { return true }, Fields: graphql.Fields{ "name": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "surname": &graphql.ArgumentConfig{ Type: graphql.Boolean, }, }, }, "nickname": &graphql.Field{ Type: graphql.String, }, "meowVolume": &graphql.Field{ Type: graphql.Int, }, "meows": &graphql.Field{ Type: graphql.Boolean, }, "furColor": &graphql.Field{ Type: furColorEnum, }, }, Interfaces: []*graphql.Interface{ beingInterface, petInterface, }, }) var catOrDogUnion = graphql.NewUnion(graphql.UnionConfig{ Name: "CatOrDog", Types: []*graphql.Object{ dogType, catType, }, ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { // not used for validation return nil }, }) var intelligentInterface = graphql.NewInterface(graphql.InterfaceConfig{ Name: "Intelligent", Fields: graphql.Fields{ "iq": &graphql.Field{ Type: graphql.Int, }, }, }) var humanType = graphql.NewObject(graphql.ObjectConfig{ Name: "Human", IsTypeOf: func(p graphql.IsTypeOfParams) bool { return true }, Interfaces: []*graphql.Interface{ beingInterface, intelligentInterface, }, Fields: graphql.Fields{ "name": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "surname": &graphql.ArgumentConfig{ Type: graphql.Boolean, }, }, }, "pets": &graphql.Field{ Type: graphql.NewList(petInterface), }, "iq": &graphql.Field{ Type: graphql.Int, }, }, }) humanType.AddFieldConfig("relatives", &graphql.Field{ Type: graphql.NewList(humanType), }) var alienType = graphql.NewObject(graphql.ObjectConfig{ Name: "Alien", IsTypeOf: func(p graphql.IsTypeOfParams) bool { return true }, Interfaces: []*graphql.Interface{ beingInterface, intelligentInterface, }, Fields: graphql.Fields{ "name": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "surname": &graphql.ArgumentConfig{ Type: graphql.Boolean, }, }, }, "iq": &graphql.Field{ Type: graphql.Int, }, "numEyes": &graphql.Field{ Type: graphql.Int, }, }, }) var dogOrHumanUnion = graphql.NewUnion(graphql.UnionConfig{ Name: "DogOrHuman", Types: []*graphql.Object{ dogType, humanType, }, ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { // not used for validation return nil }, }) var humanOrAlienUnion = graphql.NewUnion(graphql.UnionConfig{ Name: "HumanOrAlien", Types: []*graphql.Object{ alienType, humanType, }, ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { // not used for validation return nil }, }) var complexInputObject = graphql.NewInputObject(graphql.InputObjectConfig{ Name: "ComplexInput", Fields: graphql.InputObjectConfigFieldMap{ "requiredField": &graphql.InputObjectFieldConfig{ Type: graphql.NewNonNull(graphql.Boolean), }, "intField": &graphql.InputObjectFieldConfig{ Type: graphql.Int, }, "stringField": &graphql.InputObjectFieldConfig{ Type: graphql.String, }, "booleanField": &graphql.InputObjectFieldConfig{ Type: graphql.Boolean, }, "stringListField": &graphql.InputObjectFieldConfig{ Type: graphql.NewList(graphql.String), }, }, }) var complicatedArgs = graphql.NewObject(graphql.ObjectConfig{ Name: "ComplicatedArgs", // TODO List // TODO Coercion // TODO NotNulls Fields: graphql.Fields{ "intArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "intArg": &graphql.ArgumentConfig{ Type: graphql.Int, }, }, }, "nonNullIntArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "nonNullIntArg": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.Int), }, }, }, "stringArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "stringArg": &graphql.ArgumentConfig{ Type: graphql.String, }, }, }, "booleanArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "booleanArg": &graphql.ArgumentConfig{ Type: graphql.Boolean, }, }, }, "enumArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "enumArg": &graphql.ArgumentConfig{ Type: furColorEnum, }, }, }, "floatArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "floatArg": &graphql.ArgumentConfig{ Type: graphql.Float, }, }, }, "idArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "idArg": &graphql.ArgumentConfig{ Type: graphql.ID, }, }, }, "stringListArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "stringListArg": &graphql.ArgumentConfig{ Type: graphql.NewList(graphql.String), }, }, }, "complexArgField": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "complexArg": &graphql.ArgumentConfig{ Type: complexInputObject, }, }, }, "multipleReqs": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "req1": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.Int), }, "req2": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.Int), }, }, }, "multipleOpts": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "opt1": &graphql.ArgumentConfig{ Type: graphql.Int, DefaultValue: 0, }, "opt2": &graphql.ArgumentConfig{ Type: graphql.Int, DefaultValue: 0, }, }, }, "multipleOptAndReq": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "req1": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.Int), }, "req2": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.Int), }, "opt1": &graphql.ArgumentConfig{ Type: graphql.Int, DefaultValue: 0, }, "opt2": &graphql.ArgumentConfig{ Type: graphql.Int, DefaultValue: 0, }, }, }, }, }) queryRoot := graphql.NewObject(graphql.ObjectConfig{ Name: "QueryRoot", Fields: graphql.Fields{ "human": &graphql.Field{ Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{ Type: graphql.ID, }, }, Type: humanType, }, "alien": &graphql.Field{ Type: alienType, }, "dog": &graphql.Field{ Type: dogType, }, "cat": &graphql.Field{ Type: catType, }, "pet": &graphql.Field{ Type: petInterface, }, "catOrDog": &graphql.Field{ Type: catOrDogUnion, }, "dogOrHuman": &graphql.Field{ Type: dogOrHumanUnion, }, "humanOrAlien": &graphql.Field{ Type: humanOrAlienUnion, }, "complicatedArgs": &graphql.Field{ Type: complicatedArgs, }, }, }) schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: queryRoot, Directives: []*graphql.Directive{ graphql.NewDirective(graphql.DirectiveConfig{ Name: "operationOnly", Locations: []string{graphql.DirectiveLocationQuery}, }), graphql.IncludeDirective, graphql.SkipDirective, }, Types: []graphql.Type{ catType, dogType, humanType, alienType, }, }) if err != nil { panic(err) } TestSchema = &schema }
"f": &graphql.Field{ Type: graphql.String, }, }, }) var someEnumType = graphql.NewEnum(graphql.EnumConfig{ Name: "SomeEnum", Values: graphql.EnumValueConfigMap{ "ONLY": &graphql.EnumValueConfig{}, }, }) var someInputObject = graphql.NewInputObject(graphql.InputObjectConfig{ Name: "SomeInputObject", Fields: graphql.InputObjectConfigFieldMap{ "f": &graphql.InputObjectFieldConfig{ Type: graphql.String, DefaultValue: "Hello", }, }, }) func withModifiers(ttypes []graphql.Type) []graphql.Type { res := ttypes for _, ttype := range ttypes { res = append(res, graphql.NewList(ttype)) } for _, ttype := range ttypes { res = append(res, graphql.NewNonNull(ttype)) } for _, ttype := range ttypes { res = append(res, graphql.NewNonNull(graphql.NewList(ttype)))
func TestTypeSystem_DefinitionExample_DoesNotMutatePassedFieldDefinitions(t *testing.T) { fields := graphql.Fields{ "field1": &graphql.Field{ Type: graphql.String, }, "field2": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{ Type: graphql.String, }, }, }, } testObject1 := graphql.NewObject(graphql.ObjectConfig{ Name: "Test1", Fields: fields, }) testObject2 := graphql.NewObject(graphql.ObjectConfig{ Name: "Test2", Fields: fields, }) if !reflect.DeepEqual(testObject1.Fields(), testObject2.Fields()) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(testObject1.Fields(), testObject2.Fields())) } expectedFields := graphql.Fields{ "field1": &graphql.Field{ Type: graphql.String, }, "field2": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{ Type: graphql.String, }, }, }, } if !reflect.DeepEqual(fields, expectedFields) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expectedFields, fields)) } inputFields := graphql.InputObjectConfigFieldMap{ "field1": &graphql.InputObjectFieldConfig{ Type: graphql.String, }, "field2": &graphql.InputObjectFieldConfig{ Type: graphql.String, }, } expectedInputFields := graphql.InputObjectConfigFieldMap{ "field1": &graphql.InputObjectFieldConfig{ Type: graphql.String, }, "field2": &graphql.InputObjectFieldConfig{ Type: graphql.String, }, } testInputObject1 := graphql.NewInputObject(graphql.InputObjectConfig{ Name: "Test1", Fields: inputFields, }) testInputObject2 := graphql.NewInputObject(graphql.InputObjectConfig{ Name: "Test2", Fields: inputFields, }) if !reflect.DeepEqual(testInputObject1.Fields(), testInputObject2.Fields()) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(testInputObject1.Fields(), testInputObject2.Fields())) } if !reflect.DeepEqual(inputFields, expectedInputFields) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expectedInputFields, fields)) } }
Name: "Interface", }) var unionType = graphql.NewUnion(graphql.UnionConfig{ Name: "Union", Types: []*graphql.Object{ objectType, }, }) var enumType = graphql.NewEnum(graphql.EnumConfig{ Name: "Enum", Values: graphql.EnumValueConfigMap{ "foo": &graphql.EnumValueConfig{}, }, }) var inputObjectType = graphql.NewInputObject(graphql.InputObjectConfig{ Name: "InputObject", }) func init() { blogAuthor.AddFieldConfig("recentArticle", &graphql.Field{ Type: blogArticle, }) } func TestTypeSystem_DefinitionExample_DefinesAQueryOnlySchema(t *testing.T) { blogSchema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: blogQuery, }) if err != nil { t.Fatalf("unexpected error, got: %v", err) }