func schemaWithInputFieldOfType(ttype types.GraphQLType) (types.GraphQLSchema, error) {

	badInputObject := types.NewGraphQLInputObjectType(types.InputObjectConfig{
		Name: "BadInputObject",
		Fields: types.InputObjectConfigFieldMap{
			"badField": &types.InputObjectFieldConfig{
				Type: ttype,
			},
		},
	})
	return types.NewGraphQLSchema(types.GraphQLSchemaConfig{
		Query: types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{
			Name: "Query",
			Fields: types.GraphQLFieldConfigMap{
				"f": &types.GraphQLFieldConfig{
					Type: types.GraphQLString,
					Args: types.GraphQLFieldConfigArgumentMap{
						"badArg": &types.GraphQLArgumentConfig{
							Type: badInputObject,
						},
					},
				},
			},
		}),
	})
}
func TestTypeSystem_InputObjectsMustHaveFields_RejectsAnInputObjectTypeWithMissingFields(t *testing.T) {
	_, err := schemaWithInputObject(types.NewGraphQLInputObjectType(types.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 TestTypeSystem_DefinitionExample_IncludesNestedInputObjectsInTheMap(t *testing.T) {
	nestedInputObject := types.NewGraphQLInputObjectType(types.InputObjectConfig{
		Name: "NestedInputObject",
		Fields: types.InputObjectConfigFieldMap{
			"value": &types.InputObjectFieldConfig{
				Type: types.GraphQLString,
			},
		},
	})
	someInputObject := types.NewGraphQLInputObjectType(types.InputObjectConfig{
		Name: "SomeInputObject",
		Fields: types.InputObjectConfigFieldMap{
			"nested": &types.InputObjectFieldConfig{
				Type: nestedInputObject,
			},
		},
	})
	someMutation := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{
		Name: "SomeMutation",
		Fields: types.GraphQLFieldConfigMap{
			"mutateSomething": &types.GraphQLFieldConfig{
				Type: blogArticle,
				Args: types.GraphQLFieldConfigArgumentMap{
					"input": &types.GraphQLArgumentConfig{
						Type: someInputObject,
					},
				},
			},
		},
	})
	schema, err := types.NewGraphQLSchema(types.GraphQLSchemaConfig{
		Query:    blogQuery,
		Mutation: someMutation,
	})
	if err != nil {
		t.Fatalf("unexpected error, got: %v", err)
	}
	if schema.GetType("NestedInputObject") != nestedInputObject {
		t.Fatalf(`schema.GetType("NestedInputObject") expected to equal nestedInputObject, got: %v`, schema.GetType("NestedInputObject"))
	}
}
func TestTypeSystem_InputObjectsMustHaveFields_AcceptsAnInputObjectTypeWithFields(t *testing.T) {
	_, err := schemaWithInputObject(types.NewGraphQLInputObjectType(types.InputObjectConfig{
		Name: "SomeInputObject",
		Fields: types.InputObjectConfigFieldMap{
			"f": &types.InputObjectFieldConfig{
				Type: types.GraphQLString,
			},
		},
	}))
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
}
func MutationWithClientMutationId(config MutationConfig) *types.GraphQLFieldConfig {

	augmentedInputFields := config.InputFields
	if augmentedInputFields == nil {
		augmentedInputFields = types.InputObjectConfigFieldMap{}
	}
	augmentedInputFields["clientMutationId"] = &types.InputObjectFieldConfig{
		Type: types.NewGraphQLNonNull(types.GraphQLString),
	}
	augmentedOutputFields := config.OutputFields
	if augmentedOutputFields == nil {
		augmentedOutputFields = types.GraphQLFieldConfigMap{}
	}
	augmentedOutputFields["clientMutationId"] = &types.GraphQLFieldConfig{
		Type: types.NewGraphQLNonNull(types.GraphQLString),
	}

	inputType := types.NewGraphQLInputObjectType(types.InputObjectConfig{
		Name:   config.Name + "Input",
		Fields: augmentedInputFields,
	})
	outputType := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{
		Name:   config.Name + "Payload",
		Fields: augmentedOutputFields,
	})
	return &types.GraphQLFieldConfig{
		Type: outputType,
		Args: types.GraphQLFieldConfigArgumentMap{
			"input": &types.GraphQLArgumentConfig{
				Type: types.NewGraphQLNonNull(inputType),
			},
		},
		Resolve: func(p types.GQLFRParams) interface{} {
			if config.MutateAndGetPayload == nil {
				return nil
			}
			input := map[string]interface{}{}
			if inputVal, ok := p.Args["input"]; ok {
				if inputVal, ok := inputVal.(map[string]interface{}); ok {
					input = inputVal
				}
			}
			payload := config.MutateAndGetPayload(input, p.Info)
			if clientMutationId, ok := input["clientMutationId"]; ok {
				payload["clientMutationId"] = clientMutationId
			}
			return payload
		},
	}
}
func TestTypeSystem_DefinitionExample_DoesNotMutatePassedFieldDefinitions(t *testing.T) {
	fields := types.GraphQLFieldConfigMap{
		"field1": &types.GraphQLFieldConfig{
			Type: types.GraphQLString,
		},
		"field2": &types.GraphQLFieldConfig{
			Type: types.GraphQLString,
			Args: types.GraphQLFieldConfigArgumentMap{
				"id": &types.GraphQLArgumentConfig{
					Type: types.GraphQLString,
				},
			},
		},
	}
	testObject1 := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{
		Name:   "Test1",
		Fields: fields,
	})
	testObject2 := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{
		Name:   "Test2",
		Fields: fields,
	})
	if !reflect.DeepEqual(testObject1.GetFields(), testObject2.GetFields()) {
		t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(testObject1.GetFields(), testObject2.GetFields()))
	}

	expectedFields := types.GraphQLFieldConfigMap{
		"field1": &types.GraphQLFieldConfig{
			Type: types.GraphQLString,
		},
		"field2": &types.GraphQLFieldConfig{
			Type: types.GraphQLString,
			Args: types.GraphQLFieldConfigArgumentMap{
				"id": &types.GraphQLArgumentConfig{
					Type: types.GraphQLString,
				},
			},
		},
	}
	if !reflect.DeepEqual(fields, expectedFields) {
		t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expectedFields, fields))
	}

	inputFields := types.InputObjectConfigFieldMap{
		"field1": &types.InputObjectFieldConfig{
			Type: types.GraphQLString,
		},
		"field2": &types.InputObjectFieldConfig{
			Type: types.GraphQLString,
		},
	}
	expectedInputFields := types.InputObjectConfigFieldMap{
		"field1": &types.InputObjectFieldConfig{
			Type: types.GraphQLString,
		},
		"field2": &types.InputObjectFieldConfig{
			Type: types.GraphQLString,
		},
	}
	testInputObject1 := types.NewGraphQLInputObjectType(types.InputObjectConfig{
		Name:   "Test1",
		Fields: inputFields,
	})
	testInputObject2 := types.NewGraphQLInputObjectType(types.InputObjectConfig{
		Name:   "Test2",
		Fields: inputFields,
	})
	if !reflect.DeepEqual(testInputObject1.GetFields(), testInputObject2.GetFields()) {
		t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(testInputObject1.GetFields(), testInputObject2.GetFields()))
	}
	if !reflect.DeepEqual(inputFields, expectedInputFields) {
		t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expectedInputFields, fields))
	}

}
	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() {
	blogAuthor.AddFieldConfig("recentArticle", &types.GraphQLFieldConfig{
		Type: blogArticle,
	})
}

func TestTypeSystem_DefinitionExample_DefinesAQueryOnlySchema(t *testing.T) {
	blogSchema, err := types.NewGraphQLSchema(types.GraphQLSchemaConfig{
		Query: blogQuery,
	})
	if err != nil {
		t.Fatalf("unexpected error, got: %v", err)
	}
func TestIntrospection_ExecutesAnInputObject(t *testing.T) {

	testInputObject := types.NewGraphQLInputObjectType(types.InputObjectConfig{
		Name: "TestInputObject",
		Fields: types.InputObjectConfigFieldMap{
			"a": &types.InputObjectFieldConfig{
				Type:         types.GraphQLString,
				DefaultValue: "foo",
			},
			"b": &types.InputObjectFieldConfig{
				Type: types.NewGraphQLList(types.GraphQLString),
			},
		},
	})
	testType := types.NewGraphQLObjectType(types.GraphQLObjectTypeConfig{
		Name: "TestType",
		Fields: types.GraphQLFieldConfigMap{
			"field": &types.GraphQLFieldConfig{
				Type: types.GraphQLString,
				Args: types.GraphQLFieldConfigArgumentMap{
					"complex": &types.GraphQLArgumentConfig{
						Type: testInputObject,
					},
				},
				Resolve: func(p types.GQLFRParams) interface{} {
					return p.Args["complex"]
				},
			},
		},
	})
	schema, err := types.NewGraphQLSchema(types.GraphQLSchemaConfig{
		Query: testType,
	})
	if err != nil {
		t.Fatalf("Error creating GraphQLSchema: %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 := graphql(t, gql.GraphqlParams{
		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 *types.GraphQLInputObjectType = types.NewGraphQLInputObjectType(types.InputObjectConfig{
	Name: "TestInputObject",
	Fields: types.InputObjectConfigFieldMap{
		"a": &types.InputObjectFieldConfig{
			Type: types.GraphQLString,
		},
		"b": &types.InputObjectFieldConfig{
			Type: types.NewGraphQLList(types.GraphQLString),
		},
		"c": &types.InputObjectFieldConfig{
			Type: types.NewGraphQLNonNull(types.GraphQLString),
		},
		"d": &types.InputObjectFieldConfig{
			Type: testComplexScalar,
		},
	},
})

func inputResolved(p types.GQLFRParams) interface{} {
	input, ok := p.Args["input"]
	if !ok {
		return nil
	}
	b, err := json.Marshal(input)
		"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{
			Type:         types.GraphQLString,
			DefaultValue: "Hello",
		},
	},
})

func withModifiers(ttypes []types.GraphQLType) []types.GraphQLType {
	res := ttypes
	for _, ttype := range ttypes {
		res = append(res, types.NewGraphQLList(ttype))
	}
	for _, ttype := range ttypes {
		res = append(res, types.NewGraphQLNonNull(ttype))
	}
	for _, ttype := range ttypes {
		res = append(res, types.NewGraphQLNonNull(types.NewGraphQLList(ttype)))