[
  {
    "path": ".circleci/config.yml",
    "content": "test_with_go_modules: &test_with_go_modules\n  steps:\n    - checkout\n    - run: go test ./...\n    - run: go vet ./...\n\ntest_without_go_modules: &test_without_go_modules\n  working_directory: /go/src/github.com/graphql-go/graphql\n  steps:\n    - checkout\n    - run: go get -v -t -d ./...\n    - run: go test ./...\n    - run: go vet ./...\n\ndefaults: &defaults\n  <<: *test_with_go_modules\n\nversion: 2\njobs:\n  golang:1.8.7:\n    <<: *test_without_go_modules\n    docker:\n      - image: circleci/golang:1.8.7\n  golang:1.9.7:\n    <<: *test_without_go_modules\n    docker:\n      - image: circleci/golang:1.9.7\n  golang:1.11:\n    <<: *defaults\n    docker:\n      - image: circleci/golang:1.11\n  golang:latest:\n    <<: *defaults\n    docker:\n      - image: circleci/golang:latest\n  coveralls:\n    docker:\n      - image: circleci/golang:latest\n    steps:\n      - checkout\n      - run: go get github.com/mattn/goveralls\n      - run: go test -v -cover -race -coverprofile=coverage.out\n      - run: /go/bin/goveralls -coverprofile=coverage.out -service=circle-ci -repotoken $COVERALLS_TOKEN\n\nworkflows:\n  version: 2\n  build:\n    jobs:\n      - golang:1.8.7\n      - golang:1.9.7\n      - golang:1.11\n      - golang:latest\n      - coveralls\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.idea"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to graphql\n\nThis document is based on the [Node.js contribution guidelines](https://github.com/nodejs/node/blob/master/CONTRIBUTING.md)\n\n## Chat room\n\n[![Join the chat at https://gitter.im/graphql-go/graphql](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/graphql-go/graphql?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\nFeel free to participate in the chat room for informal discussions and queries.\n\nJust drop by and say hi!\n\n## Issue Contributions\n\nWhen opening new issues or commenting on existing issues on this repository\nplease make sure discussions are related to concrete technical issues with the\n`graphql` implementation.\n\n## Code Contributions\n\nThe `graphql` project welcomes new contributors.\n\nThis document will guide you through the contribution process.\n\nWhat do you want to contribute?\n\n- I want to otherwise correct or improve the docs or examples\n- I want to report a bug\n- I want to add some feature or functionality to an existing hardware platform\n- I want to add support for a new hardware platform\n\nDescriptions for each of these will eventually be provided below.\n\n## General Guidelines\n* Reading up on [CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments) would be a great start.\n* Submit a Github Pull Request to the appropriate branch and ideally discuss the changes with us in the [chat room](#chat-room).\n* We will look at the patch, test it out, and give you feedback.\n* Avoid doing minor whitespace changes, renaming, etc. along with merged content. These will be done by the maintainers from time to time but they can complicate merges and should be done separately.\n* Take care to maintain the existing coding style.\n* Always `golint` and `go fmt` your code.\n* Add unit tests for any new or changed functionality, especially for public APIs.\n* Run `go test` before submitting a PR.\n* For git help see [progit](http://git-scm.com/book) which is an awesome (and free) book on git\n\n\n## Creating Pull Requests\nBecause `graphql` makes use of self-referencing import paths, you will want\nto implement the local copy of your fork as a remote on your copy of the\noriginal `graphql` repo. Katrina Owen has [an excellent post on this workflow](https://splice.com/blog/contributing-open-source-git-repositories-go/).\n\nThe basics are as follows:\n\n1. Fork the project via the GitHub UI\n\n2. `go get` the upstream repo and set it up as the `upstream` remote and your own repo as the `origin` remote:\n\n```bash\n$ go get github.com/graphql-go/graphql\n$ cd $GOPATH/src/github.com/graphql-go/graphql\n$ git remote rename origin upstream\n$ git remote add origin git@github.com/YOUR_GITHUB_NAME/graphql\n```\nAll import paths should now work fine assuming that you've got the\nproper branch checked out.\n\n\n## Landing Pull Requests\n(This is for committers only. If you are unsure whether you are a committer, you are not.)\n\n1. Set the contributor's fork as an upstream on your checkout\n\n   ```git remote add contrib1 https://github.com/contrib1/graphql```\n\n2. Fetch the contributor's repo\n\n   ```git fetch contrib1```\n\n3. Checkout a copy of the PR branch\n\n   ```git checkout pr-1234 --track contrib1/branch-for-pr-1234```\n\n4. Review the PR as normal\n\n5. Land when you're ready via the GitHub UI\n\n## Developer's Certificate of Origin 1.0\n\nBy making a contribution to this project, I certify that:\n\n* (a) The contribution was created in whole or in part by me and I\nhave the right to submit it under the open source license indicated\nin the file; or\n* (b) The contribution is based upon previous work that, to the best\nof my knowledge, is covered under an appropriate open source license\nand I have the right under that license to submit that work with\nmodifications, whether created in whole or in part by me, under the\nsame open source license (unless I am permitted to submit under a\ndifferent license), as indicated in the file; or\n* (c) The contribution was provided directly to me by some other\nperson who certified (a), (b) or (c) and I have not modified it.\n\n\n## Code of Conduct\n\nThis Code of Conduct is adapted from [Rust's wonderful\nCoC](http://www.rust-lang.org/conduct.html).\n\n* We are committed to providing a friendly, safe and welcoming\nenvironment for all, regardless of gender, sexual orientation,\ndisability, ethnicity, religion, or similar personal characteristic.\n* Please avoid using overtly sexual nicknames or other nicknames that\nmight detract from a friendly, safe and welcoming environment for\nall.\n* Please be kind and courteous. There's no need to be mean or rude.\n* Respect that people have differences of opinion and that every\ndesign or implementation choice carries a trade-off and numerous\ncosts. There is seldom a right answer.\n* Please keep unstructured critique to a minimum. If you have solid\nideas you want to experiment with, make a fork and see how it works.\n* We will exclude you from interaction if you insult, demean or harass\nanyone.  That is not welcome behaviour. We interpret the term\n\"harassment\" as including the definition in the [Citizen Code of\nConduct](http://citizencodeofconduct.org/); if you have any lack of\nclarity about what might be included in that concept, please read\ntheir definition. In particular, we don't tolerate behavior that\nexcludes people in socially marginalized groups.\n* Private harassment is also unacceptable. No matter who you are, if\nyou feel you have been or are being harassed or made uncomfortable\nby a community member, please contact one of the channel ops or any\nof the TC members immediately with a capture (log, photo, email) of\nthe harassment if possible.  Whether you're a regular contributor or\na newcomer, we care about making this community a safe place for you\nand we've got your back.\n* Likewise any spamming, trolling, flaming, baiting or other\nattention-stealing behaviour is not welcome.\n* Avoid the use of personal pronouns in code comments or\ndocumentation. There is no need to address persons when explaining\ncode (e.g. \"When the developer\")\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Chris Ramón\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# graphql [![CircleCI](https://circleci.com/gh/graphql-go/graphql/tree/master.svg?style=svg)](https://circleci.com/gh/graphql-go/graphql/tree/master) [![Go Reference](https://pkg.go.dev/badge/github.com/graphql-go/graphql.svg)](https://pkg.go.dev/github.com/graphql-go/graphql) [![Coverage Status](https://coveralls.io/repos/github/graphql-go/graphql/badge.svg?branch=master)](https://coveralls.io/github/graphql-go/graphql?branch=master) [![Join the chat at https://gitter.im/graphql-go/graphql](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/graphql-go/graphql?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\nAn implementation of GraphQL in Go. Follows the official reference implementation [`graphql-js`](https://github.com/graphql/graphql-js).\n\nSupports: queries, mutations & subscriptions.\n\n### Documentation\n\ngodoc: https://pkg.go.dev/github.com/graphql-go/graphql\n\n### Contribute Back\n\nFriendly reminder links are available in case you would like to contribute back into our commitment with Go and open-source.\n\n| Author        |  PayPal Link  |\n|:-------------:|:-------------:|\n| [Hafiz Ismail](https://github.com/sogko) | Not available yet. |\n| [Chris Ramón](https://github.com/chris-ramon) | https://www.paypal.com/donate/?hosted_button_id=WHUQQYEMTRQBJ |\n\n### Getting Started\n\nTo install the library, run:\n```bash\ngo get github.com/graphql-go/graphql\n```\n\nThe following is a simple example which defines a schema with a single `hello` string-type field and a `Resolve` method which returns the string `world`. A GraphQL query is performed against this schema with the resulting output printed in JSON format.\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\nfunc main() {\n\t// Schema\n\tfields := graphql.Fields{\n\t\t\"hello\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\treturn \"world\", nil\n\t\t\t},\n\t\t},\n\t}\n\trootQuery := graphql.ObjectConfig{Name: \"RootQuery\", Fields: fields}\n\tschemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}\n\tschema, err := graphql.NewSchema(schemaConfig)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create new schema, error: %v\", err)\n\t}\n\n\t// Query\n\tquery := `\n\t\t{\n\t\t\thello\n\t\t}\n\t`\n\tparams := graphql.Params{Schema: schema, RequestString: query}\n\tr := graphql.Do(params)\n\tif len(r.Errors) > 0 {\n\t\tlog.Fatalf(\"failed to execute graphql operation, errors: %+v\", r.Errors)\n\t}\n\trJSON, _ := json.Marshal(r)\n\tfmt.Printf(\"%s \\n\", rJSON) // {\"data\":{\"hello\":\"world\"}}\n}\n```\nFor more complex examples, refer to the [examples/](https://github.com/graphql-go/graphql/tree/master/examples/) directory and [graphql_test.go](https://github.com/graphql-go/graphql/blob/master/graphql_test.go).\n\n### Third Party Libraries\n| Name          | Author        | Description  |\n|:-------------:|:-------------:|:------------:|\n| [graphql-go-handler](https://github.com/graphql-go/graphql-go-handler) | [Hafiz Ismail](https://github.com/sogko) | Middleware to handle GraphQL queries through HTTP requests. |\n| [graphql-relay-go](https://github.com/graphql-go/graphql-relay-go) | [Hafiz Ismail](https://github.com/sogko) | Lib to construct a graphql-go server supporting react-relay. |\n| [golang-relay-starter-kit](https://github.com/sogko/golang-relay-starter-kit) | [Hafiz Ismail](https://github.com/sogko) | Barebones starting point for a Relay application with Golang GraphQL server. |\n| [dataloader](https://github.com/nicksrandall/dataloader) | [Nick Randall](https://github.com/nicksrandall) | [DataLoader](https://github.com/facebook/dataloader) implementation in Go. |\n\n### Blog Posts\n- [Golang + GraphQL + Relay](https://wehavefaces.net/learn-golang-graphql-relay-1-e59ea174a902)\n\n"
  },
  {
    "path": "abstract_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\ntype testDog struct {\n\tName  string `json:\"name\"`\n\tWoofs bool   `json:\"woofs\"`\n}\n\ntype testCat struct {\n\tName  string `json:\"name\"`\n\tMeows bool   `json:\"meows\"`\n}\n\ntype testHuman struct {\n\tName string `json:\"name\"`\n}\n\nfunc TestIsTypeOfUsedToResolveRuntimeTypeForInterface(t *testing.T) {\n\n\tpetType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"Pet\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\n\t// ie declare that Dog belongs to Pet interface\n\tdogType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Dog\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tpetType,\n\t\t},\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\t_, ok := p.Value.(*testDog)\n\t\t\treturn ok\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif dog, ok := p.Source.(*testDog); ok {\n\t\t\t\t\t\treturn dog.Name, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"woofs\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif dog, ok := p.Source.(*testDog); ok {\n\t\t\t\t\t\treturn dog.Woofs, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\t// ie declare that Cat belongs to Pet interface\n\tcatType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Cat\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tpetType,\n\t\t},\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\t_, ok := p.Value.(*testCat)\n\t\t\treturn ok\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif cat, ok := p.Source.(*testCat); ok {\n\t\t\t\t\t\treturn cat.Name, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"meows\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif cat, ok := p.Source.(*testCat); ok {\n\t\t\t\t\t\treturn cat.Meows, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"pets\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(petType),\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn []interface{}{\n\t\t\t\t\t\t\t&testDog{\"Odie\", true},\n\t\t\t\t\t\t\t&testCat{\"Garfield\", false},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tTypes: []graphql.Type{catType, dogType},\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\tquery := `{\n      pets {\n        name\n        ... on Dog {\n          woofs\n        }\n        ... on Cat {\n          meows\n        }\n      }\n    }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"pets\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Odie\",\n\t\t\t\t\t\"woofs\": bool(true),\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Garfield\",\n\t\t\t\t\t\"meows\": bool(false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tErrors: nil,\n\t}\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestAppendTypeUsedToAddRuntimeCustomScalarTypeForInterface(t *testing.T) {\n\n\tpetType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"Pet\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\n\t// ie declare that Dog belongs to Pet interface\n\tdogType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Dog\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tpetType,\n\t\t},\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\t_, ok := p.Value.(*testDog)\n\t\t\treturn ok\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif dog, ok := p.Source.(*testDog); ok {\n\t\t\t\t\t\treturn dog.Name, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"woofs\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif dog, ok := p.Source.(*testDog); ok {\n\t\t\t\t\t\treturn dog.Woofs, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\t// ie declare that Cat belongs to Pet interface\n\tcatType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Cat\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tpetType,\n\t\t},\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\t_, ok := p.Value.(*testCat)\n\t\t\treturn ok\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif cat, ok := p.Source.(*testCat); ok {\n\t\t\t\t\t\treturn cat.Name, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"meows\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif cat, ok := p.Source.(*testCat); ok {\n\t\t\t\t\t\treturn cat.Meows, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"pets\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(petType),\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn []interface{}{\n\t\t\t\t\t\t\t&testDog{\"Odie\", true},\n\t\t\t\t\t\t\t&testCat{\"Garfield\", false},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t//Now add types catType and dogType at runtime.\n\tschema.AppendType(catType)\n\tschema.AppendType(dogType)\n\n\tquery := `{\n\t      pets {\n\t\tname\n\t\t... on Dog {\n\t\t  woofs\n\t\t}\n\t\t... on Cat {\n\t\t  meows\n\t\t}\n\t      }\n\t    }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"pets\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Odie\",\n\t\t\t\t\t\"woofs\": bool(true),\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Garfield\",\n\t\t\t\t\t\"meows\": bool(false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tErrors: nil,\n\t}\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestIsTypeOfUsedToResolveRuntimeTypeForUnion(t *testing.T) {\n\n\tdogType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Dog\",\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\t_, ok := p.Value.(*testDog)\n\t\t\treturn ok\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"woofs\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t},\n\t})\n\tcatType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Cat\",\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\t_, ok := p.Value.(*testCat)\n\t\t\treturn ok\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"meows\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t},\n\t})\n\t// ie declare Pet has Dot and Cat object types\n\tpetType := graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"Pet\",\n\t\tTypes: []*graphql.Object{\n\t\t\tdogType, catType,\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"pets\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(petType),\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn []interface{}{\n\t\t\t\t\t\t\t&testDog{\"Odie\", true},\n\t\t\t\t\t\t\t&testCat{\"Garfield\", false},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\tquery := `{\n      pets {\n        ... on Dog {\n          name\n          woofs\n        }\n        ... on Cat {\n          name\n          meows\n        }\n      }\n    }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"pets\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Odie\",\n\t\t\t\t\t\"woofs\": bool(true),\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Garfield\",\n\t\t\t\t\t\"meows\": bool(false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tErrors: nil,\n\t}\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) {\n\n\tvar dogType *graphql.Object\n\tvar catType *graphql.Object\n\tvar humanType *graphql.Object\n\tpetType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"Pet\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\tif _, ok := p.Value.(*testCat); ok {\n\t\t\t\treturn catType\n\t\t\t}\n\t\t\tif _, ok := p.Value.(*testDog); ok {\n\t\t\t\treturn dogType\n\t\t\t}\n\t\t\tif _, ok := p.Value.(*testHuman); ok {\n\t\t\t\treturn humanType\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t})\n\n\thumanType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Human\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tdogType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Dog\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tpetType,\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"woofs\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t},\n\t})\n\tcatType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Cat\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tpetType,\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"meows\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"pets\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(petType),\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn []interface{}{\n\t\t\t\t\t\t\t&testDog{\"Odie\", true},\n\t\t\t\t\t\t\t&testCat{\"Garfield\", false},\n\t\t\t\t\t\t\t&testHuman{\"Jon\"},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tTypes: []graphql.Type{catType, dogType},\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\tquery := `{\n      pets {\n        name\n        ... on Dog {\n          woofs\n        }\n        ... on Cat {\n          meows\n        }\n      }\n    }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"pets\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Odie\",\n\t\t\t\t\t\"woofs\": bool(true),\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Garfield\",\n\t\t\t\t\t\"meows\": bool(false),\n\t\t\t\t},\n\t\t\t\tnil,\n\t\t\t},\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Runtime Object type \"Human\" is not a possible type for \"Pet\".`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   2,\n\t\t\t\t\t\tColumn: 7,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"pets\",\n\t\t\t\t\t2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) {\n\n\thumanType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Human\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tdogType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Dog\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"woofs\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t},\n\t})\n\tcatType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Cat\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"meows\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t},\n\t})\n\tpetType := graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"Pet\",\n\t\tTypes: []*graphql.Object{\n\t\t\tdogType, catType,\n\t\t},\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\tif _, ok := p.Value.(*testCat); ok {\n\t\t\t\treturn catType\n\t\t\t}\n\t\t\tif _, ok := p.Value.(*testDog); ok {\n\t\t\t\treturn dogType\n\t\t\t}\n\t\t\tif _, ok := p.Value.(*testHuman); ok {\n\t\t\t\treturn humanType\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"pets\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(petType),\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn []interface{}{\n\t\t\t\t\t\t\t&testDog{\"Odie\", true},\n\t\t\t\t\t\t\t&testCat{\"Garfield\", false},\n\t\t\t\t\t\t\t&testHuman{\"Jon\"},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\tquery := `{\n      pets {\n        ... on Dog {\n          name\n          woofs\n        }\n        ... on Cat {\n          name\n          meows\n        }\n      }\n    }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"pets\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Odie\",\n\t\t\t\t\t\"woofs\": bool(true),\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\":  \"Garfield\",\n\t\t\t\t\t\"meows\": bool(false),\n\t\t\t\t},\n\t\t\t\tnil,\n\t\t\t},\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Runtime Object type \"Human\" is not a possible type for \"Pet\".`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   2,\n\t\t\t\t\t\tColumn: 7,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"pets\",\n\t\t\t\t\t2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "benchutil/list_schema.go",
    "content": "package benchutil\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\ntype color struct {\n\tHex string\n\tR   int\n\tG   int\n\tB   int\n}\n\nfunc ListSchemaWithXItems(x int) graphql.Schema {\n\n\tlist := generateXListItems(x)\n\n\tcolor := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:        \"Color\",\n\t\tDescription: \"A color\",\n\t\tFields: graphql.Fields{\n\t\t\t\"hex\": &graphql.Field{\n\t\t\t\tType:        graphql.NewNonNull(graphql.String),\n\t\t\t\tDescription: \"Hex color code.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif c, ok := p.Source.(color); ok {\n\t\t\t\t\t\treturn c.Hex, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"r\": &graphql.Field{\n\t\t\t\tType:        graphql.NewNonNull(graphql.Int),\n\t\t\t\tDescription: \"Red value.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif c, ok := p.Source.(color); ok {\n\t\t\t\t\t\treturn c.R, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"g\": &graphql.Field{\n\t\t\t\tType:        graphql.NewNonNull(graphql.Int),\n\t\t\t\tDescription: \"Green value.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif c, ok := p.Source.(color); ok {\n\t\t\t\t\t\treturn c.G, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"b\": &graphql.Field{\n\t\t\t\tType:        graphql.NewNonNull(graphql.Int),\n\t\t\t\tDescription: \"Blue value.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif c, ok := p.Source.(color); ok {\n\t\t\t\t\t\treturn c.B, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"colors\": {\n\t\t\t\tType: graphql.NewList(color),\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn list, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tcolorSchema, _ := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\n\treturn colorSchema\n}\n\nvar colors []color\n\nfunc init() {\n\tcolors = make([]color, 0, 256*16*16)\n\n\tfor r := 0; r < 256; r++ {\n\t\tfor g := 0; g < 16; g++ {\n\t\t\tfor b := 0; b < 16; b++ {\n\t\t\t\tcolors = append(colors, color{\n\t\t\t\t\tHex: fmt.Sprintf(\"#%x%x%x\", r, g, b),\n\t\t\t\t\tR:   r,\n\t\t\t\t\tG:   g,\n\t\t\t\t\tB:   b,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc generateXListItems(x int) []color {\n\tif x > len(colors) {\n\t\tx = len(colors)\n\t}\n\treturn colors[0:x]\n}\n"
  },
  {
    "path": "benchutil/wide_schema.go",
    "content": "package benchutil\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\nfunc WideSchemaWithXFieldsAndYItems(x int, y int) graphql.Schema {\n\twide := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:        \"Wide\",\n\t\tDescription: \"An object\",\n\t\tFields:      generateXWideFields(x),\n\t})\n\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"wide\": {\n\t\t\t\tType: graphql.NewList(wide),\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tout := make([]struct{}, 0, y)\n\t\t\t\t\tfor i := 0; i < y; i++ {\n\t\t\t\t\t\tout = append(out, struct{}{})\n\t\t\t\t\t}\n\t\t\t\t\treturn out, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\twideSchema, _ := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\n\treturn wideSchema\n}\n\nfunc generateXWideFields(x int) graphql.Fields {\n\tfields := graphql.Fields{}\n\tfor i := 0; i < x; i++ {\n\t\tfields[generateFieldNameFromX(i)] = generateWideFieldFromX(i)\n\t}\n\treturn fields\n}\n\nfunc generateWideFieldFromX(x int) *graphql.Field {\n\treturn &graphql.Field{\n\t\tType:    generateWideTypeFromX(x),\n\t\tResolve: generateWideResolveFromX(x),\n\t}\n}\n\nfunc generateWideTypeFromX(x int) graphql.Type {\n\tswitch x % 8 {\n\tcase 0:\n\t\treturn graphql.String\n\tcase 1:\n\t\treturn graphql.NewNonNull(graphql.String)\n\tcase 2:\n\t\treturn graphql.Int\n\tcase 3:\n\t\treturn graphql.NewNonNull(graphql.Int)\n\tcase 4:\n\t\treturn graphql.Float\n\tcase 5:\n\t\treturn graphql.NewNonNull(graphql.Float)\n\tcase 6:\n\t\treturn graphql.Boolean\n\tcase 7:\n\t\treturn graphql.NewNonNull(graphql.Boolean)\n\t}\n\n\treturn nil\n}\n\nfunc generateFieldNameFromX(x int) string {\n\tvar out string\n\talphabet := []string{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"z\"}\n\tv := x\n\tfor {\n\t\tr := v % 10\n\t\tout = alphabet[r] + out\n\t\tv /= 10\n\t\tif v == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn out\n}\n\nfunc generateWideResolveFromX(x int) func(p graphql.ResolveParams) (interface{}, error) {\n\tswitch x % 8 {\n\tcase 0:\n\t\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn fmt.Sprint(x), nil\n\t\t}\n\tcase 1:\n\t\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn fmt.Sprint(x), nil\n\t\t}\n\tcase 2:\n\t\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn x, nil\n\t\t}\n\tcase 3:\n\t\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn x, nil\n\t\t}\n\tcase 4:\n\t\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn float64(x), nil\n\t\t}\n\tcase 5:\n\t\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn float64(x), nil\n\t\t}\n\tcase 6:\n\t\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\tif x%2 == 0 {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\treturn true, nil\n\t\t}\n\tcase 7:\n\t\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\tif x%2 == 0 {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\treturn true, nil\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc WideSchemaQuery(x int) string {\n\tvar fields string\n\tfor i := 0; i < x; i++ {\n\t\tfields = fields + generateFieldNameFromX(i) + \" \"\n\t}\n\n\treturn fmt.Sprintf(\"query { wide { %s} }\", fields)\n}\n"
  },
  {
    "path": "definition.go",
    "content": "package graphql\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"regexp\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\n// Type interface for all of the possible kinds of GraphQL types\ntype Type interface {\n\tName() string\n\tDescription() string\n\tString() string\n\tError() error\n}\n\nvar _ Type = (*Scalar)(nil)\nvar _ Type = (*Object)(nil)\nvar _ Type = (*Interface)(nil)\nvar _ Type = (*Union)(nil)\nvar _ Type = (*Enum)(nil)\nvar _ Type = (*InputObject)(nil)\nvar _ Type = (*List)(nil)\nvar _ Type = (*NonNull)(nil)\nvar _ Type = (*Argument)(nil)\n\n// Input interface for types that may be used as input types for arguments and directives.\ntype Input interface {\n\tName() string\n\tDescription() string\n\tString() string\n\tError() error\n}\n\nvar _ Input = (*Scalar)(nil)\nvar _ Input = (*Enum)(nil)\nvar _ Input = (*InputObject)(nil)\nvar _ Input = (*List)(nil)\nvar _ Input = (*NonNull)(nil)\n\n// IsInputType determines if given type is a GraphQLInputType\nfunc IsInputType(ttype Type) bool {\n\tswitch GetNamed(ttype).(type) {\n\tcase *Scalar, *Enum, *InputObject:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// IsOutputType determines if given type is a GraphQLOutputType\nfunc IsOutputType(ttype Type) bool {\n\tswitch GetNamed(ttype).(type) {\n\tcase *Scalar, *Object, *Interface, *Union, *Enum:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Leaf interface for types that may be leaf values\ntype Leaf interface {\n\tName() string\n\tDescription() string\n\tString() string\n\tError() error\n\tSerialize(value interface{}) interface{}\n}\n\nvar _ Leaf = (*Scalar)(nil)\nvar _ Leaf = (*Enum)(nil)\n\n// IsLeafType determines if given type is a leaf value\nfunc IsLeafType(ttype Type) bool {\n\tswitch GetNamed(ttype).(type) {\n\tcase *Scalar, *Enum:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Output interface for types that may be used as output types as the result of fields.\ntype Output interface {\n\tName() string\n\tDescription() string\n\tString() string\n\tError() error\n}\n\nvar _ Output = (*Scalar)(nil)\nvar _ Output = (*Object)(nil)\nvar _ Output = (*Interface)(nil)\nvar _ Output = (*Union)(nil)\nvar _ Output = (*Enum)(nil)\nvar _ Output = (*List)(nil)\nvar _ Output = (*NonNull)(nil)\n\n// Composite interface for types that may describe the parent context of a selection set.\ntype Composite interface {\n\tName() string\n\tDescription() string\n\tString() string\n\tError() error\n}\n\nvar _ Composite = (*Object)(nil)\nvar _ Composite = (*Interface)(nil)\nvar _ Composite = (*Union)(nil)\n\n// IsCompositeType determines if given type is a GraphQLComposite type\nfunc IsCompositeType(ttype interface{}) bool {\n\tswitch ttype.(type) {\n\tcase *Object, *Interface, *Union:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Abstract interface for types that may describe the parent context of a selection set.\ntype Abstract interface {\n\tName() string\n}\n\nvar _ Abstract = (*Interface)(nil)\nvar _ Abstract = (*Union)(nil)\n\nfunc IsAbstractType(ttype interface{}) bool {\n\tswitch ttype.(type) {\n\tcase *Interface, *Union:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Nullable interface for types that can accept null as a value.\ntype Nullable interface {\n}\n\nvar _ Nullable = (*Scalar)(nil)\nvar _ Nullable = (*Object)(nil)\nvar _ Nullable = (*Interface)(nil)\nvar _ Nullable = (*Union)(nil)\nvar _ Nullable = (*Enum)(nil)\nvar _ Nullable = (*InputObject)(nil)\nvar _ Nullable = (*List)(nil)\n\n// GetNullable returns the Nullable type of the given GraphQL type\nfunc GetNullable(ttype Type) Nullable {\n\tif ttype, ok := ttype.(*NonNull); ok {\n\t\treturn ttype.OfType\n\t}\n\treturn ttype\n}\n\n// Named interface for types that do not include modifiers like List or NonNull.\ntype Named interface {\n\tString() string\n}\n\nvar _ Named = (*Scalar)(nil)\nvar _ Named = (*Object)(nil)\nvar _ Named = (*Interface)(nil)\nvar _ Named = (*Union)(nil)\nvar _ Named = (*Enum)(nil)\nvar _ Named = (*InputObject)(nil)\n\n// GetNamed returns the Named type of the given GraphQL type\nfunc GetNamed(ttype Type) Named {\n\tunmodifiedType := ttype\n\tfor {\n\t\tswitch typ := unmodifiedType.(type) {\n\t\tcase *List:\n\t\t\tunmodifiedType = typ.OfType\n\t\tcase *NonNull:\n\t\t\tunmodifiedType = typ.OfType\n\t\tdefault:\n\t\t\treturn unmodifiedType\n\t\t}\n\t}\n}\n\n// Scalar Type Definition\n//\n// The leaf values of any request and input values to arguments are\n// Scalars (or Enums) and are defined with a name and a series of functions\n// used to parse input from ast or variables and to ensure validity.\n//\n// Example:\n//\n//\tvar OddType = new Scalar({\n//\t  name: 'Odd',\n//\t  serialize(value) {\n//\t    return value % 2 === 1 ? value : null;\n//\t  }\n//\t});\ntype Scalar struct {\n\tPrivateName        string `json:\"name\"`\n\tPrivateDescription string `json:\"description\"`\n\n\tscalarConfig ScalarConfig\n\terr          error\n}\n\n// SerializeFn is a function type for serializing a GraphQLScalar type value\ntype SerializeFn func(value interface{}) interface{}\n\n// ParseValueFn is a function type for parsing the value of a GraphQLScalar type\ntype ParseValueFn func(value interface{}) interface{}\n\n// ParseLiteralFn is a function type for parsing the literal value of a GraphQLScalar type\ntype ParseLiteralFn func(valueAST ast.Value) interface{}\n\n// ScalarConfig options for creating a new GraphQLScalar\ntype ScalarConfig struct {\n\tName         string `json:\"name\"`\n\tDescription  string `json:\"description\"`\n\tSerialize    SerializeFn\n\tParseValue   ParseValueFn\n\tParseLiteral ParseLiteralFn\n}\n\n// NewScalar creates a new GraphQLScalar\nfunc NewScalar(config ScalarConfig) *Scalar {\n\tst := &Scalar{}\n\terr := invariant(config.Name != \"\", \"Type must be named.\")\n\tif err != nil {\n\t\tst.err = err\n\t\treturn st\n\t}\n\n\terr = assertValidName(config.Name)\n\tif err != nil {\n\t\tst.err = err\n\t\treturn st\n\t}\n\n\tst.PrivateName = config.Name\n\tst.PrivateDescription = config.Description\n\n\terr = invariantf(\n\t\tconfig.Serialize != nil,\n\t\t`%v must provide \"serialize\" function. If this custom Scalar is `+\n\t\t\t`also used as an input type, ensure \"parseValue\" and \"parseLiteral\" `+\n\t\t\t`functions are also provided.`, st,\n\t)\n\tif err != nil {\n\t\tst.err = err\n\t\treturn st\n\t}\n\tif config.ParseValue != nil || config.ParseLiteral != nil {\n\t\terr = invariantf(\n\t\t\tconfig.ParseValue != nil && config.ParseLiteral != nil,\n\t\t\t`%v must provide both \"parseValue\" and \"parseLiteral\" functions.`, st,\n\t\t)\n\t\tif err != nil {\n\t\t\tst.err = err\n\t\t\treturn st\n\t\t}\n\t}\n\n\tst.scalarConfig = config\n\treturn st\n}\nfunc (st *Scalar) Serialize(value interface{}) interface{} {\n\tif st.scalarConfig.Serialize == nil {\n\t\treturn value\n\t}\n\treturn st.scalarConfig.Serialize(value)\n}\nfunc (st *Scalar) ParseValue(value interface{}) interface{} {\n\tif st.scalarConfig.ParseValue == nil {\n\t\treturn value\n\t}\n\treturn st.scalarConfig.ParseValue(value)\n}\nfunc (st *Scalar) ParseLiteral(valueAST ast.Value) interface{} {\n\tif st.scalarConfig.ParseLiteral == nil {\n\t\treturn nil\n\t}\n\treturn st.scalarConfig.ParseLiteral(valueAST)\n}\nfunc (st *Scalar) Name() string {\n\treturn st.PrivateName\n}\nfunc (st *Scalar) Description() string {\n\treturn st.PrivateDescription\n\n}\nfunc (st *Scalar) String() string {\n\treturn st.PrivateName\n}\nfunc (st *Scalar) Error() error {\n\treturn st.err\n}\n\n// Object Type Definition\n//\n// Almost all of the GraphQL types you define will be object  Object types\n// have a name, but most importantly describe their fields.\n// Example:\n//\n//\tvar AddressType = new Object({\n//\t  name: 'Address',\n//\t  fields: {\n//\t    street: { type: String },\n//\t    number: { type: Int },\n//\t    formatted: {\n//\t      type: String,\n//\t      resolve(obj) {\n//\t        return obj.number + ' ' + obj.street\n//\t      }\n//\t    }\n//\t  }\n//\t});\n//\n// When two types need to refer to each other, or a type needs to refer to\n// itself in a field, you can use a function expression (aka a closure or a\n// thunk) to supply the fields lazily.\n//\n// Example:\n//\n//\tvar PersonType = new Object({\n//\t  name: 'Person',\n//\t  fields: () => ({\n//\t    name: { type: String },\n//\t    bestFriend: { type: PersonType },\n//\t  })\n//\t});\n//\n// /\ntype Object struct {\n\tPrivateName        string `json:\"name\"`\n\tPrivateDescription string `json:\"description\"`\n\tIsTypeOf           IsTypeOfFn\n\n\ttypeConfig            ObjectConfig\n\tinitialisedFields     bool\n\tfields                FieldDefinitionMap\n\tinitialisedInterfaces bool\n\tinterfaces            []*Interface\n\t// Interim alternative to throwing an error during schema definition at run-time\n\terr error\n}\n\n// IsTypeOfParams Params for IsTypeOfFn()\ntype IsTypeOfParams struct {\n\t// Value that needs to be resolve.\n\t// Use this to decide which GraphQLObject this value maps to.\n\tValue interface{}\n\n\t// Info is a collection of information about the current execution state.\n\tInfo ResolveInfo\n\n\t// Context argument is a context value that is provided to every resolve function within an execution.\n\t// It is commonly\n\t// used to represent an authenticated user, or request-specific caches.\n\tContext context.Context\n}\n\ntype IsTypeOfFn func(p IsTypeOfParams) bool\n\ntype InterfacesThunk func() []*Interface\n\ntype ObjectConfig struct {\n\tName        string      `json:\"name\"`\n\tInterfaces  interface{} `json:\"interfaces\"`\n\tFields      interface{} `json:\"fields\"`\n\tIsTypeOf    IsTypeOfFn  `json:\"isTypeOf\"`\n\tDescription string      `json:\"description\"`\n}\n\ntype FieldsThunk func() Fields\n\nfunc NewObject(config ObjectConfig) *Object {\n\tobjectType := &Object{}\n\n\terr := invariant(config.Name != \"\", \"Type must be named.\")\n\tif err != nil {\n\t\tobjectType.err = err\n\t\treturn objectType\n\t}\n\terr = assertValidName(config.Name)\n\tif err != nil {\n\t\tobjectType.err = err\n\t\treturn objectType\n\t}\n\n\tobjectType.PrivateName = config.Name\n\tobjectType.PrivateDescription = config.Description\n\tobjectType.IsTypeOf = config.IsTypeOf\n\tobjectType.typeConfig = config\n\n\treturn objectType\n}\n\n// ensureCache ensures that both fields and interfaces have been initialized properly,\n// to prevent races.\nfunc (gt *Object) ensureCache() {\n\tgt.Fields()\n\tgt.Interfaces()\n}\nfunc (gt *Object) AddFieldConfig(fieldName string, fieldConfig *Field) {\n\tif fieldName == \"\" || fieldConfig == nil {\n\t\treturn\n\t}\n\tif fields, ok := gt.typeConfig.Fields.(Fields); ok {\n\t\tfields[fieldName] = fieldConfig\n\t\tgt.initialisedFields = false\n\t}\n}\nfunc (gt *Object) Name() string {\n\treturn gt.PrivateName\n}\nfunc (gt *Object) Description() string {\n\treturn gt.PrivateDescription\n}\nfunc (gt *Object) String() string {\n\treturn gt.PrivateName\n}\nfunc (gt *Object) Fields() FieldDefinitionMap {\n\tif gt.initialisedFields {\n\t\treturn gt.fields\n\t}\n\n\tvar configureFields Fields\n\tswitch fields := gt.typeConfig.Fields.(type) {\n\tcase Fields:\n\t\tconfigureFields = fields\n\tcase FieldsThunk:\n\t\tconfigureFields = fields()\n\t}\n\n\tgt.fields, gt.err = defineFieldMap(gt, configureFields)\n\tgt.initialisedFields = true\n\treturn gt.fields\n}\n\nfunc (gt *Object) Interfaces() []*Interface {\n\tif gt.initialisedInterfaces {\n\t\treturn gt.interfaces\n\t}\n\n\tvar configInterfaces []*Interface\n\tswitch iface := gt.typeConfig.Interfaces.(type) {\n\tcase InterfacesThunk:\n\t\tconfigInterfaces = iface()\n\tcase []*Interface:\n\t\tconfigInterfaces = iface\n\tcase nil:\n\tdefault:\n\t\tgt.err = fmt.Errorf(\"Unknown Object.Interfaces type: %T\", gt.typeConfig.Interfaces)\n\t\tgt.initialisedInterfaces = true\n\t\treturn nil\n\t}\n\n\tgt.interfaces, gt.err = defineInterfaces(gt, configInterfaces)\n\tgt.initialisedInterfaces = true\n\treturn gt.interfaces\n}\n\nfunc (gt *Object) Error() error {\n\treturn gt.err\n}\n\nfunc defineInterfaces(ttype *Object, interfaces []*Interface) ([]*Interface, error) {\n\tifaces := []*Interface{}\n\n\tif len(interfaces) == 0 {\n\t\treturn ifaces, nil\n\t}\n\tfor _, iface := range interfaces {\n\t\terr := invariantf(\n\t\t\tiface != nil,\n\t\t\t`%v may only implement Interface types, it cannot implement: %v.`, ttype, iface,\n\t\t)\n\t\tif err != nil {\n\t\t\treturn ifaces, err\n\t\t}\n\t\tif iface.ResolveType != nil {\n\t\t\terr = invariantf(\n\t\t\t\tiface.ResolveType != nil,\n\t\t\t\t`Interface Type %v does not provide a \"resolveType\" function `+\n\t\t\t\t\t`and implementing Type %v does not provide a \"isTypeOf\" `+\n\t\t\t\t\t`function. There is no way to resolve this implementing type `+\n\t\t\t\t\t`during execution.`, iface, ttype,\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn ifaces, err\n\t\t\t}\n\t\t}\n\t\tifaces = append(ifaces, iface)\n\t}\n\n\treturn ifaces, nil\n}\n\nfunc defineFieldMap(ttype Named, fieldMap Fields) (FieldDefinitionMap, error) {\n\tresultFieldMap := FieldDefinitionMap{}\n\n\terr := invariantf(\n\t\tlen(fieldMap) > 0,\n\t\t`%v fields must be an object with field names as keys or a function which return such an object.`, ttype,\n\t)\n\tif err != nil {\n\t\treturn resultFieldMap, err\n\t}\n\n\tfor fieldName, field := range fieldMap {\n\t\tif field == nil {\n\t\t\tcontinue\n\t\t}\n\t\terr = invariantf(\n\t\t\tfield.Type != nil,\n\t\t\t`%v.%v field type must be Output Type but got: %v.`, ttype, fieldName, field.Type,\n\t\t)\n\t\tif err != nil {\n\t\t\treturn resultFieldMap, err\n\t\t}\n\t\tif field.Type.Error() != nil {\n\t\t\treturn resultFieldMap, field.Type.Error()\n\t\t}\n\t\tif err = assertValidName(fieldName); err != nil {\n\t\t\treturn resultFieldMap, err\n\t\t}\n\t\tfieldDef := &FieldDefinition{\n\t\t\tName:              fieldName,\n\t\t\tDescription:       field.Description,\n\t\t\tType:              field.Type,\n\t\t\tResolve:           field.Resolve,\n\t\t\tSubscribe:         field.Subscribe,\n\t\t\tDeprecationReason: field.DeprecationReason,\n\t\t}\n\n\t\tfieldDef.Args = []*Argument{}\n\t\tfor argName, arg := range field.Args {\n\t\t\tif err = assertValidName(argName); err != nil {\n\t\t\t\treturn resultFieldMap, err\n\t\t\t}\n\t\t\tif err = invariantf(\n\t\t\t\targ != nil,\n\t\t\t\t`%v.%v args must be an object with argument names as keys.`, ttype, fieldName,\n\t\t\t); err != nil {\n\t\t\t\treturn resultFieldMap, err\n\t\t\t}\n\t\t\tif err = invariantf(\n\t\t\t\targ.Type != nil,\n\t\t\t\t`%v.%v(%v:) argument type must be Input Type but got: %v.`, ttype, fieldName, argName, arg.Type,\n\t\t\t); err != nil {\n\t\t\t\treturn resultFieldMap, err\n\t\t\t}\n\t\t\tfieldArg := &Argument{\n\t\t\t\tPrivateName:        argName,\n\t\t\t\tPrivateDescription: arg.Description,\n\t\t\t\tType:               arg.Type,\n\t\t\t\tDefaultValue:       arg.DefaultValue,\n\t\t\t}\n\t\t\tfieldDef.Args = append(fieldDef.Args, fieldArg)\n\t\t}\n\t\tresultFieldMap[fieldName] = fieldDef\n\t}\n\treturn resultFieldMap, nil\n}\n\n// ResolveParams Params for FieldResolveFn()\ntype ResolveParams struct {\n\t// Source is the source value\n\tSource interface{}\n\n\t// Args is a map of arguments for current GraphQL request\n\tArgs map[string]interface{}\n\n\t// Info is a collection of information about the current execution state.\n\tInfo ResolveInfo\n\n\t// Context argument is a context value that is provided to every resolve function within an execution.\n\t// It is commonly\n\t// used to represent an authenticated user, or request-specific caches.\n\tContext context.Context\n}\n\ntype FieldResolveFn func(p ResolveParams) (interface{}, error)\n\ntype ResolveInfo struct {\n\tFieldName      string\n\tFieldASTs      []*ast.Field\n\tPath           *ResponsePath\n\tReturnType     Output\n\tParentType     Composite\n\tSchema         Schema\n\tFragments      map[string]ast.Definition\n\tRootValue      interface{}\n\tOperation      ast.Definition\n\tVariableValues map[string]interface{}\n}\n\ntype Fields map[string]*Field\n\ntype Field struct {\n\tName              string              `json:\"name\"` // used by graphlql-relay\n\tType              Output              `json:\"type\"`\n\tArgs              FieldConfigArgument `json:\"args\"`\n\tResolve           FieldResolveFn      `json:\"-\"`\n\tSubscribe         FieldResolveFn      `json:\"-\"`\n\tDeprecationReason string              `json:\"deprecationReason\"`\n\tDescription       string              `json:\"description\"`\n}\n\ntype FieldConfigArgument map[string]*ArgumentConfig\n\ntype ArgumentConfig struct {\n\tType         Input       `json:\"type\"`\n\tDefaultValue interface{} `json:\"defaultValue\"`\n\tDescription  string      `json:\"description\"`\n}\n\ntype FieldDefinitionMap map[string]*FieldDefinition\ntype FieldDefinition struct {\n\tName              string         `json:\"name\"`\n\tDescription       string         `json:\"description\"`\n\tType              Output         `json:\"type\"`\n\tArgs              []*Argument    `json:\"args\"`\n\tResolve           FieldResolveFn `json:\"-\"`\n\tSubscribe         FieldResolveFn `json:\"-\"`\n\tDeprecationReason string         `json:\"deprecationReason\"`\n}\n\ntype FieldArgument struct {\n\tName         string      `json:\"name\"`\n\tType         Type        `json:\"type\"`\n\tDefaultValue interface{} `json:\"defaultValue\"`\n\tDescription  string      `json:\"description\"`\n}\n\ntype Argument struct {\n\tPrivateName        string      `json:\"name\"`\n\tType               Input       `json:\"type\"`\n\tDefaultValue       interface{} `json:\"defaultValue\"`\n\tPrivateDescription string      `json:\"description\"`\n}\n\nfunc (st *Argument) Name() string {\n\treturn st.PrivateName\n}\nfunc (st *Argument) Description() string {\n\treturn st.PrivateDescription\n\n}\nfunc (st *Argument) String() string {\n\treturn st.PrivateName\n}\nfunc (st *Argument) Error() error {\n\treturn nil\n}\n\n// Interface Type Definition\n//\n// When a field can return one of a heterogeneous set of types, a Interface type\n// is used to describe what types are possible, what fields are in common across\n// all types, as well as a function to determine which type is actually used\n// when the field is resolved.\n//\n// Example:\n//\n//\tvar EntityType = new Interface({\n//\t  name: 'Entity',\n//\t  fields: {\n//\t    name: { type: String }\n//\t  }\n//\t});\ntype Interface struct {\n\tPrivateName        string `json:\"name\"`\n\tPrivateDescription string `json:\"description\"`\n\tResolveType        ResolveTypeFn\n\n\ttypeConfig        InterfaceConfig\n\tinitialisedFields bool\n\tfields            FieldDefinitionMap\n\terr               error\n}\ntype InterfaceConfig struct {\n\tName        string      `json:\"name\"`\n\tFields      interface{} `json:\"fields\"`\n\tResolveType ResolveTypeFn\n\tDescription string `json:\"description\"`\n}\n\n// ResolveTypeParams Params for ResolveTypeFn()\ntype ResolveTypeParams struct {\n\t// Value that needs to be resolve.\n\t// Use this to decide which GraphQLObject this value maps to.\n\tValue interface{}\n\n\t// Info is a collection of information about the current execution state.\n\tInfo ResolveInfo\n\n\t// Context argument is a context value that is provided to every resolve function within an execution.\n\t// It is commonly\n\t// used to represent an authenticated user, or request-specific caches.\n\tContext context.Context\n}\n\ntype ResolveTypeFn func(p ResolveTypeParams) *Object\n\nfunc NewInterface(config InterfaceConfig) *Interface {\n\tit := &Interface{}\n\n\tif it.err = invariant(config.Name != \"\", \"Type must be named.\"); it.err != nil {\n\t\treturn it\n\t}\n\tif it.err = assertValidName(config.Name); it.err != nil {\n\t\treturn it\n\t}\n\tit.PrivateName = config.Name\n\tit.PrivateDescription = config.Description\n\tit.ResolveType = config.ResolveType\n\tit.typeConfig = config\n\n\treturn it\n}\n\nfunc (it *Interface) AddFieldConfig(fieldName string, fieldConfig *Field) {\n\tif fieldName == \"\" || fieldConfig == nil {\n\t\treturn\n\t}\n\tif fields, ok := it.typeConfig.Fields.(Fields); ok {\n\t\tfields[fieldName] = fieldConfig\n\t\tit.initialisedFields = false\n\t}\n}\n\nfunc (it *Interface) Name() string {\n\treturn it.PrivateName\n}\n\nfunc (it *Interface) Description() string {\n\treturn it.PrivateDescription\n}\n\nfunc (it *Interface) Fields() (fields FieldDefinitionMap) {\n\tif it.initialisedFields {\n\t\treturn it.fields\n\t}\n\n\tvar configureFields Fields\n\tswitch fields := it.typeConfig.Fields.(type) {\n\tcase Fields:\n\t\tconfigureFields = fields\n\tcase FieldsThunk:\n\t\tconfigureFields = fields()\n\t}\n\n\tit.fields, it.err = defineFieldMap(it, configureFields)\n\tit.initialisedFields = true\n\treturn it.fields\n}\n\nfunc (it *Interface) String() string {\n\treturn it.PrivateName\n}\n\nfunc (it *Interface) Error() error {\n\treturn it.err\n}\n\n// Union Type Definition\n//\n// When a field can return one of a heterogeneous set of types, a Union type\n// is used to describe what types are possible as well as providing a function\n// to determine which type is actually used when the field is resolved.\n//\n// Example:\n//\n//\tvar PetType = new Union({\n//\t  name: 'Pet',\n//\t  types: [ DogType, CatType ],\n//\t  resolveType(value) {\n//\t    if (value instanceof Dog) {\n//\t      return DogType;\n//\t    }\n//\t    if (value instanceof Cat) {\n//\t      return CatType;\n//\t    }\n//\t  }\n//\t});\ntype Union struct {\n\tPrivateName        string `json:\"name\"`\n\tPrivateDescription string `json:\"description\"`\n\tResolveType        ResolveTypeFn\n\n\ttypeConfig      UnionConfig\n\tinitalizedTypes bool\n\ttypes           []*Object\n\tpossibleTypes   map[string]bool\n\n\terr error\n}\n\ntype UnionTypesThunk func() []*Object\n\ntype UnionConfig struct {\n\tName        string      `json:\"name\"`\n\tTypes       interface{} `json:\"types\"`\n\tResolveType ResolveTypeFn\n\tDescription string `json:\"description\"`\n}\n\nfunc NewUnion(config UnionConfig) *Union {\n\tobjectType := &Union{}\n\n\tif objectType.err = invariant(config.Name != \"\", \"Type must be named.\"); objectType.err != nil {\n\t\treturn objectType\n\t}\n\tif objectType.err = assertValidName(config.Name); objectType.err != nil {\n\t\treturn objectType\n\t}\n\tobjectType.PrivateName = config.Name\n\tobjectType.PrivateDescription = config.Description\n\tobjectType.ResolveType = config.ResolveType\n\n\tobjectType.typeConfig = config\n\n\treturn objectType\n}\n\nfunc (ut *Union) Types() []*Object {\n\tif ut.initalizedTypes {\n\t\treturn ut.types\n\t}\n\n\tvar unionTypes []*Object\n\tswitch utype := ut.typeConfig.Types.(type) {\n\tcase UnionTypesThunk:\n\t\tunionTypes = utype()\n\tcase []*Object:\n\t\tunionTypes = utype\n\tcase nil:\n\tdefault:\n\t\tut.err = fmt.Errorf(\"Unknown Union.Types type: %T\", ut.typeConfig.Types)\n\t\tut.initalizedTypes = true\n\t\treturn nil\n\t}\n\n\tut.types, ut.err = defineUnionTypes(ut, unionTypes)\n\tut.initalizedTypes = true\n\treturn ut.types\n}\n\nfunc defineUnionTypes(objectType *Union, unionTypes []*Object) ([]*Object, error) {\n\tdefinedUnionTypes := []*Object{}\n\n\tif err := invariantf(\n\t\tlen(unionTypes) > 0,\n\t\t`Must provide Array of types for Union %v.`, objectType.Name(),\n\t); err != nil {\n\t\treturn definedUnionTypes, err\n\t}\n\n\tfor _, ttype := range unionTypes {\n\t\tif err := invariantf(\n\t\t\tttype != nil,\n\t\t\t`%v may only contain Object types, it cannot contain: %v.`, objectType, ttype,\n\t\t); err != nil {\n\t\t\treturn definedUnionTypes, err\n\t\t}\n\t\tif objectType.ResolveType == nil {\n\t\t\tif err := invariantf(\n\t\t\t\tttype.IsTypeOf != nil,\n\t\t\t\t`Union Type %v does not provide a \"resolveType\" function `+\n\t\t\t\t\t`and possible Type %v does not provide a \"isTypeOf\" `+\n\t\t\t\t\t`function. There is no way to resolve this possible type `+\n\t\t\t\t\t`during execution.`, objectType, ttype,\n\t\t\t); err != nil {\n\t\t\t\treturn definedUnionTypes, err\n\t\t\t}\n\t\t}\n\t\tdefinedUnionTypes = append(definedUnionTypes, ttype)\n\t}\n\n\treturn definedUnionTypes, nil\n}\n\nfunc (ut *Union) String() string {\n\treturn ut.PrivateName\n}\n\nfunc (ut *Union) Name() string {\n\treturn ut.PrivateName\n}\n\nfunc (ut *Union) Description() string {\n\treturn ut.PrivateDescription\n}\n\nfunc (ut *Union) Error() error {\n\treturn ut.err\n}\n\n// Enum Type Definition\n//\n// Some leaf values of requests and input values are Enums. GraphQL serializes\n// Enum values as strings, however internally Enums can be represented by any\n// kind of type, often integers.\n//\n// Example:\n//\n//     var RGBType = new Enum({\n//       name: 'RGB',\n//       values: {\n//         RED: { value: 0 },\n//         GREEN: { value: 1 },\n//         BLUE: { value: 2 }\n//       }\n//     });\n//\n// Note: If a value is not provided in a definition, the name of the enum value\n// will be used as its internal value.\n\ntype Enum struct {\n\tPrivateName        string `json:\"name\"`\n\tPrivateDescription string `json:\"description\"`\n\n\tenumConfig   EnumConfig\n\tvalues       []*EnumValueDefinition\n\tvaluesLookup map[interface{}]*EnumValueDefinition\n\tnameLookup   map[string]*EnumValueDefinition\n\n\terr error\n}\ntype EnumValueConfigMap map[string]*EnumValueConfig\ntype EnumValueConfig struct {\n\tValue             interface{} `json:\"value\"`\n\tDeprecationReason string      `json:\"deprecationReason\"`\n\tDescription       string      `json:\"description\"`\n}\ntype EnumConfig struct {\n\tName        string             `json:\"name\"`\n\tValues      EnumValueConfigMap `json:\"values\"`\n\tDescription string             `json:\"description\"`\n}\ntype EnumValueDefinition struct {\n\tName              string      `json:\"name\"`\n\tValue             interface{} `json:\"value\"`\n\tDeprecationReason string      `json:\"deprecationReason\"`\n\tDescription       string      `json:\"description\"`\n}\n\nfunc NewEnum(config EnumConfig) *Enum {\n\tgt := &Enum{}\n\tgt.enumConfig = config\n\n\tif gt.err = assertValidName(config.Name); gt.err != nil {\n\t\treturn gt\n\t}\n\n\tgt.PrivateName = config.Name\n\tgt.PrivateDescription = config.Description\n\tif gt.values, gt.err = gt.defineEnumValues(config.Values); gt.err != nil {\n\t\treturn gt\n\t}\n\n\treturn gt\n}\nfunc (gt *Enum) defineEnumValues(valueMap EnumValueConfigMap) ([]*EnumValueDefinition, error) {\n\tvar err error\n\tvalues := []*EnumValueDefinition{}\n\n\tif err = invariantf(\n\t\tlen(valueMap) > 0,\n\t\t`%v values must be an object with value names as keys.`, gt,\n\t); err != nil {\n\t\treturn values, err\n\t}\n\n\tfor valueName, valueConfig := range valueMap {\n\t\tif err = invariantf(\n\t\t\tvalueConfig != nil,\n\t\t\t`%v.%v must refer to an object with a \"value\" key `+\n\t\t\t\t`representing an internal value but got: %v.`, gt, valueName, valueConfig,\n\t\t); err != nil {\n\t\t\treturn values, err\n\t\t}\n\t\tif err = assertValidName(valueName); err != nil {\n\t\t\treturn values, err\n\t\t}\n\t\tvalue := &EnumValueDefinition{\n\t\t\tName:              valueName,\n\t\t\tValue:             valueConfig.Value,\n\t\t\tDeprecationReason: valueConfig.DeprecationReason,\n\t\t\tDescription:       valueConfig.Description,\n\t\t}\n\t\tif value.Value == nil {\n\t\t\tvalue.Value = valueName\n\t\t}\n\t\tvalues = append(values, value)\n\t}\n\treturn values, nil\n}\nfunc (gt *Enum) Values() []*EnumValueDefinition {\n\treturn gt.values\n}\nfunc (gt *Enum) Serialize(value interface{}) interface{} {\n\tv := value\n\trv := reflect.ValueOf(v)\n\tif kind := rv.Kind(); kind == reflect.Ptr && rv.IsNil() {\n\t\treturn nil\n\t} else if kind == reflect.Ptr {\n\t\tv = reflect.Indirect(reflect.ValueOf(v)).Interface()\n\t}\n\tif enumValue, ok := gt.getValueLookup()[v]; ok {\n\t\treturn enumValue.Name\n\t}\n\treturn nil\n}\nfunc (gt *Enum) ParseValue(value interface{}) interface{} {\n\tvar v string\n\n\tswitch value := value.(type) {\n\tcase string:\n\t\tv = value\n\tcase *string:\n\t\tv = *value\n\tdefault:\n\t\treturn nil\n\t}\n\tif enumValue, ok := gt.getNameLookup()[v]; ok {\n\t\treturn enumValue.Value\n\t}\n\treturn nil\n}\nfunc (gt *Enum) ParseLiteral(valueAST ast.Value) interface{} {\n\tif valueAST, ok := valueAST.(*ast.EnumValue); ok {\n\t\tif enumValue, ok := gt.getNameLookup()[valueAST.Value]; ok {\n\t\t\treturn enumValue.Value\n\t\t}\n\t}\n\treturn nil\n}\nfunc (gt *Enum) Name() string {\n\treturn gt.PrivateName\n}\nfunc (gt *Enum) Description() string {\n\treturn gt.PrivateDescription\n}\nfunc (gt *Enum) String() string {\n\treturn gt.PrivateName\n}\nfunc (gt *Enum) Error() error {\n\treturn gt.err\n}\nfunc (gt *Enum) getValueLookup() map[interface{}]*EnumValueDefinition {\n\tif len(gt.valuesLookup) > 0 {\n\t\treturn gt.valuesLookup\n\t}\n\tvaluesLookup := map[interface{}]*EnumValueDefinition{}\n\tfor _, value := range gt.Values() {\n\t\tvaluesLookup[value.Value] = value\n\t}\n\tgt.valuesLookup = valuesLookup\n\treturn gt.valuesLookup\n}\n\nfunc (gt *Enum) getNameLookup() map[string]*EnumValueDefinition {\n\tif len(gt.nameLookup) > 0 {\n\t\treturn gt.nameLookup\n\t}\n\tnameLookup := map[string]*EnumValueDefinition{}\n\tfor _, value := range gt.Values() {\n\t\tnameLookup[value.Name] = value\n\t}\n\tgt.nameLookup = nameLookup\n\treturn gt.nameLookup\n}\n\n// InputObject Type Definition\n//\n// An input object defines a structured collection of fields which may be\n// supplied to a field argument.\n//\n// # Using `NonNull` will ensure that a value must be provided by the query\n//\n// Example:\n//\n//\tvar GeoPoint = new InputObject({\n//\t  name: 'GeoPoint',\n//\t  fields: {\n//\t    lat: { type: new NonNull(Float) },\n//\t    lon: { type: new NonNull(Float) },\n//\t    alt: { type: Float, defaultValue: 0 },\n//\t  }\n//\t});\ntype InputObject struct {\n\tPrivateName        string `json:\"name\"`\n\tPrivateDescription string `json:\"description\"`\n\n\ttypeConfig InputObjectConfig\n\tfields     InputObjectFieldMap\n\tinit       bool\n\terr        error\n}\ntype InputObjectFieldConfig struct {\n\tType         Input       `json:\"type\"`\n\tDefaultValue interface{} `json:\"defaultValue\"`\n\tDescription  string      `json:\"description\"`\n}\ntype InputObjectField struct {\n\tPrivateName        string      `json:\"name\"`\n\tType               Input       `json:\"type\"`\n\tDefaultValue       interface{} `json:\"defaultValue\"`\n\tPrivateDescription string      `json:\"description\"`\n}\n\nfunc (st *InputObjectField) Name() string {\n\treturn st.PrivateName\n}\nfunc (st *InputObjectField) Description() string {\n\treturn st.PrivateDescription\n}\nfunc (st *InputObjectField) String() string {\n\treturn st.PrivateName\n}\nfunc (st *InputObjectField) Error() error {\n\treturn nil\n}\n\ntype InputObjectConfigFieldMap map[string]*InputObjectFieldConfig\ntype InputObjectFieldMap map[string]*InputObjectField\ntype InputObjectConfigFieldMapThunk func() InputObjectConfigFieldMap\ntype InputObjectConfig struct {\n\tName        string      `json:\"name\"`\n\tFields      interface{} `json:\"fields\"`\n\tDescription string      `json:\"description\"`\n}\n\nfunc NewInputObject(config InputObjectConfig) *InputObject {\n\tgt := &InputObject{}\n\tif gt.err = invariant(config.Name != \"\", \"Type must be named.\"); gt.err != nil {\n\t\treturn gt\n\t}\n\n\tgt.PrivateName = config.Name\n\tgt.PrivateDescription = config.Description\n\tgt.typeConfig = config\n\treturn gt\n}\n\nfunc (gt *InputObject) defineFieldMap() InputObjectFieldMap {\n\tvar (\n\t\tfieldMap InputObjectConfigFieldMap\n\t\terr      error\n\t)\n\tswitch fields := gt.typeConfig.Fields.(type) {\n\tcase InputObjectConfigFieldMap:\n\t\tfieldMap = fields\n\tcase InputObjectConfigFieldMapThunk:\n\t\tfieldMap = fields()\n\t}\n\tresultFieldMap := InputObjectFieldMap{}\n\n\tif gt.err = invariantf(\n\t\tlen(fieldMap) > 0,\n\t\t`%v fields must be an object with field names as keys or a function which return such an object.`, gt,\n\t); gt.err != nil {\n\t\treturn resultFieldMap\n\t}\n\n\tfor fieldName, fieldConfig := range fieldMap {\n\t\tif fieldConfig == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif err = assertValidName(fieldName); err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif gt.err = invariantf(\n\t\t\tfieldConfig.Type != nil,\n\t\t\t`%v.%v field type must be Input Type but got: %v.`, gt, fieldName, fieldConfig.Type,\n\t\t); gt.err != nil {\n\t\t\treturn resultFieldMap\n\t\t}\n\t\tfield := &InputObjectField{}\n\t\tfield.PrivateName = fieldName\n\t\tfield.Type = fieldConfig.Type\n\t\tfield.PrivateDescription = fieldConfig.Description\n\t\tfield.DefaultValue = fieldConfig.DefaultValue\n\t\tresultFieldMap[fieldName] = field\n\t}\n\tgt.init = true\n\treturn resultFieldMap\n}\n\nfunc (gt *InputObject) AddFieldConfig(fieldName string, fieldConfig *InputObjectFieldConfig) {\n\tif fieldName == \"\" || fieldConfig == nil {\n\t\treturn\n\t}\n\tfieldMap, ok := gt.typeConfig.Fields.(InputObjectConfigFieldMap)\n\tif gt.err = invariant(ok, \"Cannot add field to a thunk\"); gt.err != nil {\n\t\treturn\n\t}\n\tfieldMap[fieldName] = fieldConfig\n\tgt.fields = gt.defineFieldMap()\n}\n\nfunc (gt *InputObject) Fields() InputObjectFieldMap {\n\tif !gt.init {\n\t\tgt.fields = gt.defineFieldMap()\n\t}\n\treturn gt.fields\n}\nfunc (gt *InputObject) Name() string {\n\treturn gt.PrivateName\n}\nfunc (gt *InputObject) Description() string {\n\treturn gt.PrivateDescription\n}\nfunc (gt *InputObject) String() string {\n\treturn gt.PrivateName\n}\nfunc (gt *InputObject) Error() error {\n\treturn gt.err\n}\n\n// List Modifier\n//\n// A list is a kind of type marker, a wrapping type which points to another\n// type. Lists are often created within the context of defining the fields of\n// an object type.\n//\n// Example:\n//\n//\tvar PersonType = new Object({\n//\t  name: 'Person',\n//\t  fields: () => ({\n//\t    parents: { type: new List(Person) },\n//\t    children: { type: new List(Person) },\n//\t  })\n//\t})\ntype List struct {\n\tOfType Type `json:\"ofType\"`\n\n\terr error\n}\n\nfunc NewList(ofType Type) *List {\n\tgl := &List{}\n\n\tgl.err = invariantf(ofType != nil, `Can only create List of a Type but got: %v.`, ofType)\n\tif gl.err != nil {\n\t\treturn gl\n\t}\n\n\tgl.OfType = ofType\n\treturn gl\n}\nfunc (gl *List) Name() string {\n\treturn fmt.Sprintf(\"[%v]\", gl.OfType)\n}\nfunc (gl *List) Description() string {\n\treturn \"\"\n}\nfunc (gl *List) String() string {\n\tif gl.OfType != nil {\n\t\treturn gl.Name()\n\t}\n\treturn \"\"\n}\nfunc (gl *List) Error() error {\n\treturn gl.err\n}\n\n// NonNull Modifier\n//\n// A non-null is a kind of type marker, a wrapping type which points to another\n// type. Non-null types enforce that their values are never null and can ensure\n// an error is raised if this ever occurs during a request. It is useful for\n// fields which you can make a strong guarantee on non-nullability, for example\n// usually the id field of a database row will never be null.\n//\n// Example:\n//\n//\tvar RowType = new Object({\n//\t  name: 'Row',\n//\t  fields: () => ({\n//\t    id: { type: new NonNull(String) },\n//\t  })\n//\t})\n//\n// Note: the enforcement of non-nullability occurs within the executor.\ntype NonNull struct {\n\tOfType Type `json:\"ofType\"`\n\n\terr error\n}\n\nfunc NewNonNull(ofType Type) *NonNull {\n\tgl := &NonNull{}\n\n\t_, isOfTypeNonNull := ofType.(*NonNull)\n\tgl.err = invariantf(ofType != nil && !isOfTypeNonNull, `Can only create NonNull of a Nullable Type but got: %v.`, ofType)\n\tif gl.err != nil {\n\t\treturn gl\n\t}\n\tgl.OfType = ofType\n\treturn gl\n}\nfunc (gl *NonNull) Name() string {\n\treturn fmt.Sprintf(\"%v!\", gl.OfType)\n}\nfunc (gl *NonNull) Description() string {\n\treturn \"\"\n}\nfunc (gl *NonNull) String() string {\n\tif gl.OfType != nil {\n\t\treturn gl.Name()\n\t}\n\treturn \"\"\n}\nfunc (gl *NonNull) Error() error {\n\treturn gl.err\n}\n\nvar NameRegExp = regexp.MustCompile(\"^[_a-zA-Z][_a-zA-Z0-9]*$\")\n\nfunc assertValidName(name string) error {\n\treturn invariantf(\n\t\tNameRegExp.MatchString(name),\n\t\t`Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"%v\" does not.`, name)\n\n}\n\ntype ResponsePath struct {\n\tPrev *ResponsePath\n\tKey  interface{}\n}\n\n// WithKey returns a new responsePath containing the new key.\nfunc (p *ResponsePath) WithKey(key interface{}) *ResponsePath {\n\treturn &ResponsePath{\n\t\tPrev: p,\n\t\tKey:  key,\n\t}\n}\n\n// AsArray returns an array of path keys.\nfunc (p *ResponsePath) AsArray() []interface{} {\n\tif p == nil {\n\t\treturn nil\n\t}\n\treturn append(p.Prev.AsArray(), p.Key)\n}\n"
  },
  {
    "path": "definition_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nvar blogImage = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Image\",\n\tFields: graphql.Fields{\n\t\t\"url\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"width\": &graphql.Field{\n\t\t\tType: graphql.Int,\n\t\t},\n\t\t\"height\": &graphql.Field{\n\t\t\tType: graphql.Int,\n\t\t},\n\t},\n})\nvar blogAuthor = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Author\",\n\tFields: graphql.Fields{\n\t\t\"id\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"name\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"pic\": &graphql.Field{\n\t\t\tType: blogImage,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"width\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.Int,\n\t\t\t\t},\n\t\t\t\t\"height\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.Int,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"recentArticle\": &graphql.Field{},\n\t},\n})\nvar blogArticle = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Article\",\n\tFields: graphql.Fields{\n\t\t\"id\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"isPublished\": &graphql.Field{\n\t\t\tType: graphql.Boolean,\n\t\t},\n\t\t\"author\": &graphql.Field{\n\t\t\tType: blogAuthor,\n\t\t},\n\t\t\"title\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"body\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t},\n})\n\nvar blogQuery = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Query\",\n\tFields: graphql.Fields{\n\t\t\"article\": &graphql.Field{\n\t\t\tType: blogArticle,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"feed\": &graphql.Field{\n\t\t\tType: graphql.NewList(blogArticle),\n\t\t},\n\t},\n})\n\nvar blogMutation = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Mutation\",\n\tFields: graphql.Fields{\n\t\t\"writeArticle\": &graphql.Field{\n\t\t\tType: blogArticle,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"title\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n})\n\nvar blogSubscription = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Subscription\",\n\tFields: graphql.Fields{\n\t\t\"articleSubscribe\": &graphql.Field{\n\t\t\tType: blogArticle,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n})\n\nvar objectType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Object\",\n\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\treturn true\n\t},\n})\nvar interfaceType = graphql.NewInterface(graphql.InterfaceConfig{\n\tName: \"Interface\",\n})\nvar unionType = graphql.NewUnion(graphql.UnionConfig{\n\tName: \"Union\",\n\tTypes: []*graphql.Object{\n\t\tobjectType,\n\t},\n})\nvar enumType = graphql.NewEnum(graphql.EnumConfig{\n\tName: \"Enum\",\n\tValues: graphql.EnumValueConfigMap{\n\t\t\"foo\": &graphql.EnumValueConfig{},\n\t},\n})\nvar inputObjectType = graphql.NewInputObject(graphql.InputObjectConfig{\n\tName: \"InputObject\",\n})\n\nfunc init() {\n\tblogAuthor.AddFieldConfig(\"recentArticle\", &graphql.Field{\n\t\tType: blogArticle,\n\t})\n}\n\nfunc TestTypeSystem_DefinitionExample_DefinesAQueryOnlySchema(t *testing.T) {\n\tblogSchema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: blogQuery,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\n\tif blogSchema.QueryType() != blogQuery {\n\t\tt.Fatalf(\"expected blogSchema.GetQueryType() == blogQuery\")\n\t}\n\n\tarticleField, _ := blogQuery.Fields()[\"article\"]\n\tif articleField == nil {\n\t\tt.Fatalf(\"articleField is nil\")\n\t}\n\tarticleFieldType := articleField.Type\n\tif articleFieldType != blogArticle {\n\t\tt.Fatalf(\"articleFieldType expected to equal blogArticle, got: %v\", articleField.Type)\n\t}\n\tif articleFieldType.Name() != \"Article\" {\n\t\tt.Fatalf(\"articleFieldType.Name expected to equal `Article`, got: %v\", articleField.Type.Name())\n\t}\n\tif articleField.Name != \"article\" {\n\t\tt.Fatalf(\"articleField.Name expected to equal `article`, got: %v\", articleField.Name)\n\t}\n\tarticleFieldTypeObject, ok := articleFieldType.(*graphql.Object)\n\tif !ok {\n\t\tt.Fatalf(\"expected articleFieldType to be graphql.Object`, got: %v\", articleField)\n\t}\n\n\t// TODO: expose a Object.GetField(key string), instead of this ghetto way of accessing a field map?\n\ttitleField := articleFieldTypeObject.Fields()[\"title\"]\n\tif titleField == nil {\n\t\tt.Fatalf(\"titleField is nil\")\n\t}\n\tif titleField.Name != \"title\" {\n\t\tt.Fatalf(\"titleField.Name expected to equal title, got: %v\", titleField.Name)\n\t}\n\tif titleField.Type != graphql.String {\n\t\tt.Fatalf(\"titleField.Type expected to equal graphql.String, got: %v\", titleField.Type)\n\t}\n\tif titleField.Type.Name() != \"String\" {\n\t\tt.Fatalf(\"titleField.Type.GetName() expected to equal `String`, got: %v\", titleField.Type.Name())\n\t}\n\n\tauthorField := articleFieldTypeObject.Fields()[\"author\"]\n\tif authorField == nil {\n\t\tt.Fatalf(\"authorField is nil\")\n\t}\n\tauthorFieldObject, ok := authorField.Type.(*graphql.Object)\n\tif !ok {\n\t\tt.Fatalf(\"expected authorField.Type to be Object`, got: %v\", authorField)\n\t}\n\n\trecentArticleField := authorFieldObject.Fields()[\"recentArticle\"]\n\tif recentArticleField == nil {\n\t\tt.Fatalf(\"recentArticleField is nil\")\n\t}\n\tif recentArticleField.Type != blogArticle {\n\t\tt.Fatalf(\"recentArticleField.Type expected to equal blogArticle, got: %v\", recentArticleField.Type)\n\t}\n\n\tfeedField := blogQuery.Fields()[\"feed\"]\n\tfeedFieldList, ok := feedField.Type.(*graphql.List)\n\tif !ok {\n\t\tt.Fatalf(\"expected feedFieldList to be List`, got: %v\", authorField)\n\t}\n\tif feedFieldList.OfType != blogArticle {\n\t\tt.Fatalf(\"feedFieldList.OfType expected to equal blogArticle, got: %v\", feedFieldList.OfType)\n\t}\n\tif feedField.Name != \"feed\" {\n\t\tt.Fatalf(\"feedField.Name expected to equal `feed`, got: %v\", feedField.Name)\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_DefinesAMutationScheme(t *testing.T) {\n\tblogSchema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery:    blogQuery,\n\t\tMutation: blogMutation,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\n\tif blogSchema.MutationType() != blogMutation {\n\t\tt.Fatalf(\"expected blogSchema.GetMutationType() == blogMutation\")\n\t}\n\n\twriteMutation, _ := blogMutation.Fields()[\"writeArticle\"]\n\tif writeMutation == nil {\n\t\tt.Fatalf(\"writeMutation is nil\")\n\t}\n\twriteMutationType := writeMutation.Type\n\tif writeMutationType != blogArticle {\n\t\tt.Fatalf(\"writeMutationType expected to equal blogArticle, got: %v\", writeMutationType)\n\t}\n\tif writeMutationType.Name() != \"Article\" {\n\t\tt.Fatalf(\"writeMutationType.Name expected to equal `Article`, got: %v\", writeMutationType.Name())\n\t}\n\tif writeMutation.Name != \"writeArticle\" {\n\t\tt.Fatalf(\"writeMutation.Name expected to equal `writeArticle`, got: %v\", writeMutation.Name)\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_DefinesASubscriptionScheme(t *testing.T) {\n\tblogSchema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery:        blogQuery,\n\t\tSubscription: blogSubscription,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\n\tif blogSchema.SubscriptionType() != blogSubscription {\n\t\tt.Fatalf(\"expected blogSchema.SubscriptionType() == blogSubscription\")\n\t}\n\n\tsubMutation, _ := blogSubscription.Fields()[\"articleSubscribe\"]\n\tif subMutation == nil {\n\t\tt.Fatalf(\"subMutation is nil\")\n\t}\n\tsubMutationType := subMutation.Type\n\tif subMutationType != blogArticle {\n\t\tt.Fatalf(\"subMutationType expected to equal blogArticle, got: %v\", subMutationType)\n\t}\n\tif subMutationType.Name() != \"Article\" {\n\t\tt.Fatalf(\"subMutationType.Name expected to equal `Article`, got: %v\", subMutationType.Name())\n\t}\n\tif subMutation.Name != \"articleSubscribe\" {\n\t\tt.Fatalf(\"subMutation.Name expected to equal `articleSubscribe`, got: %v\", subMutation.Name)\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_IncludesNestedInputObjectsInTheMap(t *testing.T) {\n\tnestedInputObject := graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"NestedInputObject\",\n\t\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\t\"value\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tsomeInputObject := graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"SomeInputObject\",\n\t\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\t\"nested\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: nestedInputObject,\n\t\t\t},\n\t\t},\n\t})\n\tsomeMutation := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeMutation\",\n\t\tFields: graphql.Fields{\n\t\t\t\"mutateSomething\": &graphql.Field{\n\t\t\t\tType: blogArticle,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: someInputObject,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tsomeSubscription := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeSubscription\",\n\t\tFields: graphql.Fields{\n\t\t\t\"subscribeToSomething\": &graphql.Field{\n\t\t\t\tType: blogArticle,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: someInputObject,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery:        blogQuery,\n\t\tMutation:     someMutation,\n\t\tSubscription: someSubscription,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tif schema.Type(\"NestedInputObject\") != nestedInputObject {\n\t\tt.Fatalf(`schema.GetType(\"NestedInputObject\") expected to equal nestedInputObject, got: %v`, schema.Type(\"NestedInputObject\"))\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_IncludesInterfacesSubTypesInTheTypeMap(t *testing.T) {\n\n\tsomeInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"SomeInterface\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t})\n\n\tsomeSubType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeSubtype\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t\tInterfaces: []*graphql.Interface{someInterface},\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"iface\": &graphql.Field{\n\t\t\t\t\tType: someInterface,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tTypes: []graphql.Type{someSubType},\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tif schema.Type(\"SomeSubtype\") != someSubType {\n\t\tt.Fatalf(`schema.GetType(\"SomeSubtype\") expected to equal someSubType, got: %v`, schema.Type(\"SomeSubtype\"))\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_IncludesInterfacesThunkSubtypesInTheTypeMap(t *testing.T) {\n\n\tsomeInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"SomeInterface\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t})\n\n\tsomeSubType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeSubtype\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t\tInterfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {\n\t\t\treturn []*graphql.Interface{someInterface}\n\t\t}),\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"iface\": &graphql.Field{\n\t\t\t\t\tType: someInterface,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tTypes: []graphql.Type{someSubType},\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tif schema.Type(\"SomeSubtype\") != someSubType {\n\t\tt.Fatalf(`schema.GetType(\"SomeSubtype\") expected to equal someSubType, got: %v`, schema.Type(\"SomeSubtype\"))\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_StringifiesSimpleTypes(t *testing.T) {\n\n\ttype Test struct {\n\t\tttype    graphql.Type\n\t\texpected string\n\t}\n\ttests := []Test{\n\t\t{graphql.Int, \"Int\"},\n\t\t{blogArticle, \"Article\"},\n\t\t{interfaceType, \"Interface\"},\n\t\t{unionType, \"Union\"},\n\t\t{enumType, \"Enum\"},\n\t\t{inputObjectType, \"InputObject\"},\n\t\t{graphql.NewNonNull(graphql.Int), \"Int!\"},\n\t\t{graphql.NewList(graphql.Int), \"[Int]\"},\n\t\t{graphql.NewNonNull(graphql.NewList(graphql.Int)), \"[Int]!\"},\n\t\t{graphql.NewList(graphql.NewNonNull(graphql.Int)), \"[Int!]\"},\n\t\t{graphql.NewList(graphql.NewList(graphql.Int)), \"[[Int]]\"},\n\t}\n\tfor _, test := range tests {\n\t\tttypeStr := fmt.Sprintf(\"%v\", test.ttype)\n\t\tif ttypeStr != test.expected {\n\t\t\tt.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)\n\t\t}\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_IdentifiesInputTypes(t *testing.T) {\n\ttype Test struct {\n\t\tttype    graphql.Type\n\t\texpected bool\n\t}\n\ttests := []Test{\n\t\t{graphql.Int, true},\n\t\t{objectType, false},\n\t\t{interfaceType, false},\n\t\t{unionType, false},\n\t\t{enumType, true},\n\t\t{inputObjectType, true},\n\t}\n\tfor _, test := range tests {\n\t\tttypeStr := fmt.Sprintf(\"%v\", test.ttype)\n\t\tif graphql.IsInputType(test.ttype) != test.expected {\n\t\t\tt.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)\n\t\t}\n\t\tif graphql.IsInputType(graphql.NewList(test.ttype)) != test.expected {\n\t\t\tt.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)\n\t\t}\n\t\tif graphql.IsInputType(graphql.NewNonNull(test.ttype)) != test.expected {\n\t\t\tt.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)\n\t\t}\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_IdentifiesOutputTypes(t *testing.T) {\n\ttype Test struct {\n\t\tttype    graphql.Type\n\t\texpected bool\n\t}\n\ttests := []Test{\n\t\t{graphql.Int, true},\n\t\t{objectType, true},\n\t\t{interfaceType, true},\n\t\t{unionType, true},\n\t\t{enumType, true},\n\t\t{inputObjectType, false},\n\t}\n\tfor _, test := range tests {\n\t\tttypeStr := fmt.Sprintf(\"%v\", test.ttype)\n\t\tif graphql.IsOutputType(test.ttype) != test.expected {\n\t\t\tt.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)\n\t\t}\n\t\tif graphql.IsOutputType(graphql.NewList(test.ttype)) != test.expected {\n\t\t\tt.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)\n\t\t}\n\t\tif graphql.IsOutputType(graphql.NewNonNull(test.ttype)) != test.expected {\n\t\t\tt.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)\n\t\t}\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_ProhibitsNestingNonNullInsideNonNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewNonNull(graphql.Int))\n\texpected := `Can only create NonNull of a Nullable Type but got: Int!.`\n\tif ttype.Error().Error() != expected {\n\t\tt.Fatalf(`expected %v , got: %v`, expected, ttype.Error())\n\t}\n}\nfunc TestTypeSystem_DefinitionExample_ProhibitsNilInNonNull(t *testing.T) {\n\tttype := graphql.NewNonNull(nil)\n\texpected := `Can only create NonNull of a Nullable Type but got: <nil>.`\n\tif ttype.Error().Error() != expected {\n\t\tt.Fatalf(`expected %v , got: %v`, expected, ttype.Error())\n\t}\n}\nfunc TestTypeSystem_DefinitionExample_ProhibitsNilTypeInUnions(t *testing.T) {\n\tttype := graphql.NewUnion(graphql.UnionConfig{\n\t\tName:  \"BadUnion\",\n\t\tTypes: []*graphql.Object{nil},\n\t})\n\tttype.Types()\n\texpected := `BadUnion may only contain Object types, it cannot contain: <nil>.`\n\tif ttype.Error().Error() != expected {\n\t\tt.Fatalf(`expected %v , got: %v`, expected, ttype.Error())\n\t}\n}\nfunc TestTypeSystem_DefinitionExample_DoesNotMutatePassedFieldDefinitions(t *testing.T) {\n\tfields := graphql.Fields{\n\t\t\"field1\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"field2\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\ttestObject1 := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:   \"Test1\",\n\t\tFields: fields,\n\t})\n\ttestObject2 := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:   \"Test2\",\n\t\tFields: fields,\n\t})\n\tif !reflect.DeepEqual(testObject1.Fields(), testObject2.Fields()) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(testObject1.Fields(), testObject2.Fields()))\n\t}\n\n\texpectedFields := graphql.Fields{\n\t\t\"field1\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"field2\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tif !reflect.DeepEqual(fields, expectedFields) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedFields, fields))\n\t}\n\n\tinputFields := graphql.InputObjectConfigFieldMap{\n\t\t\"field1\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"field2\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.String,\n\t\t},\n\t}\n\texpectedInputFields := graphql.InputObjectConfigFieldMap{\n\t\t\"field1\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"field2\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.String,\n\t\t},\n\t}\n\ttestInputObject1 := graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName:   \"Test1\",\n\t\tFields: inputFields,\n\t})\n\ttestInputObject2 := graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName:   \"Test2\",\n\t\tFields: inputFields,\n\t})\n\tif !reflect.DeepEqual(testInputObject1.Fields(), testInputObject2.Fields()) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(testInputObject1.Fields(), testInputObject2.Fields()))\n\t}\n\tif !reflect.DeepEqual(inputFields, expectedInputFields) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedInputFields, fields))\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_IncludesFieldsThunk(t *testing.T) {\n\tvar someObject *graphql.Object\n\tsomeObject = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t\tFields: (graphql.FieldsThunk)(func() graphql.Fields {\n\t\t\treturn graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: graphql.Int,\n\t\t\t\t},\n\t\t\t\t\"s\": &graphql.Field{\n\t\t\t\t\tType: someObject,\n\t\t\t\t},\n\t\t\t}\n\t\t}),\n\t})\n\tfieldMap := someObject.Fields()\n\tif !reflect.DeepEqual(fieldMap[\"s\"].Type, someObject) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(fieldMap[\"s\"].Type, someObject))\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExampe_AllowsCyclicFieldTypes(t *testing.T) {\n\tpersonType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Person\",\n\t\tFields: (graphql.FieldsThunk)(func() graphql.Fields {\n\t\t\treturn graphql.Fields{\n\t\t\t\t\"name\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"bestFriend\": &graphql.Field{\n\t\t\t\t\tType: personType,\n\t\t\t\t},\n\t\t\t}\n\t\t}),\n\t})\n\n\tfieldMap := personType.Fields()\n\tif !reflect.DeepEqual(fieldMap[\"name\"].Type, graphql.String) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(fieldMap[\"bestFriend\"].Type, personType))\n\t}\n\n}\n\nfunc TestTypeSystem_DefinitionExample_CanAddInputObjectField(t *testing.T) {\n\tio := graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"inputObject\",\n\t\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\t\"value\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tio.AddFieldConfig(\"newValue\", &graphql.InputObjectFieldConfig{\n\t\tType: graphql.Int,\n\t})\n\tfieldMap := io.Fields()\n\n\tif len(fieldMap) < 2 {\n\t\tt.Fatalf(\"Unexpected result, inputObject should have two fields, has %d\", len(fieldMap))\n\t}\n\tif _, ok := fieldMap[\"value\"]; !ok {\n\t\tt.Fatal(\"Unexpected result, inputObject should have a field named 'value'\")\n\t}\n\tif _, ok := fieldMap[\"newValue\"]; !ok {\n\t\tt.Fatal(\"Unexpected result, inputObject should have a field named 'newValue'\")\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_IncludesUnionTypesThunk(t *testing.T) {\n\tsomeObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t})\n\n\tsomeOtherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeOtherObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"g\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t})\n\n\tsomeUnion := graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"SomeUnion\",\n\t\tTypes: (graphql.UnionTypesThunk)(func() []*graphql.Object {\n\t\t\treturn []*graphql.Object{someObject, someOtherObject}\n\t\t}),\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t})\n\n\tunionTypes := someUnion.Types()\n\n\tif someUnion.Error() != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", someUnion.Error().Error())\n\t}\n\tif len(unionTypes) != 2 {\n\t\tt.Fatalf(\"Unexpected result, someUnion should have two unionTypes, has %d\", len(unionTypes))\n\t}\n}\n\nfunc TestTypeSystem_DefinitionExample_HandlesInvalidUnionTypes(t *testing.T) {\n\tsomeUnion := graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"SomeUnion\",\n\t\tTypes: (graphql.InterfacesThunk)(func() []*graphql.Interface {\n\t\t\treturn []*graphql.Interface{}\n\t\t}),\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t})\n\n\tunionTypes := someUnion.Types()\n\texpected := \"Unknown Union.Types type: graphql.InterfacesThunk\"\n\n\tif someUnion.Error().Error() != expected {\n\t\tt.Fatalf(\"Unexpected error, got: %v, want: %v\", someUnion.Error().Error(), expected)\n\t}\n\tif unionTypes != nil {\n\t\tt.Fatalf(\"Unexpected result, got: %v, want: nil\", unionTypes)\n\t}\n}\n\nfunc TestIsAbstractType(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tttype    interface{}\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"Interface type should return true\",\n\t\t\tttype:    graphql.NewInterface(graphql.InterfaceConfig{Name: \"TestInterface\"}),\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Union type should return true\",\n\t\t\tttype:    graphql.NewUnion(graphql.UnionConfig{Name: \"TestUnion\"}),\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Scalar type should return false\",\n\t\t\tttype:    graphql.NewScalar(graphql.ScalarConfig{Name: \"TestScalar\", Serialize: func(v interface{}) interface{} { return v }}),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Object type should return false\",\n\t\t\tttype:    graphql.NewObject(graphql.ObjectConfig{Name: \"TestObject\"}),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Enum type should return false\",\n\t\t\tttype:    graphql.NewEnum(graphql.EnumConfig{Name: \"TestEnum\", Values: graphql.EnumValueConfigMap{\"A\": &graphql.EnumValueConfig{}}}),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"InputObject type should return false\",\n\t\t\tttype:    graphql.NewInputObject(graphql.InputObjectConfig{Name: \"TestInputObject\"}),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"List type should return false\",\n\t\t\tttype:    graphql.NewList(graphql.NewScalar(graphql.ScalarConfig{Name: \"TestScalar\", Serialize: func(v interface{}) interface{} { return v }})),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"NonNull type should return false\",\n\t\t\tttype:    graphql.NewNonNull(graphql.NewScalar(graphql.ScalarConfig{Name: \"TestScalar\", Serialize: func(v interface{}) interface{} { return v }})),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"nil type should return false\",\n\t\t\tttype:    nil,\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"string type should return false\",\n\t\t\tttype:    \"not a type\",\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tresult := graphql.IsAbstractType(tt.ttype)\n\t\t\tif result != tt.expected {\n\t\t\t\tt.Errorf(\"IsAbstractType(%v) = %v; want %v\", tt.ttype, result, tt.expected)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetNullable(t *testing.T) {\n\tscalarType := graphql.NewScalar(graphql.ScalarConfig{Name: \"TestScalar\", Serialize: func(v interface{}) interface{} { return v }})\n\tobjectType := graphql.NewObject(graphql.ObjectConfig{Name: \"TestObject\"})\n\tlistType := graphql.NewList(scalarType)\n\n\ttests := []struct {\n\t\tname     string\n\t\tttype    graphql.Type\n\t\texpected graphql.Type\n\t}{\n\t\t{\n\t\t\tname:     \"NonNull Scalar should return Scalar\",\n\t\t\tttype:    graphql.NewNonNull(scalarType),\n\t\t\texpected: scalarType,\n\t\t},\n\t\t{\n\t\t\tname:     \"NonNull Object should return Object\",\n\t\t\tttype:    graphql.NewNonNull(objectType),\n\t\t\texpected: objectType,\n\t\t},\n\t\t{\n\t\t\tname:     \"NonNull List should return List\",\n\t\t\tttype:    graphql.NewNonNull(listType),\n\t\t\texpected: listType,\n\t\t},\n\t\t{\n\t\t\tname:     \"Scalar should return Scalar\",\n\t\t\tttype:    scalarType,\n\t\t\texpected: scalarType,\n\t\t},\n\t\t{\n\t\t\tname:     \"Object should return Object\",\n\t\t\tttype:    objectType,\n\t\t\texpected: objectType,\n\t\t},\n\t\t{\n\t\t\tname:     \"List should return List\",\n\t\t\tttype:    listType,\n\t\t\texpected: listType,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tresult := graphql.GetNullable(tt.ttype)\n\t\t\tif result != tt.expected {\n\t\t\t\tt.Errorf(\"GetNullable(%v) = %v; want %v\", tt.ttype, result, tt.expected)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNewScalar(t *testing.T) {\n\ttests := []struct {\n\t\tname          string\n\t\tconfig        graphql.ScalarConfig\n\t\texpectedError bool\n\t}{\n\t\t{\n\t\t\tname: \"empty name should error\",\n\t\t\tconfig: graphql.ScalarConfig{\n\t\t\t\tName:      \"\",\n\t\t\t\tSerialize: func(v interface{}) interface{} { return v },\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"invalid name starting with number should error\",\n\t\t\tconfig: graphql.ScalarConfig{\n\t\t\t\tName:      \"123Invalid\",\n\t\t\t\tSerialize: func(v interface{}) interface{} { return v },\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"invalid name with special characters should error\",\n\t\t\tconfig: graphql.ScalarConfig{\n\t\t\t\tName:      \"Invalid-Name\",\n\t\t\t\tSerialize: func(v interface{}) interface{} { return v },\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"valid scalar with underscore should succeed\",\n\t\t\tconfig: graphql.ScalarConfig{\n\t\t\t\tName:      \"_ValidScalar\",\n\t\t\t\tSerialize: func(v interface{}) interface{} { return v },\n\t\t\t},\n\t\t\texpectedError: false,\n\t\t},\n\t\t{\n\t\t\tname: \"valid scalar with alphanumeric should succeed\",\n\t\t\tconfig: graphql.ScalarConfig{\n\t\t\t\tName:      \"ValidScalar123\",\n\t\t\t\tSerialize: func(v interface{}) interface{} { return v },\n\t\t\t},\n\t\t\texpectedError: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tscalar := graphql.NewScalar(tt.config)\n\t\t\tif tt.expectedError && scalar.Error() == nil {\n\t\t\t\tt.Errorf(\"NewScalar(%v) expected error but got none\", tt.config.Name)\n\t\t\t}\n\t\t\tif !tt.expectedError && scalar.Error() != nil {\n\t\t\t\tt.Errorf(\"NewScalar(%v) unexpected error: %v\", tt.config.Name, scalar.Error())\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "directives.go",
    "content": "package graphql\n\nconst (\n\t// Operations\n\tDirectiveLocationQuery              = \"QUERY\"\n\tDirectiveLocationMutation           = \"MUTATION\"\n\tDirectiveLocationSubscription       = \"SUBSCRIPTION\"\n\tDirectiveLocationField              = \"FIELD\"\n\tDirectiveLocationFragmentDefinition = \"FRAGMENT_DEFINITION\"\n\tDirectiveLocationFragmentSpread     = \"FRAGMENT_SPREAD\"\n\tDirectiveLocationInlineFragment     = \"INLINE_FRAGMENT\"\n\n\t// Schema Definitions\n\tDirectiveLocationSchema               = \"SCHEMA\"\n\tDirectiveLocationScalar               = \"SCALAR\"\n\tDirectiveLocationObject               = \"OBJECT\"\n\tDirectiveLocationFieldDefinition      = \"FIELD_DEFINITION\"\n\tDirectiveLocationArgumentDefinition   = \"ARGUMENT_DEFINITION\"\n\tDirectiveLocationInterface            = \"INTERFACE\"\n\tDirectiveLocationUnion                = \"UNION\"\n\tDirectiveLocationEnum                 = \"ENUM\"\n\tDirectiveLocationEnumValue            = \"ENUM_VALUE\"\n\tDirectiveLocationInputObject          = \"INPUT_OBJECT\"\n\tDirectiveLocationInputFieldDefinition = \"INPUT_FIELD_DEFINITION\"\n)\n\n// DefaultDeprecationReason Constant string used for default reason for a deprecation.\nconst DefaultDeprecationReason = \"No longer supported\"\n\n// SpecifiedRules The full list of specified directives.\nvar SpecifiedDirectives = []*Directive{\n\tIncludeDirective,\n\tSkipDirective,\n\tDeprecatedDirective,\n}\n\n// Directive structs are used by the GraphQL runtime as a way of modifying execution\n// behavior. Type system creators will usually not create these directly.\ntype Directive struct {\n\tName        string      `json:\"name\"`\n\tDescription string      `json:\"description\"`\n\tLocations   []string    `json:\"locations\"`\n\tArgs        []*Argument `json:\"args\"`\n\n\terr error\n}\n\n// DirectiveConfig options for creating a new GraphQLDirective\ntype DirectiveConfig struct {\n\tName        string              `json:\"name\"`\n\tDescription string              `json:\"description\"`\n\tLocations   []string            `json:\"locations\"`\n\tArgs        FieldConfigArgument `json:\"args\"`\n}\n\nfunc NewDirective(config DirectiveConfig) *Directive {\n\tdir := &Directive{}\n\n\t// Ensure directive is named\n\tif dir.err = invariant(config.Name != \"\", \"Directive must be named.\"); dir.err != nil {\n\t\treturn dir\n\t}\n\n\t// Ensure directive name is valid\n\tif dir.err = assertValidName(config.Name); dir.err != nil {\n\t\treturn dir\n\t}\n\n\t// Ensure locations are provided for directive\n\tif dir.err = invariant(len(config.Locations) > 0, \"Must provide locations for directive.\"); dir.err != nil {\n\t\treturn dir\n\t}\n\n\targs := []*Argument{}\n\n\tfor argName, argConfig := range config.Args {\n\t\tif dir.err = assertValidName(argName); dir.err != nil {\n\t\t\treturn dir\n\t\t}\n\t\targs = append(args, &Argument{\n\t\t\tPrivateName:        argName,\n\t\t\tPrivateDescription: argConfig.Description,\n\t\t\tType:               argConfig.Type,\n\t\t\tDefaultValue:       argConfig.DefaultValue,\n\t\t})\n\t}\n\n\tdir.Name = config.Name\n\tdir.Description = config.Description\n\tdir.Locations = config.Locations\n\tdir.Args = args\n\treturn dir\n}\n\n// IncludeDirective is used to conditionally include fields or fragments.\nvar IncludeDirective = NewDirective(DirectiveConfig{\n\tName: \"include\",\n\tDescription: \"Directs the executor to include this field or fragment only when \" +\n\t\t\"the `if` argument is true.\",\n\tLocations: []string{\n\t\tDirectiveLocationField,\n\t\tDirectiveLocationFragmentSpread,\n\t\tDirectiveLocationInlineFragment,\n\t},\n\tArgs: FieldConfigArgument{\n\t\t\"if\": &ArgumentConfig{\n\t\t\tType:        NewNonNull(Boolean),\n\t\t\tDescription: \"Included when true.\",\n\t\t},\n\t},\n})\n\n// SkipDirective Used to conditionally skip (exclude) fields or fragments.\nvar SkipDirective = NewDirective(DirectiveConfig{\n\tName: \"skip\",\n\tDescription: \"Directs the executor to skip this field or fragment when the `if` \" +\n\t\t\"argument is true.\",\n\tArgs: FieldConfigArgument{\n\t\t\"if\": &ArgumentConfig{\n\t\t\tType:        NewNonNull(Boolean),\n\t\t\tDescription: \"Skipped when true.\",\n\t\t},\n\t},\n\tLocations: []string{\n\t\tDirectiveLocationField,\n\t\tDirectiveLocationFragmentSpread,\n\t\tDirectiveLocationInlineFragment,\n\t},\n})\n\n// DeprecatedDirective  Used to declare element of a GraphQL schema as deprecated.\nvar DeprecatedDirective = NewDirective(DirectiveConfig{\n\tName:        \"deprecated\",\n\tDescription: \"Marks an element of a GraphQL schema as no longer supported.\",\n\tArgs: FieldConfigArgument{\n\t\t\"reason\": &ArgumentConfig{\n\t\t\tType: String,\n\t\t\tDescription: \"Explains why this element was deprecated, usually also including a \" +\n\t\t\t\t\"suggestion for how to access supported similar data. Formatted\" +\n\t\t\t\t\"in [Markdown](https://daringfireball.net/projects/markdown/).\",\n\t\t\tDefaultValue: DefaultDeprecationReason,\n\t\t},\n\t},\n\tLocations: []string{\n\t\tDirectiveLocationFieldDefinition,\n\t\tDirectiveLocationEnumValue,\n\t},\n})\n"
  },
  {
    "path": "directives_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nvar directivesTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"TestType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"b\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}),\n})\n\nvar directivesTestData map[string]interface{} = map[string]interface{}{\n\t\"a\": func() interface{} { return \"a\" },\n\t\"b\": func() interface{} { return \"b\" },\n}\n\nfunc executeDirectivesTestQuery(t *testing.T, doc string) *graphql.Result {\n\tast := testutil.TestParse(t, doc)\n\tep := graphql.ExecuteParams{\n\t\tSchema: directivesTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   directivesTestData,\n\t}\n\treturn testutil.TestExecute(t, ep)\n}\n\nfunc TestDirectives_DirectivesMustBeNamed(t *testing.T) {\n\tinvalidDirective := graphql.NewDirective(graphql.DirectiveConfig{\n\t\tLocations: []string{\n\t\t\tgraphql.DirectiveLocationField,\n\t\t},\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"TestType\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tDirectives: []*graphql.Directive{invalidDirective},\n\t})\n\tactualErr := gqlerrors.FormatError(err)\n\texpectedErr := gqlerrors.FormatError(errors.New(\"Directive must be named.\"))\n\tif !testutil.EqualFormattedError(expectedErr, actualErr) {\n\t\tt.Fatalf(\"Expected error to be equal, got: %v\", testutil.Diff(expectedErr, actualErr))\n\t}\n}\n\nfunc TestDirectives_DirectiveNameMustBeValid(t *testing.T) {\n\tinvalidDirective := graphql.NewDirective(graphql.DirectiveConfig{\n\t\tName: \"123invalid name\",\n\t\tLocations: []string{\n\t\t\tgraphql.DirectiveLocationField,\n\t\t},\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"TestType\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tDirectives: []*graphql.Directive{invalidDirective},\n\t})\n\tactualErr := gqlerrors.FormatError(err)\n\texpectedErr := gqlerrors.FormatError(errors.New(`Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"123invalid name\" does not.`))\n\tif !testutil.EqualFormattedError(expectedErr, actualErr) {\n\t\tt.Fatalf(\"Expected error to be equal, got: %v\", testutil.Diff(expectedErr, actualErr))\n\t}\n}\n\nfunc TestDirectives_DirectiveNameMustProvideLocations(t *testing.T) {\n\tinvalidDirective := graphql.NewDirective(graphql.DirectiveConfig{\n\t\tName: \"skip\",\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"TestType\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tDirectives: []*graphql.Directive{invalidDirective},\n\t})\n\tactualErr := gqlerrors.FormatError(err)\n\texpectedErr := gqlerrors.FormatError(errors.New(`Must provide locations for directive.`))\n\tif !testutil.EqualFormattedError(expectedErr, actualErr) {\n\t\tt.Fatalf(\"Expected error to be equal, got: %v\", testutil.Diff(expectedErr, actualErr))\n\t}\n}\n\nfunc TestDirectives_DirectiveArgNamesMustBeValid(t *testing.T) {\n\tinvalidDirective := graphql.NewDirective(graphql.DirectiveConfig{\n\t\tName: \"skip\",\n\t\tDescription: \"Directs the executor to skip this field or fragment when the `if` \" +\n\t\t\t\"argument is true.\",\n\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\"123if\": &graphql.ArgumentConfig{\n\t\t\t\tType:        graphql.NewNonNull(graphql.Boolean),\n\t\t\t\tDescription: \"Skipped when true.\",\n\t\t\t},\n\t\t},\n\t\tLocations: []string{\n\t\t\tgraphql.DirectiveLocationField,\n\t\t\tgraphql.DirectiveLocationFragmentSpread,\n\t\t\tgraphql.DirectiveLocationInlineFragment,\n\t\t},\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"TestType\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tDirectives: []*graphql.Directive{invalidDirective},\n\t})\n\tactualErr := gqlerrors.FormatError(err)\n\texpectedErr := gqlerrors.FormatError(errors.New(`Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"123if\" does not.`))\n\tif !testutil.EqualFormattedError(expectedErr, actualErr) {\n\t\tt.Fatalf(\"Expected error to be equal, got: %v\", testutil.Diff(expectedErr, actualErr))\n\t}\n}\n\nfunc TestDirectivesWorksWithoutDirectives(t *testing.T) {\n\tquery := `{ a, b }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnScalarsIfTrueIncludesScalar(t *testing.T) {\n\tquery := `{ a, b @include(if: true) }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnScalarsIfFalseOmitsOnScalar(t *testing.T) {\n\tquery := `{ a, b @include(if: false) }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnScalarsUnlessFalseIncludesScalar(t *testing.T) {\n\tquery := `{ a, b @skip(if: false) }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnScalarsUnlessTrueOmitsScalar(t *testing.T) {\n\tquery := `{ a, b @skip(if: true) }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnFragmentSpreadsIfFalseOmitsFragmentSpread(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ...Frag @include(if: false)\n        }\n        fragment Frag on TestType {\n          b\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnFragmentSpreadsIfTrueIncludesFragmentSpread(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ...Frag @include(if: true)\n        }\n        fragment Frag on TestType {\n          b\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnFragmentSpreadsUnlessFalseIncludesFragmentSpread(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ...Frag @skip(if: false)\n        }\n        fragment Frag on TestType {\n          b\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnFragmentSpreadsUnlessTrueOmitsFragmentSpread(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ...Frag @skip(if: true)\n        }\n        fragment Frag on TestType {\n          b\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnInlineFragmentIfFalseOmitsInlineFragment(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ... on TestType @include(if: false) {\n            b\n          }\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnInlineFragmentIfTrueIncludesInlineFragment(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ... on TestType @include(if: true) {\n            b\n          }\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnInlineFragmentUnlessFalseIncludesInlineFragment(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ... on TestType @skip(if: false) {\n            b\n          }\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnInlineFragmentUnlessTrueIncludesInlineFragment(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ... on TestType @skip(if: true) {\n            b\n          }\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnAnonymousInlineFragmentIfFalseOmitsAnonymousInlineFragment(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ... @include(if: false) {\n            b\n          }\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnAnonymousInlineFragmentIfTrueIncludesAnonymousInlineFragment(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ... @include(if: true) {\n            b\n          }\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnAnonymousInlineFragmentUnlessFalseIncludesAnonymousInlineFragment(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ... @skip(if: false) {\n            b\n          }\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksOnAnonymousInlineFragmentUnlessTrueIncludesAnonymousInlineFragment(t *testing.T) {\n\tquery := `\n        query Q {\n          a\n          ... @skip(if: true) {\n            b\n          }\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksWithSkipAndIncludeDirectives_IncludeAndNoSkip(t *testing.T) {\n\tquery := `{ a, b @include(if: true) @skip(if: false) }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksWithSkipAndIncludeDirectives_IncludeAndSkip(t *testing.T) {\n\tquery := `{ a, b @include(if: true) @skip(if: true) }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksWithSkipAndIncludeDirectives_NoIncludeAndSkip(t *testing.T) {\n\tquery := `{ a, b @include(if: false) @skip(if: true) }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDirectivesWorksWithSkipAndIncludeDirectives_NoIncludeOrSkip(t *testing.T) {\n\tquery := `{ a, b @include(if: false) @skip(if: false) }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t},\n\t}\n\tresult := executeDirectivesTestQuery(t, query)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "enum_type_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nvar enumTypeTestColorType = graphql.NewEnum(graphql.EnumConfig{\n\tName: \"Color\",\n\tValues: graphql.EnumValueConfigMap{\n\t\t\"RED\": &graphql.EnumValueConfig{\n\t\t\tValue: 0,\n\t\t},\n\t\t\"GREEN\": &graphql.EnumValueConfig{\n\t\t\tValue: 1,\n\t\t},\n\t\t\"BLUE\": &graphql.EnumValueConfig{\n\t\t\tValue: 2,\n\t\t},\n\t},\n})\nvar enumTypeTestQueryType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Query\",\n\tFields: graphql.Fields{\n\t\t\"colorEnum\": &graphql.Field{\n\t\t\tType: enumTypeTestColorType,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"fromEnum\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: enumTypeTestColorType,\n\t\t\t\t},\n\t\t\t\t\"fromInt\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.Int,\n\t\t\t\t},\n\t\t\t\t\"fromString\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\tif fromInt, ok := p.Args[\"fromInt\"]; ok {\n\t\t\t\t\treturn fromInt, nil\n\t\t\t\t}\n\t\t\t\tif fromString, ok := p.Args[\"fromString\"]; ok {\n\t\t\t\t\treturn fromString, nil\n\t\t\t\t}\n\t\t\t\tif fromEnum, ok := p.Args[\"fromEnum\"]; ok {\n\t\t\t\t\treturn fromEnum, nil\n\t\t\t\t}\n\t\t\t\treturn nil, nil\n\t\t\t},\n\t\t},\n\t\t\"colorInt\": &graphql.Field{\n\t\t\tType: graphql.Int,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"fromEnum\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: enumTypeTestColorType,\n\t\t\t\t},\n\t\t\t\t\"fromInt\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.Int,\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\tif fromInt, ok := p.Args[\"fromInt\"]; ok {\n\t\t\t\t\treturn fromInt, nil\n\t\t\t\t}\n\t\t\t\tif fromEnum, ok := p.Args[\"fromEnum\"]; ok {\n\t\t\t\t\treturn fromEnum, nil\n\t\t\t\t}\n\t\t\t\treturn nil, nil\n\t\t\t},\n\t\t},\n\t},\n})\nvar enumTypeTestMutationType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Mutation\",\n\tFields: graphql.Fields{\n\t\t\"favoriteEnum\": &graphql.Field{\n\t\t\tType: enumTypeTestColorType,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"color\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: enumTypeTestColorType,\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\tif color, ok := p.Args[\"color\"]; ok {\n\t\t\t\t\treturn color, nil\n\t\t\t\t}\n\t\t\t\treturn nil, nil\n\t\t\t},\n\t\t},\n\t},\n})\n\nvar enumTypeTestSubscriptionType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Subscription\",\n\tFields: graphql.Fields{\n\t\t\"subscribeToEnum\": &graphql.Field{\n\t\t\tType: enumTypeTestColorType,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"color\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: enumTypeTestColorType,\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\tif color, ok := p.Args[\"color\"]; ok {\n\t\t\t\t\treturn color, nil\n\t\t\t\t}\n\t\t\t\treturn nil, nil\n\t\t\t},\n\t\t},\n\t},\n})\n\nvar enumTypeTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\tQuery:        enumTypeTestQueryType,\n\tMutation:     enumTypeTestMutationType,\n\tSubscription: enumTypeTestSubscriptionType,\n})\n\nfunc executeEnumTypeTest(t *testing.T, query string) *graphql.Result {\n\tresult := g(t, graphql.Params{\n\t\tSchema:        enumTypeTestSchema,\n\t\tRequestString: query,\n\t})\n\treturn result\n}\nfunc executeEnumTypeTestWithParams(t *testing.T, query string, params map[string]interface{}) *graphql.Result {\n\tresult := g(t, graphql.Params{\n\t\tSchema:         enumTypeTestSchema,\n\t\tRequestString:  query,\n\t\tVariableValues: params,\n\t})\n\treturn result\n}\nfunc TestTypeSystem_EnumValues_AcceptsEnumLiteralsAsInput(t *testing.T) {\n\tquery := \"{ colorInt(fromEnum: GREEN) }\"\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"colorInt\": 1,\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestTypeSystem_EnumValues_EnumMayBeOutputType(t *testing.T) {\n\tquery := \"{ colorEnum(fromInt: 1) }\"\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"colorEnum\": \"GREEN\",\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_EnumMayBeBothInputAndOutputType(t *testing.T) {\n\tquery := \"{ colorEnum(fromEnum: GREEN) }\"\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"colorEnum\": \"GREEN\",\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_DoesNotAcceptStringLiterals(t *testing.T) {\n\tquery := `{ colorEnum(fromEnum: \"GREEN\") }`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Argument \\\"fromEnum\\\" has invalid value \\\"GREEN\\\".\\nExpected type \\\"Color\\\", found \\\"GREEN\\\".\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 1, Column: 23},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !testutil.EqualErrorMessage(expected, result, 0) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_DoesNotAcceptIncorrectInternalValue(t *testing.T) {\n\tquery := `{ colorEnum(fromString: \"GREEN\") }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"colorEnum\": nil,\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_DoesNotAcceptInternalValueInPlaceOfEnumLiteral(t *testing.T) {\n\tquery := `{ colorEnum(fromEnum: 1) }`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Argument \\\"fromEnum\\\" has invalid value 1.\\nExpected type \\\"Color\\\", found 1.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 1, Column: 23},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !testutil.EqualErrorMessage(expected, result, 0) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestTypeSystem_EnumValues_DoesNotAcceptEnumLiteralInPlaceOfInt(t *testing.T) {\n\tquery := `{ colorEnum(fromInt: GREEN) }`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Argument \\\"fromInt\\\" has invalid value GREEN.\\nExpected type \\\"Int\\\", found GREEN.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 1, Column: 23},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !testutil.EqualErrorMessage(expected, result, 0) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestTypeSystem_EnumValues_AcceptsJSONStringAsEnumVariable(t *testing.T) {\n\tquery := `query test($color: Color!) { colorEnum(fromEnum: $color) }`\n\tparams := map[string]interface{}{\n\t\t\"color\": \"BLUE\",\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"colorEnum\": \"BLUE\",\n\t\t},\n\t}\n\tresult := executeEnumTypeTestWithParams(t, query, params)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestTypeSystem_EnumValues_AcceptsEnumLiteralsAsInputArgumentsToMutations(t *testing.T) {\n\tquery := `mutation x($color: Color!) { favoriteEnum(color: $color) }`\n\tparams := map[string]interface{}{\n\t\t\"color\": \"GREEN\",\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"favoriteEnum\": \"GREEN\",\n\t\t},\n\t}\n\tresult := executeEnumTypeTestWithParams(t, query, params)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestTypeSystem_EnumValues_AcceptsEnumLiteralsAsInputArgumentsToSubscriptions(t *testing.T) {\n\tquery := `subscription x($color: Color!) { subscribeToEnum(color: $color) }`\n\tparams := map[string]interface{}{\n\t\t\"color\": \"GREEN\",\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"subscribeToEnum\": \"GREEN\",\n\t\t},\n\t}\n\tresult := executeEnumTypeTestWithParams(t, query, params)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_DoesNotAcceptInternalValueAsEnumVariable(t *testing.T) {\n\tquery := `query test($color: Color!) { colorEnum(fromEnum: $color) }`\n\tparams := map[string]interface{}{\n\t\t\"color\": 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Variable \\\"$color\\\" got invalid value 2.\\nExpected type \\\"Color\\\", found \\\"2\\\".\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 1, Column: 12},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := executeEnumTypeTestWithParams(t, query, params)\n\tif !testutil.EqualErrorMessage(expected, result, 0) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_DoesNotAcceptStringVariablesAsEnumInput(t *testing.T) {\n\tquery := `query test($color: String!) { colorEnum(fromEnum: $color) }`\n\tparams := map[string]interface{}{\n\t\t\"color\": \"BLUE\",\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$color\" of type \"String!\" used in position expecting type \"Color\".`,\n\t\t\t},\n\t\t},\n\t}\n\tresult := executeEnumTypeTestWithParams(t, query, params)\n\tif !testutil.EqualErrorMessage(expected, result, 0) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_DoesNotAcceptInternalValueVariableAsEnumInput(t *testing.T) {\n\tquery := `query test($color: Int!) { colorEnum(fromEnum: $color) }`\n\tparams := map[string]interface{}{\n\t\t\"color\": 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$color\" of type \"Int!\" used in position expecting type \"Color\".`,\n\t\t\t},\n\t\t},\n\t}\n\tresult := executeEnumTypeTestWithParams(t, query, params)\n\tif !testutil.EqualErrorMessage(expected, result, 0) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_EnumValueMayHaveAnInternalValueOfZero(t *testing.T) {\n\tquery := `{\n        colorEnum(fromEnum: RED)\n        colorInt(fromEnum: RED)\n      }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"colorEnum\": \"RED\",\n\t\t\t\"colorInt\":  0,\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestTypeSystem_EnumValues_EnumValueMayBeNullable(t *testing.T) {\n\tquery := `{\n        colorEnum\n        colorInt\n      }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"colorEnum\": nil,\n\t\t\t\"colorInt\":  nil,\n\t\t},\n\t}\n\tresult := executeEnumTypeTest(t, query)\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestTypeSystem_EnumValues_EnumValueMayBePointer(t *testing.T) {\n\tvar enumTypeTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"query\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewObject(graphql.ObjectConfig{\n\t\t\t\t\t\tName: \"query\",\n\t\t\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\t\t\"color\": &graphql.Field{\n\t\t\t\t\t\t\t\tType: enumTypeTestColorType,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"foo\": &graphql.Field{\n\t\t\t\t\t\t\t\tDescription: \"foo field\",\n\t\t\t\t\t\t\t\tType:        graphql.Int,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t\tResolve: func(_ graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\tone := 1\n\t\t\t\t\t\treturn struct {\n\t\t\t\t\t\t\tColor *int `graphql:\"color\"`\n\t\t\t\t\t\t\tFoo   *int `graphql:\"foo\"`\n\t\t\t\t\t\t}{&one, &one}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tquery := \"{ query { color foo } }\"\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"query\": map[string]interface{}{\n\t\t\t\t\"color\": \"GREEN\",\n\t\t\t\t\"foo\":   1}}}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        enumTypeTestSchema,\n\t\tRequestString: query,\n\t})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestTypeSystem_EnumValues_EnumValueMayBeNilPointer(t *testing.T) {\n\tvar enumTypeTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"query\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewObject(graphql.ObjectConfig{\n\t\t\t\t\t\tName: \"query\",\n\t\t\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\t\t\"color\": &graphql.Field{\n\t\t\t\t\t\t\t\tType: enumTypeTestColorType,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t\tResolve: func(_ graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn struct {\n\t\t\t\t\t\t\tColor *int `graphql:\"color\"`\n\t\t\t\t\t\t}{nil}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tquery := \"{ query { color } }\"\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"query\": map[string]interface{}{\n\t\t\t\t\"color\": nil,\n\t\t\t}},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        enumTypeTestSchema,\n\t\tRequestString: query,\n\t})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "examples/concurrent-resolvers/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\ntype Foo struct {\n\tName string\n}\n\nvar FieldFooType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Foo\",\n\tFields: graphql.Fields{\n\t\t\"name\": &graphql.Field{Type: graphql.String},\n\t},\n})\n\ntype Bar struct {\n\tName string\n}\n\nvar FieldBarType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Bar\",\n\tFields: graphql.Fields{\n\t\t\"name\": &graphql.Field{Type: graphql.String},\n\t},\n})\n\n// QueryType fields: `concurrentFieldFoo` and `concurrentFieldBar` are resolved\n// concurrently because they belong to the same field-level and their `Resolve`\n// function returns a function (thunk).\nvar QueryType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Query\",\n\tFields: graphql.Fields{\n\t\t\"concurrentFieldFoo\": &graphql.Field{\n\t\t\tType: FieldFooType,\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\tvar foo = Foo{Name: \"Foo's name\"}\n\t\t\t\treturn func() (interface{}, error) {\n\t\t\t\t\treturn &foo, nil\n\t\t\t\t}, nil\n\t\t\t},\n\t\t},\n\t\t\"concurrentFieldBar\": &graphql.Field{\n\t\t\tType: FieldBarType,\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\ttype result struct {\n\t\t\t\t\tdata interface{}\n\t\t\t\t\terr  error\n\t\t\t\t}\n\t\t\t\tch := make(chan *result, 1)\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer close(ch)\n\t\t\t\t\tbar := &Bar{Name: \"Bar's name\"}\n\t\t\t\t\tch <- &result{data: bar, err: nil}\n\t\t\t\t}()\n\t\t\t\treturn func() (interface{}, error) {\n\t\t\t\t\tr := <-ch\n\t\t\t\t\treturn r.data, r.err\n\t\t\t\t}, nil\n\t\t\t},\n\t\t},\n\t},\n})\n\nfunc main() {\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: QueryType,\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tquery := `\n\t\tquery {\n\t\t\tconcurrentFieldFoo {\n\t\t\t\tname\n\t\t\t}\n\t\t\tconcurrentFieldBar {\n\t\t\t\tname\n\t\t\t}\n\t\t}\n\t`\n\tresult := graphql.Do(graphql.Params{\n\t\tRequestString: query,\n\t\tSchema:        schema,\n\t})\n\tb, err := json.Marshal(result)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Printf(\"%s\", b)\n\t/*\n\t\t{\n\t\t  \"data\": {\n\t\t    \"concurrentFieldBar\": {\n\t\t      \"name\": \"Bar's name\"\n\t\t    },\n\t\t    \"concurrentFieldFoo\": {\n\t\t      \"name\": \"Foo's name\"\n\t\t    }\n\t\t  }\n\t\t}\n\t*/\n}\n"
  },
  {
    "path": "examples/context/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\nvar Schema graphql.Schema\n\nvar userType = graphql.NewObject(\n\tgraphql.ObjectConfig{\n\t\tName: \"User\",\n\t\tFields: graphql.Fields{\n\t\t\t\"id\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t},\n)\n\nvar queryType = graphql.NewObject(\n\tgraphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"me\": &graphql.Field{\n\t\t\t\tType: userType,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn p.Context.Value(\"currentUser\"), nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\nfunc graphqlHandler(w http.ResponseWriter, r *http.Request) {\n\tuser := struct {\n\t\tID   int    `json:\"id\"`\n\t\tName string `json:\"name\"`\n\t}{1, \"cool user\"}\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        Schema,\n\t\tRequestString: r.URL.Query().Get(\"query\"),\n\t\tContext:       context.WithValue(context.Background(), \"currentUser\", user),\n\t})\n\tif len(result.Errors) > 0 {\n\t\tlog.Printf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t\treturn\n\t}\n\tjson.NewEncoder(w).Encode(result)\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/graphql\", graphqlHandler)\n\tfmt.Println(\"Now server is running on port 8080\")\n\tfmt.Println(\"Test with Get      : curl -g 'http://localhost:8080/graphql?query={me{id,name}}'\")\n\thttp.ListenAndServe(\":8080\", nil)\n}\n\nfunc init() {\n\ts, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create schema, error: %v\", err)\n\t}\n\tSchema = s\n}\n"
  },
  {
    "path": "examples/crud/Readme.md",
    "content": "# Go GraphQL CRUD example\n\nImplement create, read, update and delete on Go.\n\nTo run the program:\n\n1. go to the directory: `cd examples/crud`\n2. Run the example: `go run main.go`\n\n## Create\n\n`http://localhost:8080/product?query=mutation+_{create(name:\"Inca Kola\",info:\"Inca Kola is a soft drink that was created in Peru in 1935 by British immigrant Joseph Robinson Lindley using lemon verbena (wiki)\",price:1.99){id,name,info,price}}`\n\n## Read\n\n* Get single product by id: `http://localhost:8080/product?query={product(id:1){name,info,price}}`\n* Get product list: `http://localhost:8080/product?query={list{id,name,info,price}}`\n\n## Update\n\n`http://localhost:8080/product?query=mutation+_{update(id:1,price:3.95){id,name,info,price}}`\n\n## Delete\n\n`http://localhost:8080/product?query=mutation+_{delete(id:1){id,name,info,price}}`\n"
  },
  {
    "path": "examples/crud/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\n// Product contains information about one product\ntype Product struct {\n\tID    int64   `json:\"id\"`\n\tName  string  `json:\"name\"`\n\tInfo  string  `json:\"info,omitempty\"`\n\tPrice float64 `json:\"price\"`\n}\n\nvar products = []Product{\n\t{\n\t\tID:    1,\n\t\tName:  \"Chicha Morada\",\n\t\tInfo:  \"Chicha morada is a beverage originated in the Andean regions of Perú but is actually consumed at a national level (wiki)\",\n\t\tPrice: 7.99,\n\t},\n\t{\n\t\tID:    2,\n\t\tName:  \"Chicha de jora\",\n\t\tInfo:  \"Chicha de jora is a corn beer chicha prepared by germinating maize, extracting the malt sugars, boiling the wort, and fermenting it in large vessels (traditionally huge earthenware vats) for several days (wiki)\",\n\t\tPrice: 5.95,\n\t},\n\t{\n\t\tID:    3,\n\t\tName:  \"Pisco\",\n\t\tInfo:  \"Pisco is a colorless or yellowish-to-amber colored brandy produced in winemaking regions of Peru and Chile (wiki)\",\n\t\tPrice: 9.95,\n\t},\n}\n\nvar productType = graphql.NewObject(\n\tgraphql.ObjectConfig{\n\t\tName: \"Product\",\n\t\tFields: graphql.Fields{\n\t\t\t\"id\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"info\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"price\": &graphql.Field{\n\t\t\t\tType: graphql.Float,\n\t\t\t},\n\t\t},\n\t},\n)\n\nvar queryType = graphql.NewObject(\n\tgraphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t/* Get (read) single product by id\n\t\t\t   http://localhost:8080/product?query={product(id:1){name,info,price}}\n\t\t\t*/\n\t\t\t\"product\": &graphql.Field{\n\t\t\t\tType:        productType,\n\t\t\t\tDescription: \"Get product by id\",\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tid, ok := p.Args[\"id\"].(int)\n\t\t\t\t\tif ok {\n\t\t\t\t\t\t// Find product\n\t\t\t\t\t\tfor _, product := range products {\n\t\t\t\t\t\t\tif int(product.ID) == id {\n\t\t\t\t\t\t\t\treturn product, nil\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t/* Get (read) product list\n\t\t\t   http://localhost:8080/product?query={list{id,name,info,price}}\n\t\t\t*/\n\t\t\t\"list\": &graphql.Field{\n\t\t\t\tType:        graphql.NewList(productType),\n\t\t\t\tDescription: \"Get product list\",\n\t\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn products, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\nvar mutationType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Mutation\",\n\tFields: graphql.Fields{\n\t\t/* Create new product item\n\t\thttp://localhost:8080/product?query=mutation+_{create(name:\"Inca Kola\",info:\"Inca Kola is a soft drink that was created in Peru in 1935 by British immigrant Joseph Robinson Lindley using lemon verbena (wiki)\",price:1.99){id,name,info,price}}\n\t\t*/\n\t\t\"create\": &graphql.Field{\n\t\t\tType:        productType,\n\t\t\tDescription: \"Create new product\",\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"name\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t\t},\n\t\t\t\t\"info\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"price\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.Float),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\trand.Seed(time.Now().UnixNano())\n\t\t\t\tproduct := Product{\n\t\t\t\t\tID:    int64(rand.Intn(100000)), // generate random ID\n\t\t\t\t\tName:  params.Args[\"name\"].(string),\n\t\t\t\t\tInfo:  params.Args[\"info\"].(string),\n\t\t\t\t\tPrice: params.Args[\"price\"].(float64),\n\t\t\t\t}\n\t\t\t\tproducts = append(products, product)\n\t\t\t\treturn product, nil\n\t\t\t},\n\t\t},\n\n\t\t/* Update product by id\n\t\t   http://localhost:8080/product?query=mutation+_{update(id:1,price:3.95){id,name,info,price}}\n\t\t*/\n\t\t\"update\": &graphql.Field{\n\t\t\tType:        productType,\n\t\t\tDescription: \"Update product by id\",\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.Int),\n\t\t\t\t},\n\t\t\t\t\"name\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"info\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"price\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.Float,\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\tid, _ := params.Args[\"id\"].(int)\n\t\t\t\tname, nameOk := params.Args[\"name\"].(string)\n\t\t\t\tinfo, infoOk := params.Args[\"info\"].(string)\n\t\t\t\tprice, priceOk := params.Args[\"price\"].(float64)\n\t\t\t\tproduct := Product{}\n\t\t\t\tfor i, p := range products {\n\t\t\t\t\tif int64(id) == p.ID {\n\t\t\t\t\t\tif nameOk {\n\t\t\t\t\t\t\tproducts[i].Name = name\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif infoOk {\n\t\t\t\t\t\t\tproducts[i].Info = info\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif priceOk {\n\t\t\t\t\t\t\tproducts[i].Price = price\n\t\t\t\t\t\t}\n\t\t\t\t\t\tproduct = products[i]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn product, nil\n\t\t\t},\n\t\t},\n\n\t\t/* Delete product by id\n\t\t   http://localhost:8080/product?query=mutation+_{delete(id:1){id,name,info,price}}\n\t\t*/\n\t\t\"delete\": &graphql.Field{\n\t\t\tType:        productType,\n\t\t\tDescription: \"Delete product by id\",\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.Int),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\tid, _ := params.Args[\"id\"].(int)\n\t\t\t\tproduct := Product{}\n\t\t\t\tfor i, p := range products {\n\t\t\t\t\tif int64(id) == p.ID {\n\t\t\t\t\t\tproduct = products[i]\n\t\t\t\t\t\t// Remove from product list\n\t\t\t\t\t\tproducts = append(products[:i], products[i+1:]...)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn product, nil\n\t\t\t},\n\t\t},\n\t},\n})\n\nvar schema, _ = graphql.NewSchema(\n\tgraphql.SchemaConfig{\n\t\tQuery:    queryType,\n\t\tMutation: mutationType,\n\t},\n)\n\nfunc executeQuery(query string, schema graphql.Schema) *graphql.Result {\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) > 0 {\n\t\tfmt.Printf(\"errors: %v\", result.Errors)\n\t}\n\treturn result\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/product\", func(w http.ResponseWriter, r *http.Request) {\n\t\tresult := executeQuery(r.URL.Query().Get(\"query\"), schema)\n\t\tjson.NewEncoder(w).Encode(result)\n\t})\n\n\tfmt.Println(\"Server is running on port 8080\")\n\thttp.ListenAndServe(\":8080\", nil)\n}\n"
  },
  {
    "path": "examples/custom-scalar-type/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\ntype CustomID struct {\n\tvalue string\n}\n\nfunc (id *CustomID) String() string {\n\treturn id.value\n}\n\nfunc NewCustomID(v string) *CustomID {\n\treturn &CustomID{value: v}\n}\n\nvar CustomScalarType = graphql.NewScalar(graphql.ScalarConfig{\n\tName:        \"CustomScalarType\",\n\tDescription: \"The `CustomScalarType` scalar type represents an ID Object.\",\n\t// Serialize serializes `CustomID` to string.\n\tSerialize: func(value interface{}) interface{} {\n\t\tswitch value := value.(type) {\n\t\tcase CustomID:\n\t\t\treturn value.String()\n\t\tcase *CustomID:\n\t\t\tv := *value\n\t\t\treturn v.String()\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t},\n\t// ParseValue parses GraphQL variables from `string` to `CustomID`.\n\tParseValue: func(value interface{}) interface{} {\n\t\tswitch value := value.(type) {\n\t\tcase string:\n\t\t\treturn NewCustomID(value)\n\t\tcase *string:\n\t\t\treturn NewCustomID(*value)\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t},\n\t// ParseLiteral parses GraphQL AST value to `CustomID`.\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\tswitch valueAST := valueAST.(type) {\n\t\tcase *ast.StringValue:\n\t\t\treturn NewCustomID(valueAST.Value)\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t},\n})\n\ntype Customer struct {\n\tID *CustomID `json:\"id\"`\n}\n\nvar CustomerType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Customer\",\n\tFields: graphql.Fields{\n\t\t\"id\": &graphql.Field{\n\t\t\tType: CustomScalarType,\n\t\t},\n\t},\n})\n\nfunc main() {\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"customers\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(CustomerType),\n\t\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: CustomScalarType,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\t// id := p.Args[\"id\"]\n\t\t\t\t\t\t// log.Printf(\"id from arguments: %+v\", id)\n\t\t\t\t\t\tcustomers := []Customer{\n\t\t\t\t\t\t\tCustomer{ID: NewCustomID(\"fb278f2a4a13f\")},\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn customers, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tquery := `\n\t\tquery {\n\t\t\tcustomers {\n\t\t\t\tid\n\t\t\t}\n\t\t}\n\t`\n\t/*\n\t\tqueryWithVariable := `\n\t\t\tquery($id: CustomScalarType) {\n\t\t\t\tcustomers(id: $id) {\n\t\t\t\t\tid\n\t\t\t\t}\n\t\t\t}\n\t\t`\n\t*/\n\t/*\n\t\tqueryWithArgument := `\n\t\t\tquery {\n\t\t\t\tcustomers(id: \"5b42ba57289\") {\n\t\t\t\t\tid\n\t\t\t\t}\n\t\t\t}\n\t\t`\n\t*/\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t\tVariableValues: map[string]interface{}{\n\t\t\t\"id\": \"5b42ba57289\",\n\t\t},\n\t})\n\tif len(result.Errors) > 0 {\n\t\tlog.Fatal(result)\n\t}\n\tb, err := json.Marshal(result)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(string(b))\n}\n"
  },
  {
    "path": "examples/hello-world/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\nfunc main() {\n\t// Schema\n\tfields := graphql.Fields{\n\t\t\"hello\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\treturn \"world\", nil\n\t\t\t},\n\t\t},\n\t}\n\trootQuery := graphql.ObjectConfig{Name: \"RootQuery\", Fields: fields}\n\tschemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}\n\tschema, err := graphql.NewSchema(schemaConfig)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create new schema, error: %v\", err)\n\t}\n\n\t// Query\n\tquery := `\n\t\t{\n\t\t\thello\n\t\t}\n\t`\n\tparams := graphql.Params{Schema: schema, RequestString: query}\n\tr := graphql.Do(params)\n\tif len(r.Errors) > 0 {\n\t\tlog.Fatalf(\"failed to execute graphql operation, errors: %+v\", r.Errors)\n\t}\n\trJSON, _ := json.Marshal(r)\n\tfmt.Printf(\"%s \\n\", rJSON) // {“data”:{“hello”:”world”}}\n}\n"
  },
  {
    "path": "examples/http/data.json",
    "content": "{\n  \"1\": {\n    \"id\": \"1\",\n    \"name\": \"Dan\"\n  },\n  \"2\": {\n    \"id\": \"2\",\n    \"name\": \"Lee\"\n  },\n  \"3\": {\n    \"id\": \"3\",\n    \"name\": \"Nick\"\n  }\n}"
  },
  {
    "path": "examples/http/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\ntype user struct {\n\tID   string `json:\"id\"`\n\tName string `json:\"name\"`\n}\n\nvar data map[string]user\n\n/*\n   Create User object type with fields \"id\" and \"name\" by using GraphQLObjectTypeConfig:\n       - Name: name of object type\n       - Fields: a map of fields by using GraphQLFields\n   Setup type of field use GraphQLFieldConfig\n*/\nvar userType = graphql.NewObject(\n\tgraphql.ObjectConfig{\n\t\tName: \"User\",\n\t\tFields: graphql.Fields{\n\t\t\t\"id\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t},\n)\n\n/*\n   Create Query object type with fields \"user\" has type [userType] by using GraphQLObjectTypeConfig:\n       - Name: name of object type\n       - Fields: a map of fields by using GraphQLFields\n   Setup type of field use GraphQLFieldConfig to define:\n       - Type: type of field\n       - Args: arguments to query with current field\n       - Resolve: function to query data using params from [Args] and return value with current type\n*/\nvar queryType = graphql.NewObject(\n\tgraphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"user\": &graphql.Field{\n\t\t\t\tType: userType,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tidQuery, isOK := p.Args[\"id\"].(string)\n\t\t\t\t\tif isOK {\n\t\t\t\t\t\treturn data[idQuery], nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\nvar schema, _ = graphql.NewSchema(\n\tgraphql.SchemaConfig{\n\t\tQuery: queryType,\n\t},\n)\n\nfunc executeQuery(query string, schema graphql.Schema) *graphql.Result {\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) > 0 {\n\t\tfmt.Printf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\treturn result\n}\n\nfunc main() {\n\t_ = importJSONDataFromFile(\"data.json\", &data)\n\n\thttp.HandleFunc(\"/graphql\", func(w http.ResponseWriter, r *http.Request) {\n\t\tresult := executeQuery(r.URL.Query().Get(\"query\"), schema)\n\t\tjson.NewEncoder(w).Encode(result)\n\t})\n\n\tfmt.Println(\"Now server is running on port 8080\")\n\tfmt.Println(\"Test with Get      : curl -g 'http://localhost:8080/graphql?query={user(id:\\\"1\\\"){name}}'\")\n\thttp.ListenAndServe(\":8080\", nil)\n}\n\n//Helper function to import json from file to map\nfunc importJSONDataFromFile(fileName string, result interface{}) (isOK bool) {\n\tisOK = true\n\tcontent, err := ioutil.ReadFile(fileName)\n\tif err != nil {\n\t\tfmt.Print(\"Error:\", err)\n\t\tisOK = false\n\t}\n\terr = json.Unmarshal(content, result)\n\tif err != nil {\n\t\tisOK = false\n\t\tfmt.Print(\"Error:\", err)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "examples/http-post/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/examples/todo/schema\"\n)\n\ntype postData struct {\n\tQuery     string                 `json:\"query\"`\n\tOperation string                 `json:\"operationName\"`\n\tVariables map[string]interface{} `json:\"variables\"`\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/graphql\", func(w http.ResponseWriter, req *http.Request) {\n\t\tvar p postData\n\t\tif err := json.NewDecoder(req.Body).Decode(&p); err != nil {\n\t\t\tw.WriteHeader(400)\n\t\t\treturn\n\t\t}\n\t\tresult := graphql.Do(graphql.Params{\n\t\t\tContext:        req.Context(),\n\t\t\tSchema:         schema.TodoSchema,\n\t\t\tRequestString:  p.Query,\n\t\t\tVariableValues: p.Variables,\n\t\t\tOperationName:  p.Operation,\n\t\t})\n\t\tif err := json.NewEncoder(w).Encode(result); err != nil {\n\t\t\tfmt.Printf(\"could not write result to response: %s\", err)\n\t\t}\n\t})\n\n\tfmt.Println(\"Now server is running on port 8080\")\n\n\tfmt.Println(\"\")\n\n\tfmt.Println(`Get single todo:\ncurl \\\n-X POST \\\n-H \"Content-Type: application/json\" \\\n--data '{ \"query\": \"{ todo(id:\\\"b\\\") { id text done } }\" }' \\\nhttp://localhost:8080/graphql`)\n\n\tfmt.Println(\"\")\n\n\tfmt.Println(`Create new todo:\ncurl \\\n-X POST \\\n-H \"Content-Type: application/json\" \\\n--data '{ \"query\": \"mutation { createTodo(text:\\\"My New todo\\\") { id text done } }\" }' \\\nhttp://localhost:8080/graphql`)\n\n\tfmt.Println(\"\")\n\n\tfmt.Println(`Update todo:\ncurl \\\n-X POST \\\n-H \"Content-Type: application/json\" \\\n--data '{ \"query\": \"mutation { updateTodo(id:\\\"a\\\", done: true) { id text done } }\" }' \\\nhttp://localhost:8080/graphql`)\n\n\tfmt.Println(\"\")\n\n\tfmt.Println(`Load todo list:\ncurl \\\n-X POST \\\n-H \"Content-Type: application/json\" \\\n--data '{ \"query\": \"{ todoList { id text done } }\" }' \\\nhttp://localhost:8080/graphql`)\n\n\thttp.ListenAndServe(\":8080\", nil)\n}\n"
  },
  {
    "path": "examples/httpdynamic/README.md",
    "content": "Basically, if we have `data.json` like this:\n\n    [\n      { \"id\": \"1\", \"name\": \"Dan\" },\n      { \"id\": \"2\", \"name\": \"Lee\" },\n      { \"id\": \"3\", \"name\": \"Nick\" }\n    ]\n\n... and `go run main.go`, we can query records:\n\n\t$ curl -g 'http://localhost:8080/graphql?query={user(name:\"Dan\"){id}}'\n\t{\"data\":{\"user\":{\"id\":\"1\"}}}\n\n... now let's give Dan a surname:\n\n    [\n      { \"id\": \"1\", \"name\": \"Dan\", \"surname\": \"Jones\" },\n      { \"id\": \"2\", \"name\": \"Lee\" },\n      { \"id\": \"3\", \"name\": \"Nick\" }\n    ]\n\n... and kick the server:\n\n    kill -SIGUSR1 52114\n\nAnd ask for Dan's surname:\n\n\t$ curl -g 'http://localhost:8080/graphql?query={user(name:\"Dan\"){id,surname}}'\n\t{\"data\":{\"user\":{\"id\":\"1\",\"surname\":\"Jones\"}}}\n\n... or ask Jones's name and ID:\n\n    $ curl -g 'http://localhost:8080/graphql?query={user(surname:\"Jones\"){id,name}}'\n    {\"data\":{\"user\":{\"id\":\"1\",\"name\":\"Dan\"}}}\n\nIf you look at `main.go`, the file is not field-aware. That is, all it knows is\nhow to work with `[]map[string]string` type.\n\nWith this, we are not that far from exposing dynamic fields and filters which\nfully depend on what we have stored, all without changing our tooling.\n"
  },
  {
    "path": "examples/httpdynamic/data.json",
    "content": "[\n  {\n    \"id\": \"1\",\n    \"name\": \"Dan\",\n    \"surname\": \"Jones\"\n  },\n  {\n    \"id\": \"2\",\n    \"name\": \"Lee\"\n  },\n  {\n    \"id\": \"3\",\n    \"name\": \"Nick\"\n  }\n]\n"
  },
  {
    "path": "examples/httpdynamic/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"strconv\"\n\t\"syscall\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\n/*****************************************************************************/\n/* Shared data variables to allow dynamic reloads\n/*****************************************************************************/\n\nvar schema graphql.Schema\n\nconst jsonDataFile = \"data.json\"\n\nfunc handleSIGUSR1(c chan os.Signal) {\n\tfor {\n\t\t<-c\n\t\tfmt.Printf(\"Caught SIGUSR1. Reloading %s\\n\", jsonDataFile)\n\t\terr := importJSONDataFromFile(jsonDataFile)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error: %s\\n\", err.Error())\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc filterUser(data []map[string]interface{}, args map[string]interface{}) map[string]interface{} {\n\tfor _, user := range data {\n\t\tfor k, v := range args {\n\t\t\tif user[k] != v {\n\t\t\t\tgoto nextuser\n\t\t\t}\n\t\t\treturn user\n\t\t}\n\n\tnextuser:\n\t}\n\treturn nil\n}\n\nfunc executeQuery(query string, schema graphql.Schema) *graphql.Result {\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) > 0 {\n\t\tfmt.Printf(\"wrong result, unexpected errors: %v\\n\", result.Errors)\n\t}\n\treturn result\n}\n\nfunc importJSONDataFromFile(fileName string) error {\n\tcontent, err := ioutil.ReadFile(fileName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar data []map[string]interface{}\n\n\terr = json.Unmarshal(content, &data)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfields := make(graphql.Fields)\n\targs := make(graphql.FieldConfigArgument)\n\tfor _, item := range data {\n\t\tfor k := range item {\n\t\t\tfields[k] = &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t}\n\t\t\targs[k] = &graphql.ArgumentConfig{\n\t\t\t\tType: graphql.String,\n\t\t\t}\n\t\t}\n\t}\n\n\tvar userType = graphql.NewObject(\n\t\tgraphql.ObjectConfig{\n\t\t\tName:   \"User\",\n\t\t\tFields: fields,\n\t\t},\n\t)\n\n\tvar queryType = graphql.NewObject(\n\t\tgraphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"user\": &graphql.Field{\n\t\t\t\t\tType: userType,\n\t\t\t\t\tArgs: args,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn filterUser(data, p.Args), nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\n\tschema, _ = graphql.NewSchema(\n\t\tgraphql.SchemaConfig{\n\t\t\tQuery: queryType,\n\t\t},\n\t)\n\n\treturn nil\n}\n\nfunc main() {\n\t// Catch SIGUSR1 and reload the data file\n\tc := make(chan os.Signal, 1)\n\tsignal.Notify(c, syscall.SIGUSR1)\n\tgo handleSIGUSR1(c)\n\n\terr := importJSONDataFromFile(jsonDataFile)\n\tif err != nil {\n\t\tfmt.Printf(\"Error: %s\\n\", err.Error())\n\t\treturn\n\t}\n\n\thttp.HandleFunc(\"/graphql\", func(w http.ResponseWriter, r *http.Request) {\n\t\tresult := executeQuery(r.URL.Query().Get(\"query\"), schema)\n\t\tjson.NewEncoder(w).Encode(result)\n\t})\n\n\tfmt.Println(\"Now server is running on port 8080\")\n\tfmt.Println(\"Test with Get      : curl -g 'http://localhost:8080/graphql?query={user(name:\\\"Dan\\\"){id,surname}}'\")\n\tfmt.Printf(\"Reload json file   : kill -SIGUSR1 %s\\n\", strconv.Itoa(os.Getpid()))\n\thttp.ListenAndServe(\":8080\", nil)\n}\n"
  },
  {
    "path": "examples/modify-context/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\ntype User struct {\n\tID int `json:\"id\"`\n}\n\nvar UserType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"User\",\n\tFields: graphql.Fields{\n\t\t\"id\": &graphql.Field{\n\t\t\tType: graphql.Int,\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\trootValue := p.Info.RootValue.(map[string]interface{})\n\t\t\t\tif rootValue[\"data-from-parent\"] == \"ok\" &&\n\t\t\t\t\trootValue[\"data-before-execution\"] == \"ok\" {\n\t\t\t\t\tuser := p.Source.(User)\n\t\t\t\t\treturn user.ID, nil\n\t\t\t\t}\n\t\t\t\treturn nil, nil\n\t\t\t},\n\t\t},\n\t},\n})\n\nfunc main() {\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"users\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(UserType),\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\trootValue := p.Info.RootValue.(map[string]interface{})\n\t\t\t\t\t\trootValue[\"data-from-parent\"] = \"ok\"\n\t\t\t\t\t\tresult := []User{\n\t\t\t\t\t\t\tUser{ID: 1},\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn result, nil\n\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tctx := context.WithValue(context.Background(), \"currentUser\", User{ID: 100})\n\t// Instead of trying to modify context within a resolve function, use:\n\t// `graphql.Params.RootObject` is a mutable optional variable and available on\n\t// each resolve function via: `graphql.ResolveParams.Info.RootValue`.\n\trootObject := map[string]interface{}{\n\t\t\"data-before-execution\": \"ok\",\n\t}\n\tresult := graphql.Do(graphql.Params{\n\t\tContext:       ctx,\n\t\tRequestString: \"{ users { id } }\",\n\t\tRootObject:    rootObject,\n\t\tSchema:        schema,\n\t})\n\tb, err := json.Marshal(result)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Printf(\"%s\\n\", string(b)) // {\"data\":{\"users\":[{\"id\":1}]}}\n}\n"
  },
  {
    "path": "examples/sql-nullstring/README.md",
    "content": "# Go GraphQL SQL null string example\r\n\r\n<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://golang.org/pkg/database/sql/#NullString\">database/sql Nullstring</a> implementation, with JSON marshalling interfaces.\r\n\r\nTo run the program, go to the directory  \r\n`cd examples/sql-nullstring`\r\n\r\nRun the example  \r\n`go run main.go`\r\n\r\n## sql.NullString\r\n\r\nOn occasion you will encounter sql fields that are nullable, as in\r\n\r\n```sql\r\nCREATE TABLE persons (\r\n    id INT PRIMARY KEY,\r\n    name TEXT NOT NULL,\r\n    favorite_dog TEXT -- this field can have a NULL value\r\n)\r\n```\r\n\r\nFor the struct\r\n\r\n```golang\r\nimport \"database/sql\"\r\n\r\ntype Person struct {\r\n    ID          int             `json:\"id\" sql:\"id\"`\r\n    Name        string          `json:\"name\" sql:\"name\"`\r\n    FavoriteDog sql.NullString  `json:\"favorite_dog\" sql:\"favorite_dog\"`\r\n}\r\n```\r\n\r\nBut `graphql` would render said field as an object `{{ false}}` or `{{Bulldog true}}`, depending on their validity.\r\n\r\nWith this implementation, `graphql` would render the null items as an empty string (`\"\"`), but would be saved in the database as `NULL`, appropriately.\r\n\r\nThe pattern can be extended to include other `database/sql` null types.\r\n"
  },
  {
    "path": "examples/sql-nullstring/main.go",
    "content": "package main\r\n\r\nimport (\r\n\t\"database/sql\"\r\n\t\"encoding/json\"\r\n\t\"fmt\"\r\n\t\"github.com/graphql-go/graphql\"\r\n\t\"github.com/graphql-go/graphql/language/ast\"\r\n\t\"log\"\r\n)\r\n\r\n// NullString to be used in place of sql.NullString\r\ntype NullString struct {\r\n\tsql.NullString\r\n}\r\n\r\n// MarshalJSON from the json.Marshaler interface\r\nfunc (v NullString) MarshalJSON() ([]byte, error) {\r\n\tif v.Valid {\r\n\t\treturn json.Marshal(v.String)\r\n\t}\r\n\treturn json.Marshal(nil)\r\n}\r\n\r\n// UnmarshalJSON from the json.Unmarshaler interface\r\nfunc (v *NullString) UnmarshalJSON(data []byte) error {\r\n\tvar x *string\r\n\tif err := json.Unmarshal(data, &x); err != nil {\r\n\t\treturn err\r\n\t}\r\n\tif x != nil {\r\n\t\tv.String = *x\r\n\t\tv.Valid = true\r\n\t} else {\r\n\t\tv.Valid = false\r\n\t}\r\n\treturn nil\r\n}\r\n\r\n// NewNullString create a new null string. Empty string evaluates to an\r\n// \"invalid\" NullString\r\nfunc NewNullString(value string) *NullString {\r\n\tvar null NullString\r\n\tif value != \"\" {\r\n\t\tnull.String = value\r\n\t\tnull.Valid = true\r\n\t\treturn &null\r\n\t}\r\n\tnull.Valid = false\r\n\treturn &null\r\n}\r\n\r\n// SerializeNullString serializes `NullString` to a string\r\nfunc SerializeNullString(value interface{}) interface{} {\r\n\tswitch value := value.(type) {\r\n\tcase NullString:\r\n\t\treturn value.String\r\n\tcase *NullString:\r\n\t\tv := *value\r\n\t\treturn v.String\r\n\tdefault:\r\n\t\treturn nil\r\n\t}\r\n}\r\n\r\n// ParseNullString parses GraphQL variables from `string` to `CustomID`\r\nfunc ParseNullString(value interface{}) interface{} {\r\n\tswitch value := value.(type) {\r\n\tcase string:\r\n\t\treturn NewNullString(value)\r\n\tcase *string:\r\n\t\treturn NewNullString(*value)\r\n\tdefault:\r\n\t\treturn nil\r\n\t}\r\n}\r\n\r\n// ParseLiteralNullString parses GraphQL AST value to `NullString`.\r\nfunc ParseLiteralNullString(valueAST ast.Value) interface{} {\r\n\tswitch valueAST := valueAST.(type) {\r\n\tcase *ast.StringValue:\r\n\t\treturn NewNullString(valueAST.Value)\r\n\tdefault:\r\n\t\treturn nil\r\n\t}\r\n}\r\n\r\n// NullableString graphql *Scalar type based of NullString\r\nvar NullableString = graphql.NewScalar(graphql.ScalarConfig{\r\n\tName:         \"NullableString\",\r\n\tDescription:  \"The `NullableString` type repesents a nullable SQL string.\",\r\n\tSerialize:    SerializeNullString,\r\n\tParseValue:   ParseNullString,\r\n\tParseLiteral: ParseLiteralNullString,\r\n})\r\n\r\n/*\r\nCREATE TABLE persons (\r\n\tfavorite_dog TEXT -- is a nullable field\r\n\t);\r\n\r\n*/\r\n\r\n// Person noqa\r\ntype Person struct {\r\n\tName        string      `json:\"name\"`\r\n\tFavoriteDog *NullString `json:\"favorite_dog\"` // Some people don't like dogs ¯\\_(ツ)_/¯\r\n}\r\n\r\n// PersonType noqa\r\nvar PersonType = graphql.NewObject(graphql.ObjectConfig{\r\n\tName: \"Person\",\r\n\tFields: graphql.Fields{\r\n\t\t\"name\": &graphql.Field{\r\n\t\t\tType: graphql.String,\r\n\t\t},\r\n\t\t\"favorite_dog\": &graphql.Field{\r\n\t\t\tType: NullableString,\r\n\t\t},\r\n\t},\r\n})\r\n\r\nfunc main() {\r\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\r\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\r\n\t\t\tName: \"Query\",\r\n\t\t\tFields: graphql.Fields{\r\n\t\t\t\t\"people\": &graphql.Field{\r\n\t\t\t\t\tType: graphql.NewList(PersonType),\r\n\t\t\t\t\tArgs: graphql.FieldConfigArgument{\r\n\t\t\t\t\t\t\"favorite_dog\": &graphql.ArgumentConfig{\r\n\t\t\t\t\t\t\tType: NullableString,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t},\r\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\r\n\t\t\t\t\t\tdog, dogOk := p.Args[\"favorite_dog\"].(*NullString)\r\n\t\t\t\t\t\tpeople := []Person{\r\n\t\t\t\t\t\t\tPerson{Name: \"Alice\", FavoriteDog: NewNullString(\"Yorkshire Terrier\")},\r\n\t\t\t\t\t\t\t// `Bob`'s favorite dog will be saved as null in the database\r\n\t\t\t\t\t\t\tPerson{Name: \"Bob\", FavoriteDog: NewNullString(\"\")},\r\n\t\t\t\t\t\t\tPerson{Name: \"Chris\", FavoriteDog: NewNullString(\"French Bulldog\")},\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tswitch {\r\n\t\t\t\t\t\tcase dogOk:\r\n\t\t\t\t\t\t\tlog.Printf(\"favorite_dog from arguments: %+v\", dog)\r\n\t\t\t\t\t\t\tdogPeople := make([]Person, 0)\r\n\t\t\t\t\t\t\tfor _, p := range people {\r\n\t\t\t\t\t\t\t\tif p.FavoriteDog.Valid {\r\n\t\t\t\t\t\t\t\t\tif p.FavoriteDog.String == dog.String {\r\n\t\t\t\t\t\t\t\t\t\tdogPeople = append(dogPeople, p)\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\treturn dogPeople, nil\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\treturn people, nil\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t},\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t}),\r\n\t})\r\n\tif err != nil {\r\n\t\tlog.Fatal(err)\r\n\t}\r\n\tquery := `\r\nquery {\r\n  people {\r\n    name\r\n    favorite_dog\r\n    }\r\n}`\r\n\tqueryWithArgument := `\r\nquery {\r\n  people(favorite_dog: \"Yorkshire Terrier\") {\r\n    name\r\n    favorite_dog\r\n  }\r\n}`\r\n\tr1 := graphql.Do(graphql.Params{\r\n\t\tSchema:        schema,\r\n\t\tRequestString: query,\r\n\t})\r\n\tr2 := graphql.Do(graphql.Params{\r\n\t\tSchema:        schema,\r\n\t\tRequestString: queryWithArgument,\r\n\t})\r\n\tif len(r1.Errors) > 0 {\r\n\t\tlog.Fatal(r1)\r\n\t}\r\n\tif len(r2.Errors) > 0 {\r\n\t\tlog.Fatal(r1)\r\n\t}\r\n\tb1, err := json.MarshalIndent(r1, \"\", \"  \")\r\n\tif err != nil {\r\n\t\tlog.Fatal(err)\r\n\t}\r\n\tb2, err := json.MarshalIndent(r2, \"\", \"  \")\r\n\tif err != nil {\r\n\t\tlog.Fatal(err)\r\n\r\n\t}\r\n\tfmt.Printf(\"\\nQuery: %+v\\n\", string(query))\r\n\tfmt.Printf(\"\\nResult: %+v\\n\", string(b1))\r\n\tfmt.Printf(\"\\nQuery (with arguments): %+v\\n\", string(queryWithArgument))\r\n\tfmt.Printf(\"\\nResult (with arguments): %+v\\n\", string(b2))\r\n}\r\n\r\n/* Output:\r\nQuery:\r\nquery {\r\n  people {\r\n    name\r\n    favorite_dog\r\n    }\r\n}\r\n\r\nResult: {\r\n  \"data\": {\r\n    \"people\": [\r\n      {\r\n        \"favorite_dog\": \"Yorkshire Terrier\",\r\n        \"name\": \"Alice\"\r\n      },\r\n      {\r\n        \"favorite_dog\": \"\",\r\n        \"name\": \"Bob\"\r\n      },\r\n      {\r\n        \"favorite_dog\": \"French Bulldog\",\r\n        \"name\": \"Chris\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n\r\nQuery (with arguments):\r\nquery {\r\n  people(favorite_dog: \"Yorkshire Terrier\") {\r\n    name\r\n    favorite_dog\r\n  }\r\n}\r\n\r\nResult (with arguments): {\r\n  \"data\": {\r\n    \"people\": [\r\n      {\r\n        \"favorite_dog\": \"Yorkshire Terrier\",\r\n        \"name\": \"Alice\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n*/\r\n"
  },
  {
    "path": "examples/star-wars/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc main() {\n\thttp.HandleFunc(\"/graphql\", func(w http.ResponseWriter, r *http.Request) {\n\t\tquery := r.URL.Query().Get(\"query\")\n\t\tresult := graphql.Do(graphql.Params{\n\t\t\tSchema:        testutil.StarWarsSchema,\n\t\t\tRequestString: query,\n\t\t})\n\t\tjson.NewEncoder(w).Encode(result)\n\t})\n\tfmt.Println(\"Now server is running on port 8080\")\n\tfmt.Println(\"Test with Get      : curl -g 'http://localhost:8080/graphql?query={hero{name}}'\")\n\thttp.ListenAndServe(\":8080\", nil)\n}\n"
  },
  {
    "path": "examples/todo/README.md",
    "content": "# Go GraphQL ToDo example\n\nAn example that consists of basic core GraphQL queries and mutations.\n\nTo run the example navigate to the example directory by using your shell of choice.\n\n```\ncd examples/todo\n```\n\nRun the example, it will spawn a GraphQL HTTP endpoint\n\n```\ngo run main.go\n```\n\nExecute queries via shell.\n\n```\n// To get single ToDo item by ID\ncurl -g 'http://localhost:8080/graphql?query={todo(id:\"b\"){id,text,done}}'\n\n// To create a ToDo item\ncurl -g 'http://localhost:8080/graphql?query=mutation+_{createTodo(text:\"My+new+todo\"){id,text,done}}'\n\n// To get a list of ToDo items\ncurl -g 'http://localhost:8080/graphql?query={todoList{id,text,done}}'\n\n// To update a ToDo\ncurl -g 'http://localhost:8080/graphql?query=mutation+_{updateTodo(id:\"b\",text:\"My+new+todo+updated\",done:true){id,text,done}}'\n```\n\n## Web App\n\nAccess the web app at `http://localhost:8080/`. It is work in progress and currently is simply loading todos by using jQuery ajax call.\n"
  },
  {
    "path": "examples/todo/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/examples/todo/schema\"\n)\n\nfunc init() {\n\ttodo1 := schema.Todo{ID: \"a\", Text: \"A todo not to forget\", Done: false}\n\ttodo2 := schema.Todo{ID: \"b\", Text: \"This is the most important\", Done: false}\n\ttodo3 := schema.Todo{ID: \"c\", Text: \"Please do this or else\", Done: false}\n\tschema.TodoList = append(schema.TodoList, todo1, todo2, todo3)\n\n\trand.Seed(time.Now().UnixNano())\n}\n\nfunc executeQuery(query string, schema graphql.Schema) *graphql.Result {\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) > 0 {\n\t\tfmt.Printf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\treturn result\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/graphql\", func(w http.ResponseWriter, r *http.Request) {\n\t\tresult := executeQuery(r.URL.Query().Get(\"query\"), schema.TodoSchema)\n\t\tjson.NewEncoder(w).Encode(result)\n\t})\n\t// Serve static files\n\tfs := http.FileServer(http.Dir(\"static\"))\n\thttp.Handle(\"/\", fs)\n\t// Display some basic instructions\n\tfmt.Println(\"Now server is running on port 8080\")\n\tfmt.Println(\"Get single todo: curl -g 'http://localhost:8080/graphql?query={todo(id:\\\"b\\\"){id,text,done}}'\")\n\tfmt.Println(\"Create new todo: curl -g 'http://localhost:8080/graphql?query=mutation+_{createTodo(text:\\\"My+new+todo\\\"){id,text,done}}'\")\n\tfmt.Println(\"Update todo: curl -g 'http://localhost:8080/graphql?query=mutation+_{updateTodo(id:\\\"a\\\",done:true){id,text,done}}'\")\n\tfmt.Println(\"Load todo list: curl -g 'http://localhost:8080/graphql?query={todoList{id,text,done}}'\")\n\tfmt.Println(\"Access the web app via browser at 'http://localhost:8080'\")\n\n\thttp.ListenAndServe(\":8080\", nil)\n}\n"
  },
  {
    "path": "examples/todo/schema/schema.go",
    "content": "package schema\n\nimport (\n\t\"math/rand\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\nvar TodoList []Todo\n\ntype Todo struct {\n\tID   string `json:\"id\"`\n\tText string `json:\"text\"`\n\tDone bool   `json:\"done\"`\n}\n\nvar letterRunes = []rune(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\")\n\nfunc RandStringRunes(n int) string {\n\tb := make([]rune, n)\n\tfor i := range b {\n\t\tb[i] = letterRunes[rand.Intn(len(letterRunes))]\n\t}\n\treturn string(b)\n}\n\n// define custom GraphQL ObjectType `todoType` for our Golang struct `Todo`\n// Note that\n// - the fields in our todoType maps with the json tags for the fields in our struct\n// - the field type matches the field type in our struct\nvar todoType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Todo\",\n\tFields: graphql.Fields{\n\t\t\"id\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"text\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"done\": &graphql.Field{\n\t\t\tType: graphql.Boolean,\n\t\t},\n\t},\n})\n\n// root mutation\nvar rootMutation = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"RootMutation\",\n\tFields: graphql.Fields{\n\t\t/*\n\t\t\tcurl -g 'http://localhost:8080/graphql?query=mutation+_{createTodo(text:\"My+new+todo\"){id,text,done}}'\n\t\t*/\n\t\t\"createTodo\": &graphql.Field{\n\t\t\tType:        todoType, // the return type for this field\n\t\t\tDescription: \"Create new todo\",\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"text\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\n\t\t\t\t// marshall and cast the argument value\n\t\t\t\ttext, _ := params.Args[\"text\"].(string)\n\n\t\t\t\t// figure out new id\n\t\t\t\tnewID := RandStringRunes(8)\n\n\t\t\t\t// perform mutation operation here\n\t\t\t\t// for e.g. create a Todo and save to DB.\n\t\t\t\tnewTodo := Todo{\n\t\t\t\t\tID:   newID,\n\t\t\t\t\tText: text,\n\t\t\t\t\tDone: false,\n\t\t\t\t}\n\n\t\t\t\tTodoList = append(TodoList, newTodo)\n\n\t\t\t\t// return the new Todo object that we supposedly save to DB\n\t\t\t\t// Note here that\n\t\t\t\t// - we are returning a `Todo` struct instance here\n\t\t\t\t// - we previously specified the return Type to be `todoType`\n\t\t\t\t// - `Todo` struct maps to `todoType`, as defined in `todoType` ObjectConfig`\n\t\t\t\treturn newTodo, nil\n\t\t\t},\n\t\t},\n\t\t/*\n\t\t\tcurl -g 'http://localhost:8080/graphql?query=mutation+_{updateTodo(id:\"a\",done:true){id,text,done}}'\n\t\t*/\n\t\t\"updateTodo\": &graphql.Field{\n\t\t\tType:        todoType, // the return type for this field\n\t\t\tDescription: \"Update existing todo, mark it done or not done\",\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"done\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t},\n\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t// marshall and cast the argument value\n\t\t\t\tdone, _ := params.Args[\"done\"].(bool)\n\t\t\t\tid, _ := params.Args[\"id\"].(string)\n\t\t\t\taffectedTodo := Todo{}\n\n\t\t\t\t// Search list for todo with id and change the done variable\n\t\t\t\tfor i := 0; i < len(TodoList); i++ {\n\t\t\t\t\tif TodoList[i].ID == id {\n\t\t\t\t\t\tTodoList[i].Done = done\n\t\t\t\t\t\t// Assign updated todo so we can return it\n\t\t\t\t\t\taffectedTodo = TodoList[i]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Return affected todo\n\t\t\t\treturn affectedTodo, nil\n\t\t\t},\n\t\t},\n\t},\n})\n\n// root query\n// we just define a trivial example here, since root query is required.\n// Test with curl\n// curl -g 'http://localhost:8080/graphql?query={lastTodo{id,text,done}}'\nvar rootQuery = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"RootQuery\",\n\tFields: graphql.Fields{\n\n\t\t/*\n\t\t   curl -g 'http://localhost:8080/graphql?query={todo(id:\"b\"){id,text,done}}'\n\t\t*/\n\t\t\"todo\": &graphql.Field{\n\t\t\tType:        todoType,\n\t\t\tDescription: \"Get single todo\",\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\n\t\t\t\tidQuery, isOK := params.Args[\"id\"].(string)\n\t\t\t\tif isOK {\n\t\t\t\t\t// Search for el with id\n\t\t\t\t\tfor _, todo := range TodoList {\n\t\t\t\t\t\tif todo.ID == idQuery {\n\t\t\t\t\t\t\treturn todo, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn Todo{}, nil\n\t\t\t},\n\t\t},\n\n\t\t\"lastTodo\": &graphql.Field{\n\t\t\tType:        todoType,\n\t\t\tDescription: \"Last todo added\",\n\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\treturn TodoList[len(TodoList)-1], nil\n\t\t\t},\n\t\t},\n\n\t\t/*\n\t\t   curl -g 'http://localhost:8080/graphql?query={todoList{id,text,done}}'\n\t\t*/\n\t\t\"todoList\": &graphql.Field{\n\t\t\tType:        graphql.NewList(todoType),\n\t\t\tDescription: \"List of todos\",\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\treturn TodoList, nil\n\t\t\t},\n\t\t},\n\t},\n})\n\n// define schema, with our rootQuery and rootMutation\nvar TodoSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\tQuery:    rootQuery,\n\tMutation: rootMutation,\n})\n"
  },
  {
    "path": "examples/todo/static/assets/css/style.css",
    "content": "body {\n    background-color: #cccccc;\n    color: #333333;\n    font-family: sans-serif;\n}\n\n.todo-done {\n    opacity: 0.5;\n}"
  },
  {
    "path": "examples/todo/static/assets/js/app.js",
    "content": "var updateTodo = function(id, isDone){\n  $.ajax({\n    url: '/graphql?query=mutation+_{updateTodo(id:\"' + id + '\",done:' + isDone + '){id,text,done}}'\n  }).done(function(data) {\n    console.log(data);\n    var dataParsed = JSON.parse(data);\n    var updatedTodo = dataParsed.data.updateTodo;\n    if (updatedTodo.done) {\n      $('#' + updatedTodo.id).parent().parent().parent().addClass('todo-done');\n    } else {\n      $('#' + updatedTodo.id).parent().parent().parent().removeClass('todo-done');\n    } \n  });\n};\n\nvar handleTodoList = function(object) {\n  var todos = object;\n\n  if (!todos.length) {\n    $('.todo-list-container').append('<p>There are no tasks for you today</p>');\n    return\n  } else {\n    $('.todo-list-container p').remove();\n  }\n\n  $.each(todos, function(i, v) {\n    var todoTemplate = $('#todoItemTemplate').html();\n    var todo = todoTemplate.replace('{{todo-id}}', v.id);\n    todo = todo.replace('{{todo-text}}', v.text);\n    todo = todo.replace('{{todo-checked}}', (v.done ? ' checked=\"checked\"' : ''));\n    todo = todo.replace('{{todo-done}}', (v.done ? ' todo-done' : ''));\n\n    $('.todo-list-container').append(todo);\n    $('#' + v.id).click(function(){\n      var id = $(this).prop('id');\n      var isDone = $(this).prop('checked');\n      updateTodo(id, isDone);\n    });\n  });\n};\n\nvar loadTodos = function() {\n  $.ajax({\n    url: \"/graphql?query={todoList{id,text,done}}\"\n  }).done(function(data) {\n    console.log(data);\n    var dataParsed = JSON.parse(data);\n    handleTodoList(dataParsed.data.todoList);\n  });\n};\n\nvar addTodo = function(todoText) {\n  if (!todoText || todoText === \"\") {\n    alert('Please specify a task');\n    return;\n  }\n\n  $.ajax({\n    url: '/graphql?query=mutation+_{createTodo(text:\"' + todoText + '\"){id,text,done}}'\n  }).done(function(data) {\n    console.log(data);\n    var dataParsed = JSON.parse(data);\n    var todoList = [dataParsed.data.createTodo];\n    handleTodoList(todoList);\n  });\n};\n\n$(document).ready(function() {\n  $('.todo-add-form').submit(function(e){\n    e.preventDefault();\n    addTodo($('.todo-add-form #task').val());\n    $('.todo-add-form #task').val('');\n  });\n\n  loadTodos();\n});\n"
  },
  {
    "path": "examples/todo/static/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n  <title>ToDo</title>\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css\">\n  <link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"/assets/css/style.css\">\n</head>\n<body>\n\n<div class=\"wrapper\">\n\n  <div class=\"container\">\n\n    <h1>ToDo</h1>\n\n    <div class=\"todo-list\">\n      <h2>Tasks</h2>\n      <div class=\"todo-list-container\">\n        \n        <div class=\"\"></div>\n\n      </div>\n    </div><!-- /.todo-list -->\n\n    <div class=\"todo-add\">\n      \n      <h2>Add task</h2>\n\n      <form class=\"todo-add-form\">\n        <div class=\"form-group\">\n          <input \n            type=\"text\" \n            name=\"task\" \n            id=\"task\" \n            placeholder=\"Your task\"\n            class=\"form-control\">\n        </div>\n        <button class=\"btn btn-primary\">Add</button>\n      </form>\n\n    </div><!-- /.todo-add -->\n\n  </div><!-- /.container -->\n\n</div><!-- /.wrapper -->\n\n<template id=\"todoItemTemplate\">\n  <div class=\"todo-item{{todo-done}}\">\n    <div class=\"checkbox\">\n      <label>\n        <input id=\"{{todo-id}}\" type=\"checkbox\"{{todo-checked}}> {{todo-text}}\n      </label>\n    </div>\n  </div>\n</template>\n\n<script src=\"https://code.jquery.com/jquery-1.11.3.min.js\"></script>\n<script src=\"/assets/js/app.js\"></script>\n\n</body>\n</html>"
  },
  {
    "path": "executor.go",
    "content": "package graphql\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\ntype ExecuteParams struct {\n\tSchema        Schema\n\tRoot          interface{}\n\tAST           *ast.Document\n\tOperationName string\n\tArgs          map[string]interface{}\n\n\t// Context may be provided to pass application-specific per-request\n\t// information to resolve functions.\n\tContext context.Context\n}\n\nfunc Execute(p ExecuteParams) (result *Result) {\n\t// Use background context if no context was provided\n\tctx := p.Context\n\tif ctx == nil {\n\t\tctx = context.Background()\n\t}\n\t// run executionDidStart functions from extensions\n\textErrs, executionFinishFn := handleExtensionsExecutionDidStart(&p)\n\tif len(extErrs) != 0 {\n\t\treturn &Result{\n\t\t\tErrors: extErrs,\n\t\t}\n\t}\n\n\tdefer func() {\n\t\textErrs = executionFinishFn(result)\n\t\tif len(extErrs) != 0 {\n\t\t\tresult.Errors = append(result.Errors, extErrs...)\n\t\t}\n\n\t\taddExtensionResults(&p, result)\n\t}()\n\n\tresultChannel := make(chan *Result, 2)\n\n\tgo func() {\n\t\tresult := &Result{}\n\n\t\tdefer func() {\n\t\t\tif err := recover(); err != nil {\n\t\t\t\tresult.Errors = append(result.Errors, gqlerrors.FormatError(err.(error)))\n\t\t\t}\n\t\t\tresultChannel <- result\n\t\t}()\n\n\t\texeContext, err := buildExecutionContext(buildExecutionCtxParams{\n\t\t\tSchema:        p.Schema,\n\t\t\tRoot:          p.Root,\n\t\t\tAST:           p.AST,\n\t\t\tOperationName: p.OperationName,\n\t\t\tArgs:          p.Args,\n\t\t\tResult:        result,\n\t\t\tContext:       p.Context,\n\t\t})\n\n\t\tif err != nil {\n\t\t\tresult.Errors = append(result.Errors, gqlerrors.FormatError(err.(error)))\n\t\t\tresultChannel <- result\n\t\t\treturn\n\t\t}\n\n\t\tresultChannel <- executeOperation(executeOperationParams{\n\t\t\tExecutionContext: exeContext,\n\t\t\tRoot:             p.Root,\n\t\t\tOperation:        exeContext.Operation,\n\t\t})\n\t}()\n\n\tselect {\n\tcase <-ctx.Done():\n\t\tresult := &Result{}\n\t\tresult.Errors = append(result.Errors, gqlerrors.FormatError(ctx.Err()))\n\t\treturn result\n\tcase r := <-resultChannel:\n\t\treturn r\n\t}\n}\n\ntype buildExecutionCtxParams struct {\n\tSchema        Schema\n\tRoot          interface{}\n\tAST           *ast.Document\n\tOperationName string\n\tArgs          map[string]interface{}\n\tResult        *Result\n\tContext       context.Context\n}\n\ntype executionContext struct {\n\tSchema         Schema\n\tFragments      map[string]ast.Definition\n\tRoot           interface{}\n\tOperation      ast.Definition\n\tVariableValues map[string]interface{}\n\tErrors         []gqlerrors.FormattedError\n\tContext        context.Context\n}\n\nfunc buildExecutionContext(p buildExecutionCtxParams) (*executionContext, error) {\n\teCtx := &executionContext{}\n\tvar operation *ast.OperationDefinition\n\tfragments := map[string]ast.Definition{}\n\n\tfor _, definition := range p.AST.Definitions {\n\t\tswitch definition := definition.(type) {\n\t\tcase *ast.OperationDefinition:\n\t\t\tif (p.OperationName == \"\") && operation != nil {\n\t\t\t\treturn nil, errors.New(\"Must provide operation name if query contains multiple operations.\")\n\t\t\t}\n\t\t\tif p.OperationName == \"\" || definition.GetName() != nil && definition.GetName().Value == p.OperationName {\n\t\t\t\toperation = definition\n\t\t\t}\n\t\tcase *ast.FragmentDefinition:\n\t\t\tkey := \"\"\n\t\t\tif definition.GetName() != nil && definition.GetName().Value != \"\" {\n\t\t\t\tkey = definition.GetName().Value\n\t\t\t}\n\t\t\tfragments[key] = definition\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"GraphQL cannot execute a request containing a %v\", definition.GetKind())\n\t\t}\n\t}\n\n\tif operation == nil {\n\t\tif p.OperationName != \"\" {\n\t\t\treturn nil, fmt.Errorf(`Unknown operation named \"%v\".`, p.OperationName)\n\t\t}\n\t\treturn nil, fmt.Errorf(`Must provide an operation.`)\n\t}\n\n\tvariableValues, err := getVariableValues(p.Schema, operation.GetVariableDefinitions(), p.Args)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\teCtx.Schema = p.Schema\n\teCtx.Fragments = fragments\n\teCtx.Root = p.Root\n\teCtx.Operation = operation\n\teCtx.VariableValues = variableValues\n\teCtx.Context = p.Context\n\treturn eCtx, nil\n}\n\ntype executeOperationParams struct {\n\tExecutionContext *executionContext\n\tRoot             interface{}\n\tOperation        ast.Definition\n}\n\nfunc executeOperation(p executeOperationParams) *Result {\n\toperationType, err := getOperationRootType(p.ExecutionContext.Schema, p.Operation)\n\tif err != nil {\n\t\treturn &Result{Errors: gqlerrors.FormatErrors(err)}\n\t}\n\n\tfields := collectFields(collectFieldsParams{\n\t\tExeContext:   p.ExecutionContext,\n\t\tRuntimeType:  operationType,\n\t\tSelectionSet: p.Operation.GetSelectionSet(),\n\t})\n\n\texecuteFieldsParams := executeFieldsParams{\n\t\tExecutionContext: p.ExecutionContext,\n\t\tParentType:       operationType,\n\t\tSource:           p.Root,\n\t\tFields:           fields,\n\t}\n\n\tif p.Operation.GetOperation() == ast.OperationTypeMutation {\n\t\treturn executeFieldsSerially(executeFieldsParams)\n\t}\n\treturn executeFields(executeFieldsParams)\n\n}\n\n// Extracts the root type of the operation from the schema.\nfunc getOperationRootType(schema Schema, operation ast.Definition) (*Object, error) {\n\tif operation == nil {\n\t\treturn nil, errors.New(\"Can only execute queries, mutations and subscription\")\n\t}\n\n\tswitch operation.GetOperation() {\n\tcase ast.OperationTypeQuery:\n\t\treturn schema.QueryType(), nil\n\tcase ast.OperationTypeMutation:\n\t\tmutationType := schema.MutationType()\n\t\tif mutationType == nil || mutationType.PrivateName == \"\" {\n\t\t\treturn nil, gqlerrors.NewError(\n\t\t\t\t\"Schema is not configured for mutations\",\n\t\t\t\t[]ast.Node{operation},\n\t\t\t\t\"\",\n\t\t\t\tnil,\n\t\t\t\t[]int{},\n\t\t\t\tnil,\n\t\t\t)\n\t\t}\n\t\treturn mutationType, nil\n\tcase ast.OperationTypeSubscription:\n\t\tsubscriptionType := schema.SubscriptionType()\n\t\tif subscriptionType == nil || subscriptionType.PrivateName == \"\" {\n\t\t\treturn nil, gqlerrors.NewError(\n\t\t\t\t\"Schema is not configured for subscriptions\",\n\t\t\t\t[]ast.Node{operation},\n\t\t\t\t\"\",\n\t\t\t\tnil,\n\t\t\t\t[]int{},\n\t\t\t\tnil,\n\t\t\t)\n\t\t}\n\t\treturn subscriptionType, nil\n\tdefault:\n\t\treturn nil, gqlerrors.NewError(\n\t\t\t\"Can only execute queries, mutations and subscription\",\n\t\t\t[]ast.Node{operation},\n\t\t\t\"\",\n\t\t\tnil,\n\t\t\t[]int{},\n\t\t\tnil,\n\t\t)\n\t}\n}\n\ntype executeFieldsParams struct {\n\tExecutionContext *executionContext\n\tParentType       *Object\n\tSource           interface{}\n\tFields           map[string][]*ast.Field\n\tPath             *ResponsePath\n}\n\n// Implements the \"Evaluating selection sets\" section of the spec for \"write\" mode.\nfunc executeFieldsSerially(p executeFieldsParams) *Result {\n\tif p.Source == nil {\n\t\tp.Source = map[string]interface{}{}\n\t}\n\tif p.Fields == nil {\n\t\tp.Fields = map[string][]*ast.Field{}\n\t}\n\n\tfinalResults := make(map[string]interface{}, len(p.Fields))\n\tfor _, orderedField := range orderedFields(p.Fields) {\n\t\tresponseName := orderedField.responseName\n\t\tfieldASTs := orderedField.fieldASTs\n\t\tfieldPath := p.Path.WithKey(responseName)\n\t\tresolved, state := resolveField(p.ExecutionContext, p.ParentType, p.Source, fieldASTs, fieldPath)\n\t\tif state.hasNoFieldDefs {\n\t\t\tcontinue\n\t\t}\n\t\tfinalResults[responseName] = resolved\n\t}\n\tdethunkMapDepthFirst(finalResults)\n\n\treturn &Result{\n\t\tData:   finalResults,\n\t\tErrors: p.ExecutionContext.Errors,\n\t}\n}\n\n// Implements the \"Evaluating selection sets\" section of the spec for \"read\" mode.\nfunc executeFields(p executeFieldsParams) *Result {\n\tfinalResults := executeSubFields(p)\n\n\tdethunkMapWithBreadthFirstTraversal(finalResults)\n\n\treturn &Result{\n\t\tData:   finalResults,\n\t\tErrors: p.ExecutionContext.Errors,\n\t}\n}\n\nfunc executeSubFields(p executeFieldsParams) map[string]interface{} {\n\n\tif p.Source == nil {\n\t\tp.Source = map[string]interface{}{}\n\t}\n\tif p.Fields == nil {\n\t\tp.Fields = map[string][]*ast.Field{}\n\t}\n\n\tfinalResults := make(map[string]interface{}, len(p.Fields))\n\tfor responseName, fieldASTs := range p.Fields {\n\t\tfieldPath := p.Path.WithKey(responseName)\n\t\tresolved, state := resolveField(p.ExecutionContext, p.ParentType, p.Source, fieldASTs, fieldPath)\n\t\tif state.hasNoFieldDefs {\n\t\t\tcontinue\n\t\t}\n\t\tfinalResults[responseName] = resolved\n\t}\n\n\treturn finalResults\n}\n\n// dethunkQueue is a structure that allows us to execute a classic breadth-first traversal.\ntype dethunkQueue struct {\n\tDethunkFuncs []func()\n}\n\nfunc (d *dethunkQueue) push(f func()) {\n\td.DethunkFuncs = append(d.DethunkFuncs, f)\n}\n\nfunc (d *dethunkQueue) shift() func() {\n\tf := d.DethunkFuncs[0]\n\td.DethunkFuncs = d.DethunkFuncs[1:]\n\treturn f\n}\n\n// dethunkWithBreadthFirstTraversal performs a breadth-first descent of the map, calling any thunks\n// in the map values and replacing each thunk with that thunk's return value. This parallels\n// the reference graphql-js implementation, which calls Promise.all on thunks at each depth (which\n// is an implicit parallel descent).\nfunc dethunkMapWithBreadthFirstTraversal(finalResults map[string]interface{}) {\n\tdethunkQueue := &dethunkQueue{DethunkFuncs: []func(){}}\n\tdethunkMapBreadthFirst(finalResults, dethunkQueue)\n\tfor len(dethunkQueue.DethunkFuncs) > 0 {\n\t\tf := dethunkQueue.shift()\n\t\tf()\n\t}\n}\n\nfunc dethunkMapBreadthFirst(m map[string]interface{}, dethunkQueue *dethunkQueue) {\n\tfor k, v := range m {\n\t\tif f, ok := v.(func() interface{}); ok {\n\t\t\tm[k] = f()\n\t\t}\n\t\tswitch val := m[k].(type) {\n\t\tcase map[string]interface{}:\n\t\t\tdethunkQueue.push(func() { dethunkMapBreadthFirst(val, dethunkQueue) })\n\t\tcase []interface{}:\n\t\t\tdethunkQueue.push(func() { dethunkListBreadthFirst(val, dethunkQueue) })\n\t\t}\n\t}\n}\n\nfunc dethunkListBreadthFirst(list []interface{}, dethunkQueue *dethunkQueue) {\n\tfor i, v := range list {\n\t\tif f, ok := v.(func() interface{}); ok {\n\t\t\tlist[i] = f()\n\t\t}\n\t\tswitch val := list[i].(type) {\n\t\tcase map[string]interface{}:\n\t\t\tdethunkQueue.push(func() { dethunkMapBreadthFirst(val, dethunkQueue) })\n\t\tcase []interface{}:\n\t\t\tdethunkQueue.push(func() { dethunkListBreadthFirst(val, dethunkQueue) })\n\t\t}\n\t}\n}\n\n// dethunkMapDepthFirst performs a serial descent of the map, calling any thunks\n// in the map values and replacing each thunk with that thunk's return value. This is needed\n// to conform to the graphql-js reference implementation, which requires serial (depth-first)\n// implementations for mutation selects.\nfunc dethunkMapDepthFirst(m map[string]interface{}) {\n\tfor k, v := range m {\n\t\tif f, ok := v.(func() interface{}); ok {\n\t\t\tm[k] = f()\n\t\t}\n\t\tswitch val := m[k].(type) {\n\t\tcase map[string]interface{}:\n\t\t\tdethunkMapDepthFirst(val)\n\t\tcase []interface{}:\n\t\t\tdethunkListDepthFirst(val)\n\t\t}\n\t}\n}\n\nfunc dethunkListDepthFirst(list []interface{}) {\n\tfor i, v := range list {\n\t\tif f, ok := v.(func() interface{}); ok {\n\t\t\tlist[i] = f()\n\t\t}\n\t\tswitch val := list[i].(type) {\n\t\tcase map[string]interface{}:\n\t\t\tdethunkMapDepthFirst(val)\n\t\tcase []interface{}:\n\t\t\tdethunkListDepthFirst(val)\n\t\t}\n\t}\n}\n\ntype collectFieldsParams struct {\n\tExeContext           *executionContext\n\tRuntimeType          *Object // previously known as OperationType\n\tSelectionSet         *ast.SelectionSet\n\tFields               map[string][]*ast.Field\n\tVisitedFragmentNames map[string]bool\n}\n\n// Given a selectionSet, adds all of the fields in that selection to\n// the passed in map of fields, and returns it at the end.\n// CollectFields requires the \"runtime type\" of an object. For a field which\n// returns and Interface or Union type, the \"runtime type\" will be the actual\n// Object type returned by that field.\nfunc collectFields(p collectFieldsParams) (fields map[string][]*ast.Field) {\n\t// overlying SelectionSet & Fields to fields\n\tif p.SelectionSet == nil {\n\t\treturn p.Fields\n\t}\n\tfields = p.Fields\n\tif fields == nil {\n\t\tfields = map[string][]*ast.Field{}\n\t}\n\tif p.VisitedFragmentNames == nil {\n\t\tp.VisitedFragmentNames = map[string]bool{}\n\t}\n\tfor _, iSelection := range p.SelectionSet.Selections {\n\t\tswitch selection := iSelection.(type) {\n\t\tcase *ast.Field:\n\t\t\tif !shouldIncludeNode(p.ExeContext, selection.Directives) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tname := getFieldEntryKey(selection)\n\t\t\tif _, ok := fields[name]; !ok {\n\t\t\t\tfields[name] = []*ast.Field{}\n\t\t\t}\n\t\t\tfields[name] = append(fields[name], selection)\n\t\tcase *ast.InlineFragment:\n\n\t\t\tif !shouldIncludeNode(p.ExeContext, selection.Directives) ||\n\t\t\t\t!doesFragmentConditionMatch(p.ExeContext, selection, p.RuntimeType) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tinnerParams := collectFieldsParams{\n\t\t\t\tExeContext:           p.ExeContext,\n\t\t\t\tRuntimeType:          p.RuntimeType,\n\t\t\t\tSelectionSet:         selection.SelectionSet,\n\t\t\t\tFields:               fields,\n\t\t\t\tVisitedFragmentNames: p.VisitedFragmentNames,\n\t\t\t}\n\t\t\tcollectFields(innerParams)\n\t\tcase *ast.FragmentSpread:\n\t\t\tfragName := \"\"\n\t\t\tif selection.Name != nil {\n\t\t\t\tfragName = selection.Name.Value\n\t\t\t}\n\t\t\tif visited, ok := p.VisitedFragmentNames[fragName]; (ok && visited) ||\n\t\t\t\t!shouldIncludeNode(p.ExeContext, selection.Directives) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tp.VisitedFragmentNames[fragName] = true\n\t\t\tfragment, hasFragment := p.ExeContext.Fragments[fragName]\n\t\t\tif !hasFragment {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif fragment, ok := fragment.(*ast.FragmentDefinition); ok {\n\t\t\t\tif !doesFragmentConditionMatch(p.ExeContext, fragment, p.RuntimeType) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tinnerParams := collectFieldsParams{\n\t\t\t\t\tExeContext:           p.ExeContext,\n\t\t\t\t\tRuntimeType:          p.RuntimeType,\n\t\t\t\t\tSelectionSet:         fragment.GetSelectionSet(),\n\t\t\t\t\tFields:               fields,\n\t\t\t\t\tVisitedFragmentNames: p.VisitedFragmentNames,\n\t\t\t\t}\n\t\t\t\tcollectFields(innerParams)\n\t\t\t}\n\t\t}\n\t}\n\treturn fields\n}\n\n// Determines if a field should be included based on the @include and @skip\n// directives, where @skip has higher precedence than @include.\nfunc shouldIncludeNode(eCtx *executionContext, directives []*ast.Directive) bool {\n\tvar (\n\t\tskipAST, includeAST *ast.Directive\n\t\targValues           map[string]interface{}\n\t)\n\tfor _, directive := range directives {\n\t\tif directive == nil || directive.Name == nil {\n\t\t\tcontinue\n\t\t}\n\t\tswitch directive.Name.Value {\n\t\tcase SkipDirective.Name:\n\t\t\tskipAST = directive\n\t\tcase IncludeDirective.Name:\n\t\t\tincludeAST = directive\n\t\t}\n\t}\n\t// precedence: skipAST > includeAST\n\tif skipAST != nil {\n\t\targValues = getArgumentValues(SkipDirective.Args, skipAST.Arguments, eCtx.VariableValues)\n\t\tif skipIf, ok := argValues[\"if\"].(bool); ok && skipIf {\n\t\t\treturn false // excluded selectionSet's fields\n\t\t}\n\t}\n\tif includeAST != nil {\n\t\targValues = getArgumentValues(IncludeDirective.Args, includeAST.Arguments, eCtx.VariableValues)\n\t\tif includeIf, ok := argValues[\"if\"].(bool); ok && !includeIf {\n\t\t\treturn false // excluded selectionSet's fields\n\t\t}\n\t}\n\treturn true\n}\n\n// Determines if a fragment is applicable to the given type.\nfunc doesFragmentConditionMatch(eCtx *executionContext, fragment ast.Node, ttype *Object) bool {\n\n\tswitch fragment := fragment.(type) {\n\tcase *ast.FragmentDefinition:\n\t\ttypeConditionAST := fragment.TypeCondition\n\t\tif typeConditionAST == nil {\n\t\t\treturn true\n\t\t}\n\t\tconditionalType, err := typeFromAST(eCtx.Schema, typeConditionAST)\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\tif conditionalType == ttype {\n\t\t\treturn true\n\t\t}\n\t\tif conditionalType.Name() == ttype.Name() {\n\t\t\treturn true\n\t\t}\n\t\tif conditionalType, ok := conditionalType.(*Interface); ok {\n\t\t\treturn eCtx.Schema.IsPossibleType(conditionalType, ttype)\n\t\t}\n\t\tif conditionalType, ok := conditionalType.(*Union); ok {\n\t\t\treturn eCtx.Schema.IsPossibleType(conditionalType, ttype)\n\t\t}\n\tcase *ast.InlineFragment:\n\t\ttypeConditionAST := fragment.TypeCondition\n\t\tif typeConditionAST == nil {\n\t\t\treturn true\n\t\t}\n\t\tconditionalType, err := typeFromAST(eCtx.Schema, typeConditionAST)\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\tif conditionalType == ttype {\n\t\t\treturn true\n\t\t}\n\t\tif conditionalType.Name() == ttype.Name() {\n\t\t\treturn true\n\t\t}\n\t\tif conditionalType, ok := conditionalType.(*Interface); ok {\n\t\t\treturn eCtx.Schema.IsPossibleType(conditionalType, ttype)\n\t\t}\n\t\tif conditionalType, ok := conditionalType.(*Union); ok {\n\t\t\treturn eCtx.Schema.IsPossibleType(conditionalType, ttype)\n\t\t}\n\t}\n\n\treturn false\n}\n\n// Implements the logic to compute the key of a given field’s entry\nfunc getFieldEntryKey(node *ast.Field) string {\n\n\tif node.Alias != nil && node.Alias.Value != \"\" {\n\t\treturn node.Alias.Value\n\t}\n\tif node.Name != nil && node.Name.Value != \"\" {\n\t\treturn node.Name.Value\n\t}\n\treturn \"\"\n}\n\n// Internal resolveField state\ntype resolveFieldResultState struct {\n\thasNoFieldDefs bool\n}\n\nfunc handleFieldError(r interface{}, fieldNodes []ast.Node, path *ResponsePath, returnType Output, eCtx *executionContext) {\n\terr := NewLocatedErrorWithPath(r, fieldNodes, path.AsArray())\n\t// send panic upstream\n\tif _, ok := returnType.(*NonNull); ok {\n\t\tpanic(err)\n\t}\n\teCtx.Errors = append(eCtx.Errors, gqlerrors.FormatError(err))\n}\n\n// Resolves the field on the given source object. In particular, this\n// figures out the value that the field returns by calling its resolve function,\n// then calls completeValue to complete promises, serialize scalars, or execute\n// the sub-selection-set for objects.\nfunc resolveField(eCtx *executionContext, parentType *Object, source interface{}, fieldASTs []*ast.Field, path *ResponsePath) (result interface{}, resultState resolveFieldResultState) {\n\t// catch panic from resolveFn\n\tvar returnType Output\n\tdefer func() (interface{}, resolveFieldResultState) {\n\t\tif r := recover(); r != nil {\n\t\t\thandleFieldError(r, FieldASTsToNodeASTs(fieldASTs), path, returnType, eCtx)\n\t\t\treturn result, resultState\n\t\t}\n\t\treturn result, resultState\n\t}()\n\n\tfieldAST := fieldASTs[0]\n\tfieldName := \"\"\n\tif fieldAST.Name != nil {\n\t\tfieldName = fieldAST.Name.Value\n\t}\n\n\tfieldDef := getFieldDef(eCtx.Schema, parentType, fieldName)\n\tif fieldDef == nil {\n\t\tresultState.hasNoFieldDefs = true\n\t\treturn nil, resultState\n\t}\n\treturnType = fieldDef.Type\n\tresolveFn := fieldDef.Resolve\n\tif resolveFn == nil {\n\t\tresolveFn = DefaultResolveFn\n\t}\n\n\t// Build a map of arguments from the field.arguments AST, using the\n\t// variables scope to fulfill any variable references.\n\t// TODO: find a way to memoize, in case this field is within a List type.\n\targs := getArgumentValues(fieldDef.Args, fieldAST.Arguments, eCtx.VariableValues)\n\n\tinfo := ResolveInfo{\n\t\tFieldName:      fieldName,\n\t\tFieldASTs:      fieldASTs,\n\t\tPath:           path,\n\t\tReturnType:     returnType,\n\t\tParentType:     parentType,\n\t\tSchema:         eCtx.Schema,\n\t\tFragments:      eCtx.Fragments,\n\t\tRootValue:      eCtx.Root,\n\t\tOperation:      eCtx.Operation,\n\t\tVariableValues: eCtx.VariableValues,\n\t}\n\n\tvar resolveFnError error\n\n\textErrs, resolveFieldFinishFn := handleExtensionsResolveFieldDidStart(eCtx.Schema.extensions, eCtx, &info)\n\tif len(extErrs) != 0 {\n\t\teCtx.Errors = append(eCtx.Errors, extErrs...)\n\t}\n\n\tresult, resolveFnError = resolveFn(ResolveParams{\n\t\tSource:  source,\n\t\tArgs:    args,\n\t\tInfo:    info,\n\t\tContext: eCtx.Context,\n\t})\n\n\textErrs = resolveFieldFinishFn(result, resolveFnError)\n\tif len(extErrs) != 0 {\n\t\teCtx.Errors = append(eCtx.Errors, extErrs...)\n\t}\n\n\tif resolveFnError != nil {\n\t\tpanic(resolveFnError)\n\t}\n\n\tcompleted := completeValueCatchingError(eCtx, returnType, fieldASTs, info, path, result)\n\treturn completed, resultState\n}\n\nfunc completeValueCatchingError(eCtx *executionContext, returnType Type, fieldASTs []*ast.Field, info ResolveInfo, path *ResponsePath, result interface{}) (completed interface{}) {\n\t// catch panic\n\tdefer func() interface{} {\n\t\tif r := recover(); r != nil {\n\t\t\thandleFieldError(r, FieldASTsToNodeASTs(fieldASTs), path, returnType, eCtx)\n\t\t\treturn completed\n\t\t}\n\t\treturn completed\n\t}()\n\n\tif returnType, ok := returnType.(*NonNull); ok {\n\t\tcompleted := completeValue(eCtx, returnType, fieldASTs, info, path, result)\n\t\treturn completed\n\t}\n\tcompleted = completeValue(eCtx, returnType, fieldASTs, info, path, result)\n\treturn completed\n}\n\nfunc completeValue(eCtx *executionContext, returnType Type, fieldASTs []*ast.Field, info ResolveInfo, path *ResponsePath, result interface{}) interface{} {\n\n\tresultVal := reflect.ValueOf(result)\n\tif resultVal.IsValid() && resultVal.Kind() == reflect.Func {\n\t\treturn func() interface{} {\n\t\t\treturn completeThunkValueCatchingError(eCtx, returnType, fieldASTs, info, path, result)\n\t\t}\n\t}\n\n\t// If field type is NonNull, complete for inner type, and throw field error\n\t// if result is null.\n\tif returnType, ok := returnType.(*NonNull); ok {\n\t\tcompleted := completeValue(eCtx, returnType.OfType, fieldASTs, info, path, result)\n\t\tif completed == nil {\n\t\t\terr := NewLocatedErrorWithPath(\n\t\t\t\tfmt.Sprintf(\"Cannot return null for non-nullable field %v.%v.\", info.ParentType, info.FieldName),\n\t\t\t\tFieldASTsToNodeASTs(fieldASTs),\n\t\t\t\tpath.AsArray(),\n\t\t\t)\n\t\t\tpanic(gqlerrors.FormatError(err))\n\t\t}\n\t\treturn completed\n\t}\n\n\t// If result value is null-ish (null, undefined, or NaN) then return null.\n\tif isNullish(result) {\n\t\treturn nil\n\t}\n\n\t// If field type is List, complete each item in the list with the inner type\n\tif returnType, ok := returnType.(*List); ok {\n\t\treturn completeListValue(eCtx, returnType, fieldASTs, info, path, result)\n\t}\n\n\t// If field type is a leaf type, Scalar or Enum, serialize to a valid value,\n\t// returning null if serialization is not possible.\n\tif returnType, ok := returnType.(*Scalar); ok {\n\t\treturn completeLeafValue(returnType, result)\n\t}\n\tif returnType, ok := returnType.(*Enum); ok {\n\t\treturn completeLeafValue(returnType, result)\n\t}\n\n\t// If field type is an abstract type, Interface or Union, determine the\n\t// runtime Object type and complete for that type.\n\tif returnType, ok := returnType.(*Union); ok {\n\t\treturn completeAbstractValue(eCtx, returnType, fieldASTs, info, path, result)\n\t}\n\tif returnType, ok := returnType.(*Interface); ok {\n\t\treturn completeAbstractValue(eCtx, returnType, fieldASTs, info, path, result)\n\t}\n\n\t// If field type is Object, execute and complete all sub-selections.\n\tif returnType, ok := returnType.(*Object); ok {\n\t\treturn completeObjectValue(eCtx, returnType, fieldASTs, info, path, result)\n\t}\n\n\t// Not reachable. All possible output types have been considered.\n\terr := invariantf(false,\n\t\t`Cannot complete value of unexpected type \"%v.\"`, returnType)\n\n\tif err != nil {\n\t\tpanic(gqlerrors.FormatError(err))\n\t}\n\treturn nil\n}\n\nfunc completeThunkValueCatchingError(eCtx *executionContext, returnType Type, fieldASTs []*ast.Field, info ResolveInfo, path *ResponsePath, result interface{}) (completed interface{}) {\n\n\t// catch any panic invoked from the propertyFn (thunk)\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\thandleFieldError(r, FieldASTsToNodeASTs(fieldASTs), path, returnType, eCtx)\n\t\t}\n\t}()\n\n\tpropertyFn, ok := result.(func() (interface{}, error))\n\tif !ok {\n\t\terr := gqlerrors.NewFormattedError(\"Error resolving func. Expected `func() (interface{}, error)` signature\")\n\t\tpanic(gqlerrors.FormatError(err))\n\t}\n\tfnResult, err := propertyFn()\n\tif err != nil {\n\t\tpanic(gqlerrors.FormatError(err))\n\t}\n\n\tresult = fnResult\n\n\tif returnType, ok := returnType.(*NonNull); ok {\n\t\tcompleted := completeValue(eCtx, returnType, fieldASTs, info, path, result)\n\t\treturn completed\n\t}\n\tcompleted = completeValue(eCtx, returnType, fieldASTs, info, path, result)\n\n\treturn completed\n}\n\n// completeAbstractValue completes value of an Abstract type (Union / Interface) by determining the runtime type\n// of that value, then completing based on that type.\nfunc completeAbstractValue(eCtx *executionContext, returnType Abstract, fieldASTs []*ast.Field, info ResolveInfo, path *ResponsePath, result interface{}) interface{} {\n\n\tvar runtimeType *Object\n\n\tresolveTypeParams := ResolveTypeParams{\n\t\tValue:   result,\n\t\tInfo:    info,\n\t\tContext: eCtx.Context,\n\t}\n\tif unionReturnType, ok := returnType.(*Union); ok && unionReturnType.ResolveType != nil {\n\t\truntimeType = unionReturnType.ResolveType(resolveTypeParams)\n\t} else if interfaceReturnType, ok := returnType.(*Interface); ok && interfaceReturnType.ResolveType != nil {\n\t\truntimeType = interfaceReturnType.ResolveType(resolveTypeParams)\n\t} else {\n\t\truntimeType = defaultResolveTypeFn(resolveTypeParams, returnType)\n\t}\n\n\terr := invariantf(runtimeType != nil, `Abstract type %v must resolve to an Object type at runtime `+\n\t\t`for field %v.%v with value \"%v\", received \"%v\".`, returnType, info.ParentType, info.FieldName, result, runtimeType,\n\t)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tif !eCtx.Schema.IsPossibleType(returnType, runtimeType) {\n\t\tpanic(gqlerrors.NewFormattedError(\n\t\t\tfmt.Sprintf(`Runtime Object type \"%v\" is not a possible type `+\n\t\t\t\t`for \"%v\".`, runtimeType, returnType),\n\t\t))\n\t}\n\n\treturn completeObjectValue(eCtx, runtimeType, fieldASTs, info, path, result)\n}\n\n// completeObjectValue complete an Object value by executing all sub-selections.\nfunc completeObjectValue(eCtx *executionContext, returnType *Object, fieldASTs []*ast.Field, info ResolveInfo, path *ResponsePath, result interface{}) interface{} {\n\n\t// If there is an isTypeOf predicate function, call it with the\n\t// current result. If isTypeOf returns false, then raise an error rather\n\t// than continuing execution.\n\tif returnType.IsTypeOf != nil {\n\t\tp := IsTypeOfParams{\n\t\t\tValue:   result,\n\t\t\tInfo:    info,\n\t\t\tContext: eCtx.Context,\n\t\t}\n\t\tif !returnType.IsTypeOf(p) {\n\t\t\tpanic(gqlerrors.NewFormattedError(\n\t\t\t\tfmt.Sprintf(`Expected value of type \"%v\" but got: %T.`, returnType, result),\n\t\t\t))\n\t\t}\n\t}\n\n\t// Collect sub-fields to execute to complete this value.\n\tsubFieldASTs := map[string][]*ast.Field{}\n\tvisitedFragmentNames := map[string]bool{}\n\tfor _, fieldAST := range fieldASTs {\n\t\tif fieldAST == nil {\n\t\t\tcontinue\n\t\t}\n\t\tselectionSet := fieldAST.SelectionSet\n\t\tif selectionSet != nil {\n\t\t\tinnerParams := collectFieldsParams{\n\t\t\t\tExeContext:           eCtx,\n\t\t\t\tRuntimeType:          returnType,\n\t\t\t\tSelectionSet:         selectionSet,\n\t\t\t\tFields:               subFieldASTs,\n\t\t\t\tVisitedFragmentNames: visitedFragmentNames,\n\t\t\t}\n\t\t\tsubFieldASTs = collectFields(innerParams)\n\t\t}\n\t}\n\texecuteFieldsParams := executeFieldsParams{\n\t\tExecutionContext: eCtx,\n\t\tParentType:       returnType,\n\t\tSource:           result,\n\t\tFields:           subFieldASTs,\n\t\tPath:             path,\n\t}\n\treturn executeSubFields(executeFieldsParams)\n}\n\n// completeLeafValue complete a leaf value (Scalar / Enum) by serializing to a valid value, returning nil if serialization is not possible.\nfunc completeLeafValue(returnType Leaf, result interface{}) interface{} {\n\tserializedResult := returnType.Serialize(result)\n\tif isNullish(serializedResult) {\n\t\treturn nil\n\t}\n\treturn serializedResult\n}\n\n// completeListValue complete a list value by completing each item in the list with the inner type\nfunc completeListValue(eCtx *executionContext, returnType *List, fieldASTs []*ast.Field, info ResolveInfo, path *ResponsePath, result interface{}) interface{} {\n\tresultVal := reflect.ValueOf(result)\n\tif resultVal.Kind() == reflect.Ptr {\n\t\tresultVal = resultVal.Elem()\n\t}\n\tparentTypeName := \"\"\n\tif info.ParentType != nil {\n\t\tparentTypeName = info.ParentType.Name()\n\t}\n\terr := invariantf(\n\t\tresultVal.IsValid() && isIterable(result),\n\t\t\"User Error: expected iterable, but did not find one \"+\n\t\t\t\"for field %v.%v.\", parentTypeName, info.FieldName)\n\n\tif err != nil {\n\t\tpanic(gqlerrors.FormatError(err))\n\t}\n\n\titemType := returnType.OfType\n\tcompletedResults := make([]interface{}, 0, resultVal.Len())\n\tfor i := 0; i < resultVal.Len(); i++ {\n\t\tval := resultVal.Index(i).Interface()\n\t\tfieldPath := path.WithKey(i)\n\t\tcompletedItem := completeValueCatchingError(eCtx, itemType, fieldASTs, info, fieldPath, val)\n\t\tcompletedResults = append(completedResults, completedItem)\n\t}\n\treturn completedResults\n}\n\n// defaultResolveTypeFn If a resolveType function is not given, then a default resolve behavior is\n// used which tests each possible type for the abstract type by calling\n// isTypeOf for the object being coerced, returning the first type that matches.\nfunc defaultResolveTypeFn(p ResolveTypeParams, abstractType Abstract) *Object {\n\tpossibleTypes := p.Info.Schema.PossibleTypes(abstractType)\n\tfor _, possibleType := range possibleTypes {\n\t\tif possibleType.IsTypeOf == nil {\n\t\t\tcontinue\n\t\t}\n\t\tisTypeOfParams := IsTypeOfParams{\n\t\t\tValue:   p.Value,\n\t\t\tInfo:    p.Info,\n\t\t\tContext: p.Context,\n\t\t}\n\t\tif res := possibleType.IsTypeOf(isTypeOfParams); res {\n\t\t\treturn possibleType\n\t\t}\n\t}\n\treturn nil\n}\n\n// FieldResolver is used in DefaultResolveFn when the the source value implements this interface.\ntype FieldResolver interface {\n\t// Resolve resolves the value for the given ResolveParams. It has the same semantics as FieldResolveFn.\n\tResolve(p ResolveParams) (interface{}, error)\n}\n\n// DefaultResolveFn If a resolve function is not given, then a default resolve behavior is used\n// which takes the property of the source object of the same name as the field\n// and returns it as the result, or if it's a function, returns the result\n// of calling that function.\nfunc DefaultResolveFn(p ResolveParams) (interface{}, error) {\n\tsourceVal := reflect.ValueOf(p.Source)\n\t// Check if value implements 'Resolver' interface\n\tif resolver, ok := sourceVal.Interface().(FieldResolver); ok {\n\t\treturn resolver.Resolve(p)\n\t}\n\n\t// try to resolve p.Source as a struct\n\tif sourceVal.IsValid() && sourceVal.Type().Kind() == reflect.Ptr {\n\t\tsourceVal = sourceVal.Elem()\n\t}\n\tif !sourceVal.IsValid() {\n\t\treturn nil, nil\n\t}\n\n\tif sourceVal.Type().Kind() == reflect.Struct {\n\t\tfor i := 0; i < sourceVal.NumField(); i++ {\n\t\t\tvalueField := sourceVal.Field(i)\n\t\t\ttypeField := sourceVal.Type().Field(i)\n\t\t\t// try matching the field name first\n\t\t\tif strings.EqualFold(typeField.Name, p.Info.FieldName) {\n\t\t\t\treturn valueField.Interface(), nil\n\t\t\t}\n\t\t\ttag := typeField.Tag\n\t\t\tcheckTag := func(tagName string) bool {\n\t\t\t\tt := tag.Get(tagName)\n\t\t\t\ttOptions := strings.Split(t, \",\")\n\t\t\t\tif len(tOptions) == 0 {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif tOptions[0] != p.Info.FieldName {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif checkTag(\"json\") || checkTag(\"graphql\") {\n\t\t\t\treturn valueField.Interface(), nil\n\t\t\t} else {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\treturn nil, nil\n\t}\n\n\t// try p.Source as a map[string]interface\n\tif sourceMap, ok := p.Source.(map[string]interface{}); ok {\n\t\tproperty := sourceMap[p.Info.FieldName]\n\t\tval := reflect.ValueOf(property)\n\t\tif val.IsValid() && val.Type().Kind() == reflect.Func {\n\t\t\t// try type casting the func to the most basic func signature\n\t\t\t// for more complex signatures, user have to define ResolveFn\n\t\t\tif propertyFn, ok := property.(func() interface{}); ok {\n\t\t\t\treturn propertyFn(), nil\n\t\t\t}\n\t\t}\n\t\treturn property, nil\n\t}\n\n\t// Try accessing as map via reflection\n\tif r := reflect.ValueOf(p.Source); r.Kind() == reflect.Map && r.Type().Key().Kind() == reflect.String {\n\t\tval := r.MapIndex(reflect.ValueOf(p.Info.FieldName))\n\t\tif val.IsValid() {\n\t\t\tproperty := val.Interface()\n\t\t\tif val.Type().Kind() == reflect.Func {\n\t\t\t\t// try type casting the func to the most basic func signature\n\t\t\t\t// for more complex signatures, user have to define ResolveFn\n\t\t\t\tif propertyFn, ok := property.(func() interface{}); ok {\n\t\t\t\t\treturn propertyFn(), nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn property, nil\n\t\t}\n\t}\n\n\t// last resort, return nil\n\treturn nil, nil\n}\n\n// This method looks up the field on the given type definition.\n// It has special casing for the two introspection fields, __schema\n// and __typename. __typename is special because it can always be\n// queried as a field, even in situations where no other fields\n// are allowed, like on a Union. __schema could get automatically\n// added to the query type, but that would require mutating type\n// definitions, which would cause issues.\nfunc getFieldDef(schema Schema, parentType *Object, fieldName string) *FieldDefinition {\n\n\tif parentType == nil {\n\t\treturn nil\n\t}\n\n\tif fieldName == SchemaMetaFieldDef.Name &&\n\t\tschema.QueryType() == parentType {\n\t\treturn SchemaMetaFieldDef\n\t}\n\tif fieldName == TypeMetaFieldDef.Name &&\n\t\tschema.QueryType() == parentType {\n\t\treturn TypeMetaFieldDef\n\t}\n\tif fieldName == TypeNameMetaFieldDef.Name {\n\t\treturn TypeNameMetaFieldDef\n\t}\n\treturn parentType.Fields()[fieldName]\n}\n\n// contains field information that will be placed in an ordered slice\ntype orderedField struct {\n\tresponseName string\n\tfieldASTs    []*ast.Field\n}\n\n// orders fields from a fields map by location in the source\nfunc orderedFields(fields map[string][]*ast.Field) []*orderedField {\n\torderedFields := []*orderedField{}\n\tfieldMap := map[int]*orderedField{}\n\tstartLocs := []int{}\n\n\tfor responseName, fieldASTs := range fields {\n\t\t// find the lowest location in the current fieldASTs\n\t\tlowest := -1\n\t\tfor _, fieldAST := range fieldASTs {\n\t\t\tloc := fieldAST.GetLoc().Start\n\t\t\tif lowest == -1 || loc < lowest {\n\t\t\t\tlowest = loc\n\t\t\t}\n\t\t}\n\t\tstartLocs = append(startLocs, lowest)\n\t\tfieldMap[lowest] = &orderedField{\n\t\t\tresponseName: responseName,\n\t\t\tfieldASTs:    fieldASTs,\n\t\t}\n\t}\n\n\tsort.Ints(startLocs)\n\tfor _, startLoc := range startLocs {\n\t\torderedFields = append(orderedFields, fieldMap[startLoc])\n\t}\n\n\treturn orderedFields\n}\n"
  },
  {
    "path": "executor_resolve_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"encoding/json\"\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/testutil\"\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc testSchema(t *testing.T, testField *graphql.Field) graphql.Schema {\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"test\": testField,\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Invalid schema: %v\", err)\n\t}\n\treturn schema\n}\n\nfunc TestExecutesResolveFunction_DefaultFunctionAccessesProperties(t *testing.T) {\n\tschema := testSchema(t, &graphql.Field{Type: graphql.String})\n\n\tsource := map[string]interface{}{\n\t\t\"test\": \"testValue\",\n\t}\n\n\texpected := map[string]interface{}{\n\t\t\"test\": \"testValue\",\n\t}\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test }`,\n\t\tRootObject:    source,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n}\n\nfunc TestExecutesResolveFunction_DefaultFunctionCallsMethods(t *testing.T) {\n\tschema := testSchema(t, &graphql.Field{Type: graphql.String})\n\n\tsource := map[string]interface{}{\n\t\t\"test\": func() interface{} {\n\t\t\treturn \"testValue\"\n\t\t},\n\t}\n\n\texpected := map[string]interface{}{\n\t\t\"test\": \"testValue\",\n\t}\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test }`,\n\t\tRootObject:    source,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n}\n\nfunc TestExecutesResolveFunction_UsesProvidedResolveFunction(t *testing.T) {\n\tschema := testSchema(t, &graphql.Field{\n\t\tType: graphql.String,\n\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\"aStr\": &graphql.ArgumentConfig{Type: graphql.String},\n\t\t\t\"aInt\": &graphql.ArgumentConfig{Type: graphql.Int},\n\t\t},\n\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\tb, err := json.Marshal(p.Args)\n\t\t\treturn string(b), err\n\t\t},\n\t})\n\n\texpected := map[string]interface{}{\n\t\t\"test\": \"{}\",\n\t}\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test }`,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n\n\texpected = map[string]interface{}{\n\t\t\"test\": `{\"aStr\":\"String!\"}`,\n\t}\n\tresult = graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test(aStr: \"String!\") }`,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n\n\texpected = map[string]interface{}{\n\t\t\"test\": `{\"aInt\":-123,\"aStr\":\"String!\"}`,\n\t}\n\tresult = graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test(aInt: -123, aStr: \"String!\") }`,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n}\n\nfunc TestExecutesResolveFunction_UsesProvidedResolveFunction_SourceIsStruct_WithoutJSONTags(t *testing.T) {\n\n\t// For structs without JSON tags, it will map to upper-cased exported field names\n\ttype SubObjectWithoutJSONTags struct {\n\t\tStr string\n\t\tInt int\n\t}\n\n\tschema := testSchema(t, &graphql.Field{\n\t\tType: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName:        \"SubObject\",\n\t\t\tDescription: \"Maps GraphQL Object `SubObject` to Go struct `SubObjectWithoutJSONTags`\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"Str\": &graphql.Field{Type: graphql.String},\n\t\t\t\t\"Int\": &graphql.Field{Type: graphql.Int},\n\t\t\t},\n\t\t}),\n\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\"aStr\": &graphql.ArgumentConfig{Type: graphql.String},\n\t\t\t\"aInt\": &graphql.ArgumentConfig{Type: graphql.Int},\n\t\t},\n\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\taStr, _ := p.Args[\"aStr\"].(string)\n\t\t\taInt, _ := p.Args[\"aInt\"].(int)\n\t\t\treturn &SubObjectWithoutJSONTags{\n\t\t\t\tStr: aStr,\n\t\t\t\tInt: aInt,\n\t\t\t}, nil\n\t\t},\n\t})\n\n\texpected := map[string]interface{}{\n\t\t\"test\": map[string]interface{}{\n\t\t\t\"Str\": \"\",\n\t\t\t\"Int\": 0,\n\t\t},\n\t}\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test { Str, Int } }`,\n\t})\n\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n\n\texpected = map[string]interface{}{\n\t\t\"test\": map[string]interface{}{\n\t\t\t\"Str\": \"String!\",\n\t\t\t\"Int\": 0,\n\t\t},\n\t}\n\tresult = graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test(aStr: \"String!\") { Str, Int } }`,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n\n\texpected = map[string]interface{}{\n\t\t\"test\": map[string]interface{}{\n\t\t\t\"Str\": \"String!\",\n\t\t\t\"Int\": -123,\n\t\t},\n\t}\n\tresult = graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test(aInt: -123, aStr: \"String!\") { Str, Int } }`,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n}\n\nfunc TestExecutesResolveFunction_UsesProvidedResolveFunction_SourceIsStruct_WithJSONTags(t *testing.T) {\n\n\t// For structs without JSON tags, it will map to upper-cased exported field names\n\ttype SubObjectWithJSONTags struct {\n\t\tOtherField string `json:\"\"`\n\t\tStr        string `json:\"str\"`\n\t\tInt        int    `json:\"int\"`\n\t}\n\n\tschema := testSchema(t, &graphql.Field{\n\t\tType: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName:        \"SubObject\",\n\t\t\tDescription: \"Maps GraphQL Object `SubObject` to Go struct `SubObjectWithJSONTags`\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"str\": &graphql.Field{Type: graphql.String},\n\t\t\t\t\"int\": &graphql.Field{Type: graphql.Int},\n\t\t\t},\n\t\t}),\n\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\"aStr\": &graphql.ArgumentConfig{Type: graphql.String},\n\t\t\t\"aInt\": &graphql.ArgumentConfig{Type: graphql.Int},\n\t\t},\n\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\taStr, _ := p.Args[\"aStr\"].(string)\n\t\t\taInt, _ := p.Args[\"aInt\"].(int)\n\t\t\treturn &SubObjectWithJSONTags{\n\t\t\t\tStr: aStr,\n\t\t\t\tInt: aInt,\n\t\t\t}, nil\n\t\t},\n\t})\n\n\texpected := map[string]interface{}{\n\t\t\"test\": map[string]interface{}{\n\t\t\t\"str\": \"\",\n\t\t\t\"int\": 0,\n\t\t},\n\t}\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test { str, int } }`,\n\t})\n\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n\n\texpected = map[string]interface{}{\n\t\t\"test\": map[string]interface{}{\n\t\t\t\"str\": \"String!\",\n\t\t\t\"int\": 0,\n\t\t},\n\t}\n\tresult = graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test(aStr: \"String!\") { str, int } }`,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n\n\texpected = map[string]interface{}{\n\t\t\"test\": map[string]interface{}{\n\t\t\t\"str\": \"String!\",\n\t\t\t\"int\": -123,\n\t\t},\n\t}\n\tresult = graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: `{ test(aInt: -123, aStr: \"String!\") { str, int } }`,\n\t})\n\tif !reflect.DeepEqual(expected, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result.Data))\n\t}\n}\n"
  },
  {
    "path": "executor_schema_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\n// TODO: have a separate package for other tests for eg `parser`\n// maybe for:\n// - tests that supposed to be black-boxed (no reason to access private identifiers)\n// - tests that create internal tests structs, we might not want to pollute the package with too many test structs\n\ntype testPic struct {\n\tUrl    string `json:\"url\"`\n\tWidth  string `json:\"width\"`\n\tHeight string `json:\"height\"`\n}\n\ntype testPicFn func(width, height string) *testPic\n\ntype testAuthor struct {\n\tId            int          `json:\"id\"`\n\tName          string       `json:\"name\"`\n\tPic           testPicFn    `json:\"pic\"`\n\tRecentArticle *testArticle `json:\"recentArticle\"`\n}\ntype testArticle struct {\n\tId          string        `json:\"id\"`\n\tIsPublished string        `json:\"isPublished\"`\n\tAuthor      *testAuthor   `json:\"author\"`\n\tTitle       string        `json:\"title\"`\n\tBody        string        `json:\"body\"`\n\tHidden      string        `json:\"hidden\"`\n\tKeywords    []interface{} `json:\"keywords\"`\n}\n\nfunc getPic(id int, width, height string) *testPic {\n\treturn &testPic{\n\t\tUrl:    fmt.Sprintf(\"cdn://%v\", id),\n\t\tWidth:  width,\n\t\tHeight: height,\n\t}\n}\n\nvar johnSmith *testAuthor\n\nfunc article(id interface{}) *testArticle {\n\treturn &testArticle{\n\t\tId:          fmt.Sprintf(\"%v\", id),\n\t\tIsPublished: \"true\",\n\t\tAuthor:      johnSmith,\n\t\tTitle:       fmt.Sprintf(\"My Article %v\", id),\n\t\tBody:        \"This is a post\",\n\t\tHidden:      \"This data is not exposed in the schema\",\n\t\tKeywords: []interface{}{\n\t\t\t\"foo\", \"bar\", 1, true, nil,\n\t\t},\n\t}\n}\n\nfunc TestExecutesUsingAComplexSchema(t *testing.T) {\n\n\tjohnSmith = &testAuthor{\n\t\tId:   123,\n\t\tName: \"John Smith\",\n\t\tPic: func(width string, height string) *testPic {\n\t\t\treturn getPic(123, width, height)\n\t\t},\n\t\tRecentArticle: article(\"1\"),\n\t}\n\n\tblogImage := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Image\",\n\t\tFields: graphql.Fields{\n\t\t\t\"url\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"width\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t\t\"height\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t})\n\tblogAuthor := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Author\",\n\t\tFields: graphql.Fields{\n\t\t\t\"id\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"pic\": &graphql.Field{\n\t\t\t\tType: blogImage,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"width\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t\t\"height\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif author, ok := p.Source.(*testAuthor); ok {\n\t\t\t\t\t\twidth := fmt.Sprintf(\"%v\", p.Args[\"width\"])\n\t\t\t\t\t\theight := fmt.Sprintf(\"%v\", p.Args[\"height\"])\n\t\t\t\t\t\treturn author.Pic(width, height), nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"recentArticle\": &graphql.Field{},\n\t\t},\n\t})\n\tblogArticle := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Article\",\n\t\tFields: graphql.Fields{\n\t\t\t\"id\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t},\n\t\t\t\"isPublished\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t\t\"author\": &graphql.Field{\n\t\t\t\tType: blogAuthor,\n\t\t\t},\n\t\t\t\"title\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"body\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"keywords\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\n\tblogAuthor.AddFieldConfig(\"recentArticle\", &graphql.Field{\n\t\tType: blogArticle,\n\t})\n\n\tblogQuery := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"article\": &graphql.Field{\n\t\t\t\tType: blogArticle,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.ID,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tid := p.Args[\"id\"]\n\t\t\t\t\treturn article(id), nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"feed\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(blogArticle),\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn []*testArticle{\n\t\t\t\t\t\tarticle(1),\n\t\t\t\t\t\tarticle(2),\n\t\t\t\t\t\tarticle(3),\n\t\t\t\t\t\tarticle(4),\n\t\t\t\t\t\tarticle(5),\n\t\t\t\t\t\tarticle(6),\n\t\t\t\t\t\tarticle(7),\n\t\t\t\t\t\tarticle(8),\n\t\t\t\t\t\tarticle(9),\n\t\t\t\t\t\tarticle(10),\n\t\t\t\t\t}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tblogSchema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: blogQuery,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\trequest := `\n      {\n        feed {\n          id,\n          title\n        },\n        article(id: \"1\") {\n          ...articleFields,\n          author {\n            id,\n            name,\n            pic(width: 640, height: 480) {\n              url,\n              width,\n              height\n            },\n            recentArticle {\n              ...articleFields,\n              keywords\n            }\n          }\n        }\n      }\n\n      fragment articleFields on Article {\n        id,\n        isPublished,\n        title,\n        body,\n        hidden,\n        notdefined\n      }\n\t`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"article\": map[string]interface{}{\n\t\t\t\t\"title\": \"My Article 1\",\n\t\t\t\t\"body\":  \"This is a post\",\n\t\t\t\t\"author\": map[string]interface{}{\n\t\t\t\t\t\"id\":   \"123\",\n\t\t\t\t\t\"name\": \"John Smith\",\n\t\t\t\t\t\"pic\": map[string]interface{}{\n\t\t\t\t\t\t\"url\":    \"cdn://123\",\n\t\t\t\t\t\t\"width\":  640,\n\t\t\t\t\t\t\"height\": 480,\n\t\t\t\t\t},\n\t\t\t\t\t\"recentArticle\": map[string]interface{}{\n\t\t\t\t\t\t\"id\":          \"1\",\n\t\t\t\t\t\t\"isPublished\": bool(true),\n\t\t\t\t\t\t\"title\":       \"My Article 1\",\n\t\t\t\t\t\t\"body\":        \"This is a post\",\n\t\t\t\t\t\t\"keywords\": []interface{}{\n\t\t\t\t\t\t\t\"foo\",\n\t\t\t\t\t\t\t\"bar\",\n\t\t\t\t\t\t\t\"1\",\n\t\t\t\t\t\t\t\"true\",\n\t\t\t\t\t\t\tnil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"id\":          \"1\",\n\t\t\t\t\"isPublished\": bool(true),\n\t\t\t},\n\t\t\t\"feed\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"1\",\n\t\t\t\t\t\"title\": \"My Article 1\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"2\",\n\t\t\t\t\t\"title\": \"My Article 2\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"3\",\n\t\t\t\t\t\"title\": \"My Article 3\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"4\",\n\t\t\t\t\t\"title\": \"My Article 4\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"5\",\n\t\t\t\t\t\"title\": \"My Article 5\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"6\",\n\t\t\t\t\t\"title\": \"My Article 6\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"7\",\n\t\t\t\t\t\"title\": \"My Article 7\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"8\",\n\t\t\t\t\t\"title\": \"My Article 8\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"9\",\n\t\t\t\t\t\"title\": \"My Article 9\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"id\":    \"10\",\n\t\t\t\t\t\"title\": \"My Article 10\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, request)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: blogSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "executor_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestExecutesArbitraryCode(t *testing.T) {\n\n\tdeepData := map[string]interface{}{}\n\tdata := map[string]interface{}{\n\t\t\"a\": func() interface{} { return \"Apple\" },\n\t\t\"b\": func() interface{} { return \"Banana\" },\n\t\t\"c\": func() interface{} { return \"Cookie\" },\n\t\t\"d\": func() interface{} { return \"Donut\" },\n\t\t\"e\": func() interface{} { return \"Egg\" },\n\t\t\"f\": \"Fish\",\n\t\t\"pic\": func(size int) string {\n\t\t\treturn fmt.Sprintf(\"Pic of size: %v\", size)\n\t\t},\n\t\t\"deep\": func() interface{} { return deepData },\n\t}\n\tdata[\"promise\"] = func() interface{} {\n\t\treturn data\n\t}\n\tdeepData = map[string]interface{}{\n\t\t\"a\":      func() interface{} { return \"Already Been Done\" },\n\t\t\"b\":      func() interface{} { return \"Boring\" },\n\t\t\"c\":      func() interface{} { return []string{\"Contrived\", \"\", \"Confusing\"} },\n\t\t\"deeper\": func() interface{} { return []interface{}{data, nil, data} },\n\t}\n\n\tquery := `\n      query Example($size: Int) {\n        a,\n        b,\n        x: c\n        ...c\n        f\n        ...on DataType {\n          pic(size: $size)\n          promise {\n            a\n          }\n        }\n        deep {\n          a\n          b\n          c\n          deeper {\n            a\n            b\n          }\n        }\n      }\n\n      fragment c on DataType {\n        d\n        e\n      }\n    `\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"b\": \"Banana\",\n\t\t\t\"x\": \"Cookie\",\n\t\t\t\"d\": \"Donut\",\n\t\t\t\"e\": \"Egg\",\n\t\t\t\"promise\": map[string]interface{}{\n\t\t\t\t\"a\": \"Apple\",\n\t\t\t},\n\t\t\t\"a\": \"Apple\",\n\t\t\t\"deep\": map[string]interface{}{\n\t\t\t\t\"a\": \"Already Been Done\",\n\t\t\t\t\"b\": \"Boring\",\n\t\t\t\t\"c\": []interface{}{\n\t\t\t\t\t\"Contrived\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Confusing\",\n\t\t\t\t},\n\t\t\t\t\"deeper\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"a\": \"Apple\",\n\t\t\t\t\t\t\"b\": \"Banana\",\n\t\t\t\t\t},\n\t\t\t\t\tnil,\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"a\": \"Apple\",\n\t\t\t\t\t\t\"b\": \"Banana\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"f\":   \"Fish\",\n\t\t\t\"pic\": \"Pic of size: 100\",\n\t\t},\n\t}\n\n\t// Schema Definitions\n\tpicResolverFn := func(p graphql.ResolveParams) (interface{}, error) {\n\t\t// get and type assert ResolveFn for this field\n\t\tpicResolver, ok := p.Source.(map[string]interface{})[\"pic\"].(func(size int) string)\n\t\tif !ok {\n\t\t\treturn nil, nil\n\t\t}\n\t\t// get and type assert argument\n\t\tsizeArg, ok := p.Args[\"size\"].(int)\n\t\tif !ok {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn picResolver(sizeArg), nil\n\t}\n\tdataType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"DataType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"b\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"c\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"d\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"e\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"pic\": &graphql.Field{\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"size\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tType:    graphql.String,\n\t\t\t\tResolve: picResolverFn,\n\t\t\t},\n\t\t},\n\t})\n\tdeepDataType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"DeepDataType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"b\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"c\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(graphql.String),\n\t\t\t},\n\t\t\t\"deeper\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(dataType),\n\t\t\t},\n\t\t},\n\t})\n\n\t// Exploring a way to have a Object within itself\n\t// in this case DataType has DeepDataType has DataType\n\tdataType.AddFieldConfig(\"deep\", &graphql.Field{\n\t\tType: deepDataType,\n\t})\n\t// in this case DataType has DataType\n\tdataType.AddFieldConfig(\"promise\", &graphql.Field{\n\t\tType: dataType,\n\t})\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: dataType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tastDoc := testutil.TestParse(t, query)\n\n\t// execute\n\targs := map[string]interface{}{\n\t\t\"size\": 100,\n\t}\n\toperationName := \"Example\"\n\tep := graphql.ExecuteParams{\n\t\tSchema:        schema,\n\t\tRoot:          data,\n\t\tAST:           astDoc,\n\t\tOperationName: operationName,\n\t\tArgs:          args,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestMergesParallelFragments(t *testing.T) {\n\n\tquery := `\n      { a, ...FragOne, ...FragTwo }\n\n      fragment FragOne on Type {\n        b\n        deep { b, deeper: deep { b } }\n      }\n\n      fragment FragTwo on Type {\n        c\n        deep { c, deeper: deep { c } }\n      }\n    `\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"Apple\",\n\t\t\t\"b\": \"Banana\",\n\t\t\t\"deep\": map[string]interface{}{\n\t\t\t\t\"c\": \"Cherry\",\n\t\t\t\t\"b\": \"Banana\",\n\t\t\t\t\"deeper\": map[string]interface{}{\n\t\t\t\t\t\"b\": \"Banana\",\n\t\t\t\t\t\"c\": \"Cherry\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"c\": \"Cherry\",\n\t\t},\n\t}\n\n\ttypeObjectType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Type\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn \"Apple\", nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"b\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn \"Banana\", nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"c\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn \"Cherry\", nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tdeepTypeFieldConfig := &graphql.Field{\n\t\tType: typeObjectType,\n\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn p.Source, nil\n\t\t},\n\t}\n\ttypeObjectType.AddFieldConfig(\"deep\", deepTypeFieldConfig)\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: typeObjectType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\ntype CustomMap map[string]interface{}\n\nfunc TestCustomMapType(t *testing.T) {\n\tquery := `\n\t\tquery Example { data { a } }\n\t`\n\tdata := CustomMap{\n\t\t\"a\": \"1\",\n\t\t\"b\": \"2\",\n\t}\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"RootQuery\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"data\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewObject(graphql.ObjectConfig{\n\t\t\t\t\t\tName: \"Data\",\n\t\t\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"b\": &graphql.Field{\n\t\t\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn data, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\tresult := testutil.TestExecute(t, graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tRoot:   data,\n\t\tAST:    testutil.TestParse(t, query),\n\t})\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\n\texpected := map[string]interface{}{\n\t\t\"data\": map[string]interface{}{\n\t\t\t\"a\": \"1\",\n\t\t},\n\t}\n\tif !reflect.DeepEqual(result.Data, expected) {\n\t\tt.Fatalf(\"Expected context.key to equal %v, got %v\", expected, result.Data)\n\t}\n}\n\nfunc TestThreadsSourceCorrectly(t *testing.T) {\n\n\tquery := `\n      query Example { a }\n    `\n\n\tdata := map[string]interface{}{\n\t\t\"key\": \"value\",\n\t}\n\n\tvar resolvedSource map[string]interface{}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\tresolvedSource = p.Source.(map[string]interface{})\n\t\t\t\t\t\treturn resolvedSource, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tRoot:   data,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\n\texpected := \"value\"\n\tif resolvedSource[\"key\"] != expected {\n\t\tt.Fatalf(\"Expected context.key to equal %v, got %v\", expected, resolvedSource[\"key\"])\n\t}\n}\n\nfunc TestCorrectlyThreadsArguments(t *testing.T) {\n\n\tquery := `\n      query Example {\n        b(numArg: 123, stringArg: \"foo\")\n      }\n    `\n\n\tvar resolvedArgs map[string]interface{}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"b\": &graphql.Field{\n\t\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\t\"numArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"stringArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\tresolvedArgs = p.Args\n\t\t\t\t\t\treturn resolvedArgs, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\n\texpectedNum := 123\n\texpectedString := \"foo\"\n\tif resolvedArgs[\"numArg\"] != expectedNum {\n\t\tt.Fatalf(\"Expected args.numArg to equal `%v`, got `%v`\", expectedNum, resolvedArgs[\"numArg\"])\n\t}\n\tif resolvedArgs[\"stringArg\"] != expectedString {\n\t\tt.Fatalf(\"Expected args.stringArg to equal `%v`, got `%v`\", expectedNum, resolvedArgs[\"stringArg\"])\n\t}\n}\n\nfunc TestThreadsRootValueContextCorrectly(t *testing.T) {\n\n\tquery := `\n      query Example { a }\n    `\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\tval, _ := p.Info.RootValue.(map[string]interface{})[\"stringKey\"].(string)\n\t\t\t\t\t\treturn val, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot: map[string]interface{}{\n\t\t\t\"stringKey\": \"stringValue\",\n\t\t},\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"stringValue\",\n\t\t},\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestThreadsContextCorrectly(t *testing.T) {\n\n\tquery := `\n      query Example { a }\n    `\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn p.Context.Value(\"foo\"), nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema:  schema,\n\t\tAST:     ast,\n\t\tContext: context.WithValue(context.Background(), \"foo\", \"bar\"),\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"bar\",\n\t\t},\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestNullsOutErrorSubtrees(t *testing.T) {\n\n\t// TODO: TestNullsOutErrorSubtrees test for go-routines if implemented\n\tquery := `{\n      sync,\n      syncError,\n    }`\n\n\texpectedData := map[string]interface{}{\n\t\t\"sync\":      \"sync\",\n\t\t\"syncError\": nil,\n\t}\n\texpectedErrors := []gqlerrors.FormattedError{{\n\t\tMessage: \"Error getting syncError\",\n\t\tLocations: []location.SourceLocation{\n\t\t\t{\n\t\t\t\tLine: 3, Column: 7,\n\t\t\t},\n\t\t},\n\t\tPath: []interface{}{\n\t\t\t\"syncError\",\n\t\t},\n\t},\n\t}\n\n\tdata := map[string]interface{}{\n\t\t\"sync\": func() interface{} {\n\t\t\treturn \"sync\"\n\t\t},\n\t\t\"syncError\": func() interface{} {\n\t\t\tpanic(\"Error getting syncError\")\n\t\t},\n\t}\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"sync\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"syncError\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot:   data,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !reflect.DeepEqual(expectedData, result.Data) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedData, result.Data))\n\t}\n\tif !testutil.EqualFormattedErrors(expectedErrors, result.Errors) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedErrors, result.Errors))\n\t}\n}\n\nfunc TestUsesTheInlineOperationIfNoOperationNameIsProvided(t *testing.T) {\n\n\tdoc := `{ a }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"b\",\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot:   data,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestUsesTheOnlyOperationIfNoOperationNameIsProvided(t *testing.T) {\n\n\tdoc := `query Example { a }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"b\",\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot:   data,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestUsesTheNamedOperationIfOperationNameIsProvided(t *testing.T) {\n\n\tdoc := `query Example { first: a } query OtherExample { second: a }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"second\": \"b\",\n\t\t},\n\t}\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema:        schema,\n\t\tAST:           ast,\n\t\tRoot:          data,\n\t\tOperationName: \"OtherExample\",\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestThrowsIfNoOperationIsProvided(t *testing.T) {\n\n\tdoc := `fragment Example on Type { a }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t}\n\n\texpectedErrors := []gqlerrors.FormattedError{\n\t\t{\n\t\t\tMessage:   \"Must provide an operation.\",\n\t\t\tLocations: []location.SourceLocation{},\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot:   data,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif result.Data != nil {\n\t\tt.Fatalf(\"wrong result, expected nil result.Data, got %v\", result.Data)\n\t}\n\tif !testutil.EqualFormattedErrors(expectedErrors, result.Errors) {\n\t\tt.Fatalf(\"unexpected result, Diff: %v\", testutil.Diff(expectedErrors, result.Errors))\n\t}\n}\nfunc TestThrowsIfNoOperationNameIsProvidedWithMultipleOperations(t *testing.T) {\n\n\tdoc := `query Example { a } query OtherExample { a }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t}\n\n\texpectedErrors := []gqlerrors.FormattedError{\n\t\t{\n\t\t\tMessage:   \"Must provide operation name if query contains multiple operations.\",\n\t\t\tLocations: []location.SourceLocation{},\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot:   data,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif result.Data != nil {\n\t\tt.Fatalf(\"wrong result, expected nil result.Data, got %v\", result.Data)\n\t}\n\tif !testutil.EqualFormattedErrors(expectedErrors, result.Errors) {\n\t\tt.Fatalf(\"unexpected result, Diff: %v\", testutil.Diff(expectedErrors, result.Errors))\n\t}\n}\n\nfunc TestThrowsIfUnknownOperationNameIsProvided(t *testing.T) {\n\n\tdoc := `query Example { a } query OtherExample { a }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t}\n\n\texpectedErrors := []gqlerrors.FormattedError{\n\t\t{\n\t\t\tMessage:   `Unknown operation named \"UnknownExample\".`,\n\t\t\tLocations: []location.SourceLocation{},\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema:        schema,\n\t\tAST:           ast,\n\t\tRoot:          data,\n\t\tOperationName: \"UnknownExample\",\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif result.Data != nil {\n\t\tt.Fatalf(\"wrong result, expected nil result.Data, got %v\", result.Data)\n\t}\n\tif !testutil.EqualFormattedErrors(expectedErrors, result.Errors) {\n\t\tt.Fatalf(\"unexpected result, Diff: %v\", testutil.Diff(expectedErrors, result.Errors))\n\t}\n}\n\nfunc TestThrowsIfOperationTypeIsUnsupported(t *testing.T) {\n\tquery := `mutation Mut { a } subscription Sub { a }`\n\toperations := []string{\"Mut\", \"Sub\"}\n\n\texpectedErrors := [][]gqlerrors.FormattedError{\n\t\t{{\n\t\t\tMessage:   `Schema is not configured for mutations`,\n\t\t\tLocations: []location.SourceLocation{{Line: 1, Column: 1}},\n\t\t}},\n\t\t{{\n\t\t\tMessage:   `Schema is not configured for subscriptions`,\n\t\t\tLocations: []location.SourceLocation{{Line: 1, Column: 20}},\n\t\t}},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\tfor opIndex, operation := range operations {\n\t\texpectedErrors := expectedErrors[opIndex]\n\n\t\t// execute\n\t\tep := graphql.ExecuteParams{\n\t\t\tSchema:        schema,\n\t\t\tAST:           ast,\n\t\t\tOperationName: operation,\n\t\t}\n\t\tresult := testutil.TestExecute(t, ep)\n\t\tif result.Data != nil {\n\t\t\tt.Fatalf(\"wrong result, expected nil result.Data, got %v\", result.Data)\n\t\t}\n\t\tif !testutil.EqualFormattedErrors(expectedErrors, result.Errors) {\n\t\t\tt.Fatalf(\"unexpected result, Diff: %v\", testutil.Diff(expectedErrors, result.Errors))\n\t\t}\n\t}\n}\nfunc TestUsesTheQuerySchemaForQueries(t *testing.T) {\n\n\tdoc := `query Q { a } mutation M { c } subscription S { a }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t\t\"c\": \"d\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"b\",\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Q\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tMutation: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"M\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"c\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tSubscription: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"S\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema:        schema,\n\t\tAST:           ast,\n\t\tRoot:          data,\n\t\tOperationName: \"Q\",\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestUsesTheMutationSchemaForMutations(t *testing.T) {\n\n\tdoc := `query Q { a } mutation M { c }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t\t\"c\": \"d\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"c\": \"d\",\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Q\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tMutation: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"M\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"c\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema:        schema,\n\t\tAST:           ast,\n\t\tRoot:          data,\n\t\tOperationName: \"M\",\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestUsesTheSubscriptionSchemaForSubscriptions(t *testing.T) {\n\n\tdoc := `query Q { a } subscription S { a }`\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t\t\"c\": \"d\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"b\",\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Q\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tSubscription: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"S\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema:        schema,\n\t\tAST:           ast,\n\t\tRoot:          data,\n\t\tOperationName: \"S\",\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestCorrectFieldOrderingDespiteExecutionOrder(t *testing.T) {\n\n\tdoc := `\n\t{\n      b,\n      a,\n      c,\n      d,\n      e\n    }\n\t`\n\tdata := map[string]interface{}{\n\t\t\"a\": func() interface{} { return \"a\" },\n\t\t\"b\": func() interface{} { return \"b\" },\n\t\t\"c\": func() interface{} { return \"c\" },\n\t\t\"d\": func() interface{} { return \"d\" },\n\t\t\"e\": func() interface{} { return \"e\" },\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"a\",\n\t\t\t\"b\": \"b\",\n\t\t\t\"c\": \"c\",\n\t\t\t\"d\": \"d\",\n\t\t\t\"e\": \"e\",\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"b\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"c\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"d\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"e\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot:   data,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n\n\t// TODO: test to ensure key ordering\n\t// The following does not work\n\t// - iterating over result.Data map\n\t//   Note that golang's map iteration order is randomized\n\t//   So, iterating over result.Data won't do it for a test\n\t// - Marshal the result.Data to json string and assert it\n\t//   json.Marshal seems to re-sort the keys automatically\n\t//\n\tt.Skipf(\"TODO: Ensure key ordering\")\n}\n\nfunc TestAvoidsRecursion(t *testing.T) {\n\n\tdoc := `\n      query Q {\n        a\n        ...Frag\n        ...Frag\n      }\n\n      fragment Frag on Type {\n        a,\n        ...Frag\n      }\n    `\n\tdata := map[string]interface{}{\n\t\t\"a\": \"b\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"b\",\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema:        schema,\n\t\tAST:           ast,\n\t\tRoot:          data,\n\t\tOperationName: \"Q\",\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n\n}\n\nfunc TestDoesNotIncludeIllegalFieldsInOutput(t *testing.T) {\n\n\tdoc := `mutation M {\n      thisIsIllegalDontIncludeMe\n    }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Q\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tMutation: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"M\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"c\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, expected len(%v) errors, got len(%v)\", len(expected.Errors), len(result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestDoesNotIncludeArgumentsThatWereNotSet(t *testing.T) {\n\n\tdoc := `{ field(a: true, c: false, e: 0) }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"field\": `{\"a\":true,\"c\":false,\"e\":0}`,\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"field\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\t\"a\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"b\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"c\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"d\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"e\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\targs, _ := json.Marshal(p.Args)\n\t\t\t\t\t\treturn string(args), nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\ntype testSpecialType struct {\n\tValue string\n}\ntype testNotSpecialType struct {\n\tValue string\n}\n\nfunc TestFailsWhenAnIsTypeOfCheckIsNotMet(t *testing.T) {\n\n\tquery := `{ specials { value } }`\n\n\tdata := map[string]interface{}{\n\t\t\"specials\": []interface{}{\n\t\t\ttestSpecialType{\"foo\"},\n\t\t\ttestNotSpecialType{\"bar\"},\n\t\t},\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"specials\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"value\": \"foo\",\n\t\t\t\t},\n\t\t\t\tnil,\n\t\t\t},\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{{\n\t\t\tMessage: `Expected value of type \"SpecialType\" but got: graphql_test.testNotSpecialType.`,\n\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t{\n\t\t\t\t\tLine:   1,\n\t\t\t\t\tColumn: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tPath: []interface{}{\n\t\t\t\t\"specials\",\n\t\t\t\t1,\n\t\t\t},\n\t\t},\n\t\t},\n\t}\n\n\tspecialType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SpecialType\",\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\tif _, ok := p.Value.(testSpecialType); ok {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"value\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn p.Source.(testSpecialType).Value, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"specials\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(specialType),\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn p.Source.(map[string]interface{})[\"specials\"], nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot:   data,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestFailsToExecuteQueryContainingATypeDefinition(t *testing.T) {\n\n\tquery := `\n      { foo }\n\n      type Query { foo: String }\n\t`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage:   \"GraphQL cannot execute a request containing a ObjectDefinition\",\n\t\t\t\tLocations: []location.SourceLocation{},\n\t\t\t},\n\t\t},\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"foo\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, query)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestQuery_ExecutionAddsErrorsFromFieldResolveFn(t *testing.T) {\n\tqError := errors.New(\"queryError\")\n\tq := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn nil, qError\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"b\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn \"ok\", nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tblogSchema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: q,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tquery := \"{ a }\"\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        blogSchema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) == 0 {\n\t\tt.Fatal(\"wrong result, expected errors, got no errors\")\n\t}\n\tif result.Errors[0].Error() != qError.Error() {\n\t\tt.Fatalf(\"wrong result, unexpected error, got: %v, expected: %v\", result.Errors[0], qError)\n\t}\n}\n\nfunc TestQuery_ExecutionDoesNotAddErrorsFromFieldResolveFn(t *testing.T) {\n\tqError := errors.New(\"queryError\")\n\tq := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn nil, qError\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"b\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn \"ok\", nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tblogSchema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: q,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tquery := \"{ b }\"\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        blogSchema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %+v\", result.Errors)\n\t}\n}\n\nfunc TestQuery_InputObjectUsesFieldDefaultValueFn(t *testing.T) {\n\tinputType := graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"Input\",\n\t\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\t\"default\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType:         graphql.String,\n\t\t\t\tDefaultValue: \"bar\",\n\t\t\t},\n\t\t},\n\t})\n\tq := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"foo\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.NewNonNull(inputType),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tval := p.Args[\"foo\"].(map[string]interface{})\n\t\t\t\t\tdef, ok := val[\"default\"]\n\t\t\t\t\tif !ok || def == nil {\n\t\t\t\t\t\treturn nil, errors.New(\"queryError: No 'default' param\")\n\t\t\t\t\t}\n\t\t\t\t\tif def.(string) != \"bar\" {\n\t\t\t\t\t\treturn nil, errors.New(\"queryError: 'default' param has wrong value\")\n\t\t\t\t\t}\n\t\t\t\t\treturn \"ok\", nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: q,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tquery := `{ a(foo: {}) }`\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %+v\", result.Errors)\n\t}\n}\n\nfunc TestMutation_ExecutionAddsErrorsFromFieldResolveFn(t *testing.T) {\n\tmError := errors.New(\"mutationError\")\n\tq := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tm := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Mutation\",\n\t\tFields: graphql.Fields{\n\t\t\t\"foo\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"f\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn nil, mError\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"bar\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"b\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn \"ok\", nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery:    q,\n\t\tMutation: m,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tquery := \"mutation _ { newFoo: foo(f:\\\"title\\\") }\"\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) == 0 {\n\t\tt.Fatal(\"wrong result, expected errors, got no errors\")\n\t}\n\tif result.Errors[0].Error() != mError.Error() {\n\t\tt.Fatalf(\"wrong result, unexpected error, got: %v, expected: %v\", result.Errors[0], mError)\n\t}\n}\n\nfunc TestMutation_ExecutionDoesNotAddErrorsFromFieldResolveFn(t *testing.T) {\n\tmError := errors.New(\"mutationError\")\n\tq := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tm := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Mutation\",\n\t\tFields: graphql.Fields{\n\t\t\t\"foo\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"f\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn nil, mError\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"bar\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"b\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn \"ok\", nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery:    q,\n\t\tMutation: m,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tquery := \"mutation _ { newBar: bar(b:\\\"title\\\") }\"\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %+v\", result.Errors)\n\t}\n}\n\nfunc TestGraphqlTag(t *testing.T) {\n\ttypeObjectType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Type\",\n\t\tFields: graphql.Fields{\n\t\t\t\"fooBar\": &graphql.Field{Type: graphql.String},\n\t\t},\n\t})\n\tvar baz = &graphql.Field{\n\t\tType:        typeObjectType,\n\t\tDescription: \"typeObjectType\",\n\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\tt := struct {\n\t\t\t\tFooBar string `graphql:\"fooBar\"`\n\t\t\t}{\"foo bar value\"}\n\t\t\treturn t, nil\n\t\t},\n\t}\n\tq := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"baz\": baz,\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: q,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tquery := \"{ baz { fooBar } }\"\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %+v\", result.Errors)\n\t}\n\texpectedData := map[string]interface{}{\n\t\t\"baz\": map[string]interface{}{\n\t\t\t\"fooBar\": \"foo bar value\",\n\t\t},\n\t}\n\tif !reflect.DeepEqual(result.Data, expectedData) {\n\t\tt.Fatalf(\"unexpected result, got: %+v, expected: %+v\", expectedData, result.Data)\n\t}\n}\n\nfunc TestFieldResolver(t *testing.T) {\n\ttypeObjectType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Type\",\n\t\tFields: graphql.Fields{\n\t\t\t\"fooBar\": &graphql.Field{Type: graphql.String},\n\t\t},\n\t})\n\tvar baz = &graphql.Field{\n\t\tType:        typeObjectType,\n\t\tDescription: \"typeObjectType\",\n\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn testCustomResolver{}, nil\n\t\t},\n\t}\n\tvar bazPtr = &graphql.Field{\n\t\tType:        typeObjectType,\n\t\tDescription: \"typeObjectType\",\n\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn &testCustomResolver{}, nil\n\t\t},\n\t}\n\tq := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"baz\":    baz,\n\t\t\t\"bazPtr\": bazPtr,\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: q,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\tquery := \"{ baz { fooBar }, bazPtr { fooBar } }\"\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %+v\", result.Errors)\n\t}\n\texpectedData := map[string]interface{}{\n\t\t\"baz\": map[string]interface{}{\n\t\t\t\"fooBar\": \"foo bar value\",\n\t\t},\n\t\t\"bazPtr\": map[string]interface{}{\n\t\t\t\"fooBar\": \"foo bar value\",\n\t\t},\n\t}\n\tif !reflect.DeepEqual(result.Data, expectedData) {\n\t\tt.Fatalf(\"unexpected result, got: %+v, expected: %+v\", result.Data, expectedData)\n\t}\n}\n\ntype testCustomResolver struct{}\n\nfunc (r testCustomResolver) Resolve(p graphql.ResolveParams) (interface{}, error) {\n\tif p.Info.FieldName == \"fooBar\" {\n\t\treturn \"foo bar value\", nil\n\t}\n\treturn \"\", errors.New(\"invalid field \" + p.Info.FieldName)\n}\n\nfunc TestContextDeadline(t *testing.T) {\n\ttimeout := time.Millisecond * time.Duration(100)\n\tacceptableDelay := time.Millisecond * time.Duration(10)\n\texpectedErrors := []gqlerrors.FormattedError{\n\t\t{\n\t\t\tMessage:   context.DeadlineExceeded.Error(),\n\t\t\tLocations: []location.SourceLocation{},\n\t\t},\n\t}\n\n\t// Query type includes a field that won't resolve within the deadline\n\tvar queryType = graphql.NewObject(\n\t\tgraphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"hello\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\ttime.Sleep(2 * time.Second)\n\t\t\t\t\t\treturn \"world\", nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\tdefer cancel()\n\n\tstartTime := time.Now()\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: \"{hello}\",\n\t\tContext:       ctx,\n\t})\n\tduration := time.Since(startTime)\n\n\tif duration > timeout+acceptableDelay {\n\t\tt.Fatalf(\"graphql.Do completed in %s, should have completed in %s\", duration, timeout)\n\t}\n\tif !result.HasErrors() || len(result.Errors) == 0 {\n\t\tt.Fatalf(\"Result should include errors when deadline is exceeded\")\n\t}\n\tif !testutil.EqualFormattedErrors(expectedErrors, result.Errors) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedErrors, result.Errors))\n\t}\n}\n\nfunc TestThunkResultsProcessedCorrectly(t *testing.T) {\n\tbarType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Bar\",\n\t\tFields: graphql.Fields{\n\t\t\t\"bazA\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"bazB\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\n\tfooType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Foo\",\n\t\tFields: graphql.Fields{\n\t\t\t\"bar\": &graphql.Field{\n\t\t\t\tType: barType,\n\t\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tvar bar struct {\n\t\t\t\t\t\tBazA string\n\t\t\t\t\t\tBazB string\n\t\t\t\t\t}\n\t\t\t\t\tbar.BazA = \"A\"\n\t\t\t\t\tbar.BazB = \"B\"\n\n\t\t\t\t\tthunk := func() (interface{}, error) { return &bar, nil }\n\t\t\t\t\treturn thunk, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"foo\": &graphql.Field{\n\t\t\t\tType: fooType,\n\t\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tvar foo struct{}\n\t\t\t\t\treturn foo, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\texpectNoError := func(err error) {\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"expected no error, got %v\", err)\n\t\t}\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\texpectNoError(err)\n\n\tquery := \"{ foo { bar { bazA bazB } } }\"\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) != 0 {\n\t\tt.Fatalf(\"expected no errors, got %v\", result.Errors)\n\t}\n\n\tfoo := result.Data.(map[string]interface{})[\"foo\"].(map[string]interface{})\n\tbar, ok := foo[\"bar\"].(map[string]interface{})\n\n\tif !ok {\n\t\tt.Errorf(\"expected bar to be a map[string]interface{}: actual = %v\", reflect.TypeOf(foo[\"bar\"]))\n\t} else {\n\t\tif got, want := bar[\"bazA\"], \"A\"; got != want {\n\t\t\tt.Errorf(\"foo.bar.bazA: got=%v, want=%v\", got, want)\n\t\t}\n\t\tif got, want := bar[\"bazB\"], \"B\"; got != want {\n\t\t\tt.Errorf(\"foo.bar.bazB: got=%v, want=%v\", got, want)\n\t\t}\n\t}\n\n\tif t.Failed() {\n\t\tb, err := json.Marshal(result.Data)\n\t\texpectNoError(err)\n\t\tt.Log(string(b))\n\t}\n}\n\nfunc TestThunkErrorsAreHandledCorrectly(t *testing.T) {\n\tvar bazCError = errors.New(\"barC error\")\n\tbarType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Bar\",\n\t\tFields: graphql.Fields{\n\t\t\t\"bazA\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"bazB\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"bazC\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tthunk := func() (interface{}, error) {\n\t\t\t\t\t\treturn nil, bazCError\n\t\t\t\t\t}\n\t\t\t\t\treturn thunk, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tfooType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Foo\",\n\t\tFields: graphql.Fields{\n\t\t\t\"bar\": &graphql.Field{\n\t\t\t\tType: barType,\n\t\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tvar bar struct {\n\t\t\t\t\t\tBazA string\n\t\t\t\t\t\tBazB string\n\t\t\t\t\t}\n\t\t\t\t\tbar.BazA = \"A\"\n\t\t\t\t\tbar.BazB = \"B\"\n\n\t\t\t\t\tthunk := func() (interface{}, error) {\n\t\t\t\t\t\treturn &bar, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn thunk, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"foo\": &graphql.Field{\n\t\t\t\tType: fooType,\n\t\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tvar foo struct{}\n\t\t\t\t\treturn foo, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error, got: %v\", err)\n\t}\n\n\tquery := \"{ foo { bar { bazA bazB bazC } } }\"\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\tfoo := result.Data.(map[string]interface{})[\"foo\"].(map[string]interface{})\n\tbar, ok := foo[\"bar\"].(map[string]interface{})\n\n\tif !ok {\n\t\tt.Errorf(\"expected bar to be a map[string]interface{}: actual = %v\", reflect.TypeOf(foo[\"bar\"]))\n\t} else {\n\t\tif got, want := bar[\"bazA\"], \"A\"; got != want {\n\t\t\tt.Errorf(\"foo.bar.bazA: got=%v, want=%v\", got, want)\n\t\t}\n\t\tif got, want := bar[\"bazB\"], \"B\"; got != want {\n\t\t\tt.Errorf(\"foo.bar.bazB: got=%v, want=%v\", got, want)\n\t\t}\n\t\tif got := bar[\"bazC\"]; got != nil {\n\t\t\tt.Errorf(\"foo.bar.bazC: got=%v, want=nil\", got)\n\t\t}\n\t\tvar errs = result.Errors\n\t\tif len(errs) != 1 {\n\t\t\tt.Fatalf(\"expected 1 error, got %v\", result.Errors)\n\t\t}\n\t\tif got, want := errs[0].Message, bazCError.Error(); got != want {\n\t\t\tt.Errorf(\"expected error: got=%v, want=%v\", got, want)\n\t\t}\n\t}\n\n\tif t.Failed() {\n\t\tb, err := json.Marshal(result.Data)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\tt.Log(string(b))\n\t}\n}\n\nfunc assertJSON(t *testing.T, expected string, actual interface{}) {\n\tvar e interface{}\n\tif err := json.Unmarshal([]byte(expected), &e); err != nil {\n\t\tt.Fatalf(err.Error())\n\t}\n\taJSON, err := json.MarshalIndent(actual, \"\", \"  \")\n\tif err != nil {\n\t\tt.Fatalf(err.Error())\n\t}\n\tvar a interface{}\n\tif err := json.Unmarshal(aJSON, &a); err != nil {\n\t\tt.Fatalf(err.Error())\n\t}\n\tif !reflect.DeepEqual(e, a) {\n\t\teNormalizedJSON, err := json.MarshalIndent(e, \"\", \"  \")\n\t\tif err != nil {\n\t\t\tt.Fatalf(err.Error())\n\t\t}\n\t\tt.Fatalf(\"Expected JSON:\\n\\n%v\\n\\nActual JSON:\\n\\n%v\", string(eNormalizedJSON), string(aJSON))\n\t}\n}\n\ntype extendedError struct {\n\terror\n\textensions map[string]interface{}\n}\n\nfunc (err extendedError) Extensions() map[string]interface{} {\n\treturn err.extensions\n}\n\nvar _ gqlerrors.ExtendedError = &extendedError{}\n\nfunc testErrors(t *testing.T, nameType graphql.Output, extensions map[string]interface{}, formatErrorFn func(err error) error) *graphql.Result {\n\ttype Hero struct {\n\t\tId      string `graphql:\"id\"`\n\t\tName    string\n\t\tFriends []Hero `graphql:\"friends\"`\n\t}\n\n\tvar heroFields graphql.Fields\n\n\theroType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Hero\",\n\t\tFields: graphql.FieldsThunk(func() graphql.Fields {\n\t\t\treturn heroFields\n\t\t}),\n\t})\n\n\theroFields = graphql.Fields{\n\t\t\"id\": &graphql.Field{\n\t\t\tType: graphql.ID,\n\t\t},\n\t\t\"name\": &graphql.Field{\n\t\t\tType: nameType,\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\thero := p.Source.(Hero)\n\t\t\t\tif hero.Name != \"\" {\n\t\t\t\t\treturn hero.Name, nil\n\t\t\t\t}\n\n\t\t\t\terr := fmt.Errorf(\"Name for character with ID %v could not be fetched.\", hero.Id)\n\t\t\t\tif formatErrorFn != nil {\n\t\t\t\t\terr = formatErrorFn(err)\n\t\t\t\t}\n\n\t\t\t\tif extensions != nil {\n\t\t\t\t\treturn nil, &extendedError{\n\t\t\t\t\t\terror:      err,\n\t\t\t\t\t\textensions: extensions,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn nil, err\n\t\t\t},\n\t\t},\n\t\t\"friends\": &graphql.Field{\n\t\t\tType: graphql.NewList(heroType),\n\t\t},\n\t}\n\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"hero\": &graphql.Field{\n\t\t\t\tType: heroType,\n\t\t\t\tResolve: func(params graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn Hero{\n\t\t\t\t\t\tName: \"R2-D2\",\n\t\t\t\t\t\tFriends: []Hero{\n\t\t\t\t\t\t\t{Id: \"1000\", Name: \"Luke Skywalker\"},\n\t\t\t\t\t\t\t{Id: \"1002\"},\n\t\t\t\t\t\t\t{Id: \"1003\", Name: \"Leia Organa\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\texpectNoError := func(err error) {\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"expected no error, got %v\", err)\n\t\t}\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\texpectNoError(err)\n\n\treturn graphql.Do(graphql.Params{\n\t\tSchema: schema,\n\t\tRequestString: `{\n  hero {\n    name\n    heroFriends: friends {\n      id\n      name\n    }\n  }\n}`,\n\t})\n}\n\n// http://facebook.github.io/graphql/June2018/#example-bc485\nfunc TestQuery_ErrorPath(t *testing.T) {\n\tresult := testErrors(t, graphql.String, nil, nil)\n\n\tassertJSON(t, `{\n\t  \"errors\": [\n\t\t{\n\t\t  \"message\": \"Name for character with ID 1002 could not be fetched.\",\n\t\t  \"locations\": [ { \"line\": 6, \"column\": 7 } ],\n\t\t  \"path\": [ \"hero\", \"heroFriends\", 1, \"name\" ]\n\t\t}\n\t  ],\n\t  \"data\": {\n\t\t\"hero\": {\n\t\t  \"name\": \"R2-D2\",\n\t\t  \"heroFriends\": [\n\t\t\t{\n\t\t\t  \"id\": \"1000\",\n\t\t\t  \"name\": \"Luke Skywalker\"\n\t\t\t},\n\t\t\t{\n\t\t\t  \"id\": \"1002\",\n\t\t\t  \"name\": null\n\t\t\t},\n\t\t\t{\n\t\t\t  \"id\": \"1003\",\n\t\t\t  \"name\": \"Leia Organa\"\n\t\t\t}\n\t\t  ]\n\t\t}\n\t  }\n\t}`, result)\n}\n\n// http://facebook.github.io/graphql/June2018/#example-08b62\nfunc TestQuery_ErrorPathForNonNullField(t *testing.T) {\n\tresult := testErrors(t, graphql.NewNonNull(graphql.String), nil, nil)\n\n\tassertJSON(t, `{\n\t  \"errors\": [\n\t\t{\n\t\t  \"message\": \"Name for character with ID 1002 could not be fetched.\",\n\t\t  \"locations\": [ { \"line\": 6, \"column\": 7 } ],\n\t\t  \"path\": [ \"hero\", \"heroFriends\", 1, \"name\" ]\n\t\t}\n\t  ],\n\t  \"data\": {\n\t\t\"hero\": {\n\t\t  \"name\": \"R2-D2\",\n\t\t  \"heroFriends\": [\n\t\t\t{\n\t\t\t  \"id\": \"1000\",\n\t\t\t  \"name\": \"Luke Skywalker\"\n\t\t\t},\n\t\t\tnull,\n\t\t\t{\n\t\t\t  \"id\": \"1003\",\n\t\t\t  \"name\": \"Leia Organa\"\n\t\t\t}\n\t\t  ]\n\t\t}\n\t  }\n\t}`, result)\n}\n\n// http://facebook.github.io/graphql/June2018/#example-fce18\nfunc TestQuery_ErrorExtensions(t *testing.T) {\n\tresult := testErrors(t, graphql.NewNonNull(graphql.String), map[string]interface{}{\n\t\t\"code\":      \"CAN_NOT_FETCH_BY_ID\",\n\t\t\"timestamp\": \"Fri Feb 9 14:33:09 UTC 2018\",\n\t}, nil)\n\n\tassertJSON(t, `{\n\t  \"errors\": [\n\t\t{\n\t\t  \"message\": \"Name for character with ID 1002 could not be fetched.\",\n\t\t  \"locations\": [ { \"line\": 6, \"column\": 7 } ],\n\t\t  \"path\": [ \"hero\", \"heroFriends\", 1, \"name\" ],\n\t\t  \"extensions\": {\n\t\t\t  \"code\": \"CAN_NOT_FETCH_BY_ID\",\n\t\t\t  \"timestamp\": \"Fri Feb 9 14:33:09 UTC 2018\"\n\t\t  }}\n\t  ],\n\t  \"data\": {\n\t\t\"hero\": {\n\t\t  \"name\": \"R2-D2\",\n\t\t  \"heroFriends\": [\n\t\t\t{\n\t\t\t  \"id\": \"1000\",\n\t\t\t  \"name\": \"Luke Skywalker\"\n\t\t\t},\n\t\t\tnull,\n\t\t\t{\n\t\t\t  \"id\": \"1003\",\n\t\t\t  \"name\": \"Leia Organa\"\n\t\t\t}\n\t\t  ]\n\t\t}\n\t  }\n\t}`, result)\n}\n\nfunc TestQuery_OriginalErrorBuiltin(t *testing.T) {\n\tresult := testErrors(t, graphql.String, nil, nil)\n\tswitch err := result.Errors[0].OriginalError().(type) {\n\tcase *gqlerrors.Error:\n\t\tswitch err := err.OriginalError.(type) {\n\t\tcase error:\n\t\tdefault:\n\t\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t\t}\n\tdefault:\n\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t}\n}\n\nfunc TestQuery_OriginalErrorExtended(t *testing.T) {\n\tresult := testErrors(t, graphql.String, map[string]interface{}{\n\t\t\"code\": \"CAN_NOT_FETCH_BY_ID\",\n\t}, nil)\n\tswitch err := result.Errors[0].OriginalError().(type) {\n\tcase *gqlerrors.Error:\n\t\tswitch err := err.OriginalError.(type) {\n\t\tcase *extendedError:\n\t\tcase extendedError:\n\t\tdefault:\n\t\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t\t}\n\tdefault:\n\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t}\n}\n\ntype customError struct {\n\terror\n}\n\nfunc (e customError) Error() string {\n\treturn e.error.Error()\n}\n\nfunc TestQuery_OriginalErrorCustom(t *testing.T) {\n\tresult := testErrors(t, graphql.String, nil, func(err error) error {\n\t\treturn customError{error: err}\n\t})\n\tswitch err := result.Errors[0].OriginalError().(type) {\n\tcase *gqlerrors.Error:\n\t\tswitch err := err.OriginalError.(type) {\n\t\tcase customError:\n\t\tdefault:\n\t\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t\t}\n\tdefault:\n\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t}\n}\n\nfunc TestQuery_OriginalErrorCustomPtr(t *testing.T) {\n\tresult := testErrors(t, graphql.String, nil, func(err error) error {\n\t\treturn &customError{error: err}\n\t})\n\tswitch err := result.Errors[0].OriginalError().(type) {\n\tcase *gqlerrors.Error:\n\t\tswitch err := err.OriginalError.(type) {\n\t\tcase *customError:\n\t\tdefault:\n\t\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t\t}\n\tdefault:\n\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t}\n}\n\nfunc TestQuery_OriginalErrorPanic(t *testing.T) {\n\tresult := testErrors(t, graphql.String, nil, func(err error) error {\n\t\tpanic(errors.New(\"panic error\"))\n\t})\n\tswitch err := result.Errors[0].OriginalError().(type) {\n\tcase *gqlerrors.Error:\n\t\tswitch err := err.OriginalError.(type) {\n\t\tcase error:\n\t\tdefault:\n\t\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t\t}\n\tdefault:\n\t\tt.Fatalf(\"unexpected error: %v\", reflect.TypeOf(err))\n\t}\n}\n"
  },
  {
    "path": "extensions.go",
    "content": "package graphql\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n)\n\ntype (\n\t// ParseFinishFunc is called when the parse of the query is done\n\tParseFinishFunc func(error)\n\t// parseFinishFuncHandler handles the call of all the ParseFinishFuncs from the extenisons\n\tparseFinishFuncHandler func(error) []gqlerrors.FormattedError\n\n\t// ValidationFinishFunc is called when the Validation of the query is finished\n\tValidationFinishFunc func([]gqlerrors.FormattedError)\n\t// validationFinishFuncHandler responsible for the call of all the ValidationFinishFuncs\n\tvalidationFinishFuncHandler func([]gqlerrors.FormattedError) []gqlerrors.FormattedError\n\n\t// ExecutionFinishFunc is called when the execution is done\n\tExecutionFinishFunc func(*Result)\n\t// executionFinishFuncHandler calls all the ExecutionFinishFuncs from each extension\n\texecutionFinishFuncHandler func(*Result) []gqlerrors.FormattedError\n\n\t// ResolveFieldFinishFunc is called with the result of the ResolveFn and the error it returned\n\tResolveFieldFinishFunc func(interface{}, error)\n\t// resolveFieldFinishFuncHandler calls the resolveFieldFinishFns for all the extensions\n\tresolveFieldFinishFuncHandler func(interface{}, error) []gqlerrors.FormattedError\n)\n\n// Extension is an interface for extensions in graphql\ntype Extension interface {\n\t// Init is used to help you initialize the extension\n\tInit(context.Context, *Params) context.Context\n\n\t// Name returns the name of the extension (make sure it's custom)\n\tName() string\n\n\t// ParseDidStart is being called before starting the parse\n\tParseDidStart(context.Context) (context.Context, ParseFinishFunc)\n\n\t// ValidationDidStart is called just before the validation begins\n\tValidationDidStart(context.Context) (context.Context, ValidationFinishFunc)\n\n\t// ExecutionDidStart notifies about the start of the execution\n\tExecutionDidStart(context.Context) (context.Context, ExecutionFinishFunc)\n\n\t// ResolveFieldDidStart notifies about the start of the resolving of a field\n\tResolveFieldDidStart(context.Context, *ResolveInfo) (context.Context, ResolveFieldFinishFunc)\n\n\t// HasResult returns if the extension wants to add data to the result\n\tHasResult() bool\n\n\t// GetResult returns the data that the extension wants to add to the result\n\tGetResult(context.Context) interface{}\n}\n\n// handleExtensionsInits handles all the init functions for all the extensions in the schema\nfunc handleExtensionsInits(p *Params) gqlerrors.FormattedErrors {\n\terrs := gqlerrors.FormattedErrors{}\n\tfor _, ext := range p.Schema.extensions {\n\t\tfunc() {\n\t\t\t// catch panic from an extension init fn\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\terrs = append(errs, gqlerrors.FormatError(fmt.Errorf(\"%s.Init: %v\", ext.Name(), r.(error))))\n\t\t\t\t}\n\t\t\t}()\n\t\t\t// update context\n\t\t\tp.Context = ext.Init(p.Context, p)\n\t\t}()\n\t}\n\treturn errs\n}\n\n// handleExtensionsParseDidStart runs the ParseDidStart functions for each extension\nfunc handleExtensionsParseDidStart(p *Params) ([]gqlerrors.FormattedError, parseFinishFuncHandler) {\n\tfs := map[string]ParseFinishFunc{}\n\terrs := gqlerrors.FormattedErrors{}\n\tfor _, ext := range p.Schema.extensions {\n\t\tvar (\n\t\t\tctx      context.Context\n\t\t\tfinishFn ParseFinishFunc\n\t\t)\n\t\t// catch panic from an extension's parseDidStart functions\n\t\tfunc() {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\terrs = append(errs, gqlerrors.FormatError(fmt.Errorf(\"%s.ParseDidStart: %v\", ext.Name(), r.(error))))\n\t\t\t\t}\n\t\t\t}()\n\t\t\tctx, finishFn = ext.ParseDidStart(p.Context)\n\t\t\t// update context\n\t\t\tp.Context = ctx\n\t\t\tfs[ext.Name()] = finishFn\n\t\t}()\n\t}\n\treturn errs, func(err error) []gqlerrors.FormattedError {\n\t\terrs := gqlerrors.FormattedErrors{}\n\t\tfor name, fn := range fs {\n\t\t\tfunc() {\n\t\t\t\t// catch panic from a finishFn\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\terrs = append(errs, gqlerrors.FormatError(fmt.Errorf(\"%s.ParseFinishFunc: %v\", name, r.(error))))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tfn(err)\n\t\t\t}()\n\t\t}\n\t\treturn errs\n\t}\n}\n\n// handleExtensionsValidationDidStart notifies the extensions about the start of the validation process\nfunc handleExtensionsValidationDidStart(p *Params) ([]gqlerrors.FormattedError, validationFinishFuncHandler) {\n\tfs := map[string]ValidationFinishFunc{}\n\terrs := gqlerrors.FormattedErrors{}\n\tfor _, ext := range p.Schema.extensions {\n\t\tvar (\n\t\t\tctx      context.Context\n\t\t\tfinishFn ValidationFinishFunc\n\t\t)\n\t\t// catch panic from an extension's validationDidStart function\n\t\tfunc() {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\terrs = append(errs, gqlerrors.FormatError(fmt.Errorf(\"%s.ValidationDidStart: %v\", ext.Name(), r.(error))))\n\t\t\t\t}\n\t\t\t}()\n\t\t\tctx, finishFn = ext.ValidationDidStart(p.Context)\n\t\t\t// update context\n\t\t\tp.Context = ctx\n\t\t\tfs[ext.Name()] = finishFn\n\t\t}()\n\t}\n\treturn errs, func(errs []gqlerrors.FormattedError) []gqlerrors.FormattedError {\n\t\textErrs := gqlerrors.FormattedErrors{}\n\t\tfor name, finishFn := range fs {\n\t\t\tfunc() {\n\t\t\t\t// catch panic from a finishFn\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\textErrs = append(extErrs, gqlerrors.FormatError(fmt.Errorf(\"%s.ValidationFinishFunc: %v\", name, r.(error))))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tfinishFn(errs)\n\t\t\t}()\n\t\t}\n\t\treturn extErrs\n\t}\n}\n\n// handleExecutionDidStart handles the ExecutionDidStart functions\nfunc handleExtensionsExecutionDidStart(p *ExecuteParams) ([]gqlerrors.FormattedError, executionFinishFuncHandler) {\n\tfs := map[string]ExecutionFinishFunc{}\n\terrs := gqlerrors.FormattedErrors{}\n\tfor _, ext := range p.Schema.extensions {\n\t\tvar (\n\t\t\tctx      context.Context\n\t\t\tfinishFn ExecutionFinishFunc\n\t\t)\n\t\t// catch panic from an extension's executionDidStart function\n\t\tfunc() {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\terrs = append(errs, gqlerrors.FormatError(fmt.Errorf(\"%s.ExecutionDidStart: %v\", ext.Name(), r.(error))))\n\t\t\t\t}\n\t\t\t}()\n\t\t\tctx, finishFn = ext.ExecutionDidStart(p.Context)\n\t\t\t// update context\n\t\t\tp.Context = ctx\n\t\t\tfs[ext.Name()] = finishFn\n\t\t}()\n\t}\n\treturn errs, func(result *Result) []gqlerrors.FormattedError {\n\t\textErrs := gqlerrors.FormattedErrors{}\n\t\tfor name, finishFn := range fs {\n\t\t\tfunc() {\n\t\t\t\t// catch panic from a finishFn\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\textErrs = append(extErrs, gqlerrors.FormatError(fmt.Errorf(\"%s.ExecutionFinishFunc: %v\", name, r.(error))))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tfinishFn(result)\n\t\t\t}()\n\t\t}\n\t\treturn extErrs\n\t}\n}\n\n// handleResolveFieldDidStart handles the notification of the extensions about the start of a resolve function\nfunc handleExtensionsResolveFieldDidStart(exts []Extension, p *executionContext, i *ResolveInfo) ([]gqlerrors.FormattedError, resolveFieldFinishFuncHandler) {\n\tfs := map[string]ResolveFieldFinishFunc{}\n\terrs := gqlerrors.FormattedErrors{}\n\tfor _, ext := range p.Schema.extensions {\n\t\tvar (\n\t\t\tctx      context.Context\n\t\t\tfinishFn ResolveFieldFinishFunc\n\t\t)\n\t\t// catch panic from an extension's resolveFieldDidStart function\n\t\tfunc() {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\terrs = append(errs, gqlerrors.FormatError(fmt.Errorf(\"%s.ResolveFieldDidStart: %v\", ext.Name(), r.(error))))\n\t\t\t\t}\n\t\t\t}()\n\t\t\tctx, finishFn = ext.ResolveFieldDidStart(p.Context, i)\n\t\t\t// update context\n\t\t\tp.Context = ctx\n\t\t\tfs[ext.Name()] = finishFn\n\t\t}()\n\t}\n\treturn errs, func(val interface{}, err error) []gqlerrors.FormattedError {\n\t\textErrs := gqlerrors.FormattedErrors{}\n\t\tfor name, finishFn := range fs {\n\t\t\tfunc() {\n\t\t\t\t// catch panic from a finishFn\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\textErrs = append(extErrs, gqlerrors.FormatError(fmt.Errorf(\"%s.ResolveFieldFinishFunc: %v\", name, r.(error))))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tfinishFn(val, err)\n\t\t\t}()\n\t\t}\n\t\treturn extErrs\n\t}\n}\n\nfunc addExtensionResults(p *ExecuteParams, result *Result) {\n\tif len(p.Schema.extensions) != 0 {\n\t\tfor _, ext := range p.Schema.extensions {\n\t\t\tfunc() {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tresult.Errors = append(result.Errors, gqlerrors.FormatError(fmt.Errorf(\"%s.GetResult: %v\", ext.Name(), r.(error))))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tif ext.HasResult() {\n\t\t\t\t\tif result.Extensions == nil {\n\t\t\t\t\t\tresult.Extensions = make(map[string]interface{})\n\t\t\t\t\t}\n\t\t\t\t\tresult.Extensions[ext.Name()] = ext.GetResult(p.Context)\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "extensions_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc tinit(t *testing.T) graphql.Schema {\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Type\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"a\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn \"foo\", nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"erred\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn \"\", errors.New(\"ooops\")\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\treturn schema\n}\n\nfunc TestExtensionInitPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.initFn = func(ctx context.Context, p *graphql.Params) context.Context {\n\t\tif true {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t\treturn ctx\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.Init: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionParseDidStartPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.parseDidStartFn = func(ctx context.Context) (context.Context, graphql.ParseFinishFunc) {\n\t\tif true {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t\treturn ctx, func(err error) {\n\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.ParseDidStart: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionParseFinishFuncPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.parseDidStartFn = func(ctx context.Context) (context.Context, graphql.ParseFinishFunc) {\n\t\treturn ctx, func(err error) {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.ParseFinishFunc: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionValidationDidStartPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.validationDidStartFn = func(ctx context.Context) (context.Context, graphql.ValidationFinishFunc) {\n\t\tif true {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t\treturn ctx, func([]gqlerrors.FormattedError) {\n\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.ValidationDidStart: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionValidationFinishFuncPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.validationDidStartFn = func(ctx context.Context) (context.Context, graphql.ValidationFinishFunc) {\n\t\treturn ctx, func([]gqlerrors.FormattedError) {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.ValidationFinishFunc: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionExecutionDidStartPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.executionDidStartFn = func(ctx context.Context) (context.Context, graphql.ExecutionFinishFunc) {\n\t\tif true {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t\treturn ctx, func(r *graphql.Result) {\n\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.ExecutionDidStart: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionExecutionFinishFuncPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.executionDidStartFn = func(ctx context.Context) (context.Context, graphql.ExecutionFinishFunc) {\n\t\treturn ctx, func(r *graphql.Result) {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"foo\",\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.ExecutionFinishFunc: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionResolveFieldDidStartPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.resolveFieldDidStartFn = func(ctx context.Context, i *graphql.ResolveInfo) (context.Context, graphql.ResolveFieldFinishFunc) {\n\t\tif true {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t\treturn ctx, func(v interface{}, err error) {\n\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"foo\",\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.ResolveFieldDidStart: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionResolveFieldFinishFuncPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.resolveFieldDidStartFn = func(ctx context.Context, i *graphql.ResolveInfo) (context.Context, graphql.ResolveFieldFinishFunc) {\n\t\treturn ctx, func(v interface{}, err error) {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"foo\",\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.ResolveFieldFinishFunc: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t}\n\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestExtensionResolveFieldFinishFuncAfterError(t *testing.T) {\n\tvar fnErrs int\n\text := newtestExt(\"testExt\")\n\text.resolveFieldDidStartFn = func(ctx context.Context, i *graphql.ResolveInfo) (context.Context, graphql.ResolveFieldFinishFunc) {\n\t\treturn ctx, func(v interface{}, err error) {\n\t\t\tif err != nil {\n\t\t\t\tfnErrs++\n\t\t\t}\n\t\t}\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { erred }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\tif resErrs := len(result.Errors); resErrs != 1 {\n\t\tt.Errorf(\"Incorrect number of returned result errors: %d\", resErrs)\n\t}\n\n\tif fnErrs != 1 {\n\t\tt.Errorf(\"Incorrect number of errors captured: %d\", fnErrs)\n\t}\n}\n\nfunc TestExtensionGetResultPanic(t *testing.T) {\n\text := newtestExt(\"testExt\")\n\text.getResultFn = func(context.Context) interface{} {\n\t\tif true {\n\t\t\tpanic(errors.New(\"test error\"))\n\t\t}\n\t\treturn nil\n\t}\n\text.hasResultFn = func() bool {\n\t\treturn true\n\t}\n\n\tschema := tinit(t)\n\tquery := `query Example { a }`\n\tschema.AddExtensions(ext)\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"a\": \"foo\",\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(fmt.Errorf(\"%s.GetResult: %v\", ext.Name(), errors.New(\"test error\"))),\n\t\t},\n\t\tExtensions: make(map[string]interface{}),\n\t}\n\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc newtestExt(name string) *testExt {\n\text := &testExt{\n\t\tname: name,\n\t}\n\tif ext.initFn == nil {\n\t\text.initFn = func(ctx context.Context, p *graphql.Params) context.Context {\n\t\t\treturn ctx\n\t\t}\n\t}\n\tif ext.parseDidStartFn == nil {\n\t\text.parseDidStartFn = func(ctx context.Context) (context.Context, graphql.ParseFinishFunc) {\n\t\t\treturn ctx, func(err error) {\n\n\t\t\t}\n\t\t}\n\t}\n\tif ext.validationDidStartFn == nil {\n\t\text.validationDidStartFn = func(ctx context.Context) (context.Context, graphql.ValidationFinishFunc) {\n\t\t\treturn ctx, func([]gqlerrors.FormattedError) {\n\n\t\t\t}\n\t\t}\n\t}\n\tif ext.executionDidStartFn == nil {\n\t\text.executionDidStartFn = func(ctx context.Context) (context.Context, graphql.ExecutionFinishFunc) {\n\t\t\treturn ctx, func(r *graphql.Result) {\n\n\t\t\t}\n\t\t}\n\t}\n\tif ext.resolveFieldDidStartFn == nil {\n\t\text.resolveFieldDidStartFn = func(ctx context.Context, i *graphql.ResolveInfo) (context.Context, graphql.ResolveFieldFinishFunc) {\n\t\t\treturn ctx, func(v interface{}, err error) {\n\n\t\t\t}\n\t\t}\n\t}\n\tif ext.hasResultFn == nil {\n\t\text.hasResultFn = func() bool {\n\t\t\treturn false\n\t\t}\n\t}\n\tif ext.getResultFn == nil {\n\t\text.getResultFn = func(context.Context) interface{} {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn ext\n}\n\ntype testExt struct {\n\tname                   string\n\tinitFn                 func(ctx context.Context, p *graphql.Params) context.Context\n\thasResultFn            func() bool\n\tgetResultFn            func(context.Context) interface{}\n\tparseDidStartFn        func(ctx context.Context) (context.Context, graphql.ParseFinishFunc)\n\tvalidationDidStartFn   func(ctx context.Context) (context.Context, graphql.ValidationFinishFunc)\n\texecutionDidStartFn    func(ctx context.Context) (context.Context, graphql.ExecutionFinishFunc)\n\tresolveFieldDidStartFn func(ctx context.Context, i *graphql.ResolveInfo) (context.Context, graphql.ResolveFieldFinishFunc)\n}\n\nfunc (t *testExt) Init(ctx context.Context, p *graphql.Params) context.Context {\n\treturn t.initFn(ctx, p)\n}\n\nfunc (t *testExt) Name() string {\n\treturn t.name\n}\n\nfunc (t *testExt) HasResult() bool {\n\treturn t.hasResultFn()\n}\n\nfunc (t *testExt) GetResult(ctx context.Context) interface{} {\n\treturn t.getResultFn(ctx)\n}\n\nfunc (t *testExt) ParseDidStart(ctx context.Context) (context.Context, graphql.ParseFinishFunc) {\n\treturn t.parseDidStartFn(ctx)\n}\n\nfunc (t *testExt) ValidationDidStart(ctx context.Context) (context.Context, graphql.ValidationFinishFunc) {\n\treturn t.validationDidStartFn(ctx)\n}\n\nfunc (t *testExt) ExecutionDidStart(ctx context.Context) (context.Context, graphql.ExecutionFinishFunc) {\n\treturn t.executionDidStartFn(ctx)\n}\n\nfunc (t *testExt) ResolveFieldDidStart(ctx context.Context, i *graphql.ResolveInfo) (context.Context, graphql.ResolveFieldFinishFunc) {\n\treturn t.resolveFieldDidStartFn(ctx, i)\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/graphql-go/graphql\n\ngo 1.13\n"
  },
  {
    "path": "gqlerrors/error.go",
    "content": "package gqlerrors\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\ntype Error struct {\n\tMessage       string\n\tStack         string\n\tNodes         []ast.Node\n\tSource        *source.Source\n\tPositions     []int\n\tLocations     []location.SourceLocation\n\tOriginalError error\n\tPath          []interface{}\n}\n\n// implements Golang's built-in `error` interface\nfunc (g Error) Error() string {\n\treturn fmt.Sprintf(\"%v\", g.Message)\n}\n\nfunc NewError(message string, nodes []ast.Node, stack string, source *source.Source, positions []int, origError error) *Error {\n\treturn newError(message, nodes, stack, source, positions, nil, origError)\n}\n\nfunc NewErrorWithPath(message string, nodes []ast.Node, stack string, source *source.Source, positions []int, path []interface{}, origError error) *Error {\n\treturn newError(message, nodes, stack, source, positions, path, origError)\n}\n\nfunc newError(message string, nodes []ast.Node, stack string, source *source.Source, positions []int, path []interface{}, origError error) *Error {\n\tif stack == \"\" && message != \"\" {\n\t\tstack = message\n\t}\n\tif source == nil {\n\t\tfor _, node := range nodes {\n\t\t\t// get source from first node\n\t\t\tif node == nil || reflect.ValueOf(node).IsNil() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif node.GetLoc() != nil {\n\t\t\t\tsource = node.GetLoc().Source\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\tif len(positions) == 0 && len(nodes) > 0 {\n\t\tfor _, node := range nodes {\n\t\t\tif node == nil || reflect.ValueOf(node).IsNil() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif node.GetLoc() == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpositions = append(positions, node.GetLoc().Start)\n\t\t}\n\t}\n\tlocations := []location.SourceLocation{}\n\tfor _, pos := range positions {\n\t\tloc := location.GetLocation(source, pos)\n\t\tlocations = append(locations, loc)\n\t}\n\treturn &Error{\n\t\tMessage:       message,\n\t\tStack:         stack,\n\t\tNodes:         nodes,\n\t\tSource:        source,\n\t\tPositions:     positions,\n\t\tLocations:     locations,\n\t\tOriginalError: origError,\n\t\tPath:          path,\n\t}\n}\n"
  },
  {
    "path": "gqlerrors/formatted.go",
    "content": "package gqlerrors\n\nimport (\n\t\"errors\"\n\n\t\"github.com/graphql-go/graphql/language/location\"\n)\n\ntype ExtendedError interface {\n\terror\n\tExtensions() map[string]interface{}\n}\n\ntype FormattedError struct {\n\tMessage       string                    `json:\"message\"`\n\tLocations     []location.SourceLocation `json:\"locations\"`\n\tPath          []interface{}             `json:\"path,omitempty\"`\n\tExtensions    map[string]interface{}    `json:\"extensions,omitempty\"`\n\toriginalError error\n}\n\nfunc (g FormattedError) OriginalError() error {\n\treturn g.originalError\n}\n\nfunc (g FormattedError) Error() string {\n\treturn g.Message\n}\n\nfunc NewFormattedError(message string) FormattedError {\n\terr := errors.New(message)\n\treturn FormatError(err)\n}\n\nfunc FormatError(err error) FormattedError {\n\tswitch err := err.(type) {\n\tcase FormattedError:\n\t\treturn err\n\tcase *Error:\n\t\tret := FormattedError{\n\t\t\tMessage:       err.Error(),\n\t\t\tLocations:     err.Locations,\n\t\t\tPath:          err.Path,\n\t\t\toriginalError: err,\n\t\t}\n\t\tif err := err.OriginalError; err != nil {\n\t\t\tif extended, ok := err.(ExtendedError); ok {\n\t\t\t\tret.Extensions = extended.Extensions()\n\t\t\t}\n\t\t}\n\t\treturn ret\n\tcase Error:\n\t\treturn FormatError(&err)\n\tdefault:\n\t\treturn FormattedError{\n\t\t\tMessage:       err.Error(),\n\t\t\tLocations:     []location.SourceLocation{},\n\t\t\toriginalError: err,\n\t\t}\n\t}\n}\n\nfunc FormatErrors(errs ...error) []FormattedError {\n\tformattedErrors := []FormattedError{}\n\tfor _, err := range errs {\n\t\tformattedErrors = append(formattedErrors, FormatError(err))\n\t}\n\treturn formattedErrors\n}\n"
  },
  {
    "path": "gqlerrors/located.go",
    "content": "package gqlerrors\n\nimport (\n\t\"errors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\n// NewLocatedError creates a graphql.Error with location info\n// @deprecated 0.4.18\n// Already exists in `graphql.NewLocatedError()`\nfunc NewLocatedError(err interface{}, nodes []ast.Node) *Error {\n\tvar origError error\n\tmessage := \"An unknown error occurred.\"\n\tif err, ok := err.(error); ok {\n\t\tmessage = err.Error()\n\t\torigError = err\n\t}\n\tif err, ok := err.(string); ok {\n\t\tmessage = err\n\t\torigError = errors.New(err)\n\t}\n\tstack := message\n\treturn NewError(\n\t\tmessage,\n\t\tnodes,\n\t\tstack,\n\t\tnil,\n\t\t[]int{},\n\t\torigError,\n\t)\n}\n\nfunc FieldASTsToNodeASTs(fieldASTs []*ast.Field) []ast.Node {\n\tnodes := []ast.Node{}\n\tfor _, fieldAST := range fieldASTs {\n\t\tnodes = append(nodes, fieldAST)\n\t}\n\treturn nodes\n}\n"
  },
  {
    "path": "gqlerrors/sortutil.go",
    "content": "package gqlerrors\n\nimport \"bytes\"\n\ntype FormattedErrors []FormattedError\n\nfunc (errs FormattedErrors) Len() int {\n\treturn len(errs)\n}\n\nfunc (errs FormattedErrors) Swap(i, j int) {\n\terrs[i], errs[j] = errs[j], errs[i]\n}\n\nfunc (errs FormattedErrors) Less(i, j int) bool {\n\tmCompare := bytes.Compare([]byte(errs[i].Message), []byte(errs[j].Message))\n\tlesserLine := errs[i].Locations[0].Line < errs[j].Locations[0].Line\n\teqLine := errs[i].Locations[0].Line == errs[j].Locations[0].Line\n\tlesserColumn := errs[i].Locations[0].Column < errs[j].Locations[0].Column\n\tif mCompare < 0 {\n\t\treturn true\n\t}\n\tif mCompare == 0 && lesserLine {\n\t\treturn true\n\t}\n\tif mCompare == 0 && eqLine && lesserColumn {\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "gqlerrors/syntax.go",
    "content": "package gqlerrors\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\nfunc NewSyntaxError(s *source.Source, position int, description string) *Error {\n\tl := location.GetLocation(s, position)\n\treturn NewError(\n\t\tfmt.Sprintf(\"Syntax Error %s (%d:%d) %s\\n\\n%s\", s.Name, l.Line, l.Column, description, highlightSourceAtLocation(s, l)),\n\t\t[]ast.Node{},\n\t\t\"\",\n\t\ts,\n\t\t[]int{position},\n\t\tnil,\n\t)\n}\n\n// printCharCode here is slightly different from lexer.printCharCode()\nfunc printCharCode(code rune) string {\n\t// print as ASCII for printable range\n\tif code >= 0x0020 {\n\t\treturn fmt.Sprintf(`%c`, code)\n\t}\n\t// Otherwise print the escaped form. e.g. `\"\\\\u0007\"`\n\treturn fmt.Sprintf(`\\u%04X`, code)\n}\nfunc printLine(str string) string {\n\tstrSlice := []string{}\n\tfor _, runeValue := range str {\n\t\tstrSlice = append(strSlice, printCharCode(runeValue))\n\t}\n\treturn fmt.Sprintf(`%s`, strings.Join(strSlice, \"\"))\n}\nfunc highlightSourceAtLocation(s *source.Source, l location.SourceLocation) string {\n\tline := l.Line\n\tprevLineNum := fmt.Sprintf(\"%d\", (line - 1))\n\tlineNum := fmt.Sprintf(\"%d\", line)\n\tnextLineNum := fmt.Sprintf(\"%d\", (line + 1))\n\tpadLen := len(nextLineNum)\n\tlines := regexp.MustCompile(\"\\r\\n|[\\n\\r]\").Split(string(s.Body), -1)\n\tvar highlight string\n\tif line >= 2 {\n\t\thighlight += fmt.Sprintf(\"%s: %s\\n\", lpad(padLen, prevLineNum), printLine(lines[line-2]))\n\t}\n\thighlight += fmt.Sprintf(\"%s: %s\\n\", lpad(padLen, lineNum), printLine(lines[line-1]))\n\tfor i := 1; i < (2 + padLen + l.Column); i++ {\n\t\thighlight += \" \"\n\t}\n\thighlight += \"^\\n\"\n\tif line < len(lines) {\n\t\thighlight += fmt.Sprintf(\"%s: %s\\n\", lpad(padLen, nextLineNum), printLine(lines[line]))\n\t}\n\treturn highlight\n}\n\nfunc lpad(l int, s string) string {\n\tvar r string\n\tfor i := 1; i < (l - len(s) + 1); i++ {\n\t\tr += \" \"\n\t}\n\treturn r + s\n}\n"
  },
  {
    "path": "graphql.go",
    "content": "package graphql\n\nimport (\n\t\"context\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/parser\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\ntype Params struct {\n\t// The GraphQL type system to use when validating and executing a query.\n\tSchema Schema\n\n\t// A GraphQL language formatted string representing the requested operation.\n\tRequestString string\n\n\t// The value provided as the first argument to resolver functions on the top\n\t// level type (e.g. the query object type).\n\tRootObject map[string]interface{}\n\n\t// A mapping of variable name to runtime value to use for all variables\n\t// defined in the requestString.\n\tVariableValues map[string]interface{}\n\n\t// The name of the operation to use if requestString contains multiple\n\t// possible operations. Can be omitted if requestString contains only\n\t// one operation.\n\tOperationName string\n\n\t// Context may be provided to pass application-specific per-request\n\t// information to resolve functions.\n\tContext context.Context\n}\n\nfunc Do(p Params) *Result {\n\tsource := source.NewSource(&source.Source{\n\t\tBody: []byte(p.RequestString),\n\t\tName: \"GraphQL request\",\n\t})\n\n\t// run init on the extensions\n\textErrs := handleExtensionsInits(&p)\n\tif len(extErrs) != 0 {\n\t\treturn &Result{\n\t\t\tErrors: extErrs,\n\t\t}\n\t}\n\n\textErrs, parseFinishFn := handleExtensionsParseDidStart(&p)\n\tif len(extErrs) != 0 {\n\t\treturn &Result{\n\t\t\tErrors: extErrs,\n\t\t}\n\t}\n\n\t// parse the source\n\tAST, err := parser.Parse(parser.ParseParams{Source: source})\n\tif err != nil {\n\t\t// run parseFinishFuncs for extensions\n\t\textErrs = parseFinishFn(err)\n\n\t\t// merge the errors from extensions and the original error from parser\n\t\textErrs = append(extErrs, gqlerrors.FormatErrors(err)...)\n\t\treturn &Result{\n\t\t\tErrors: extErrs,\n\t\t}\n\t}\n\n\t// run parseFinish functions for extensions\n\textErrs = parseFinishFn(err)\n\tif len(extErrs) != 0 {\n\t\treturn &Result{\n\t\t\tErrors: extErrs,\n\t\t}\n\t}\n\n\t// notify extensions about the start of the validation\n\textErrs, validationFinishFn := handleExtensionsValidationDidStart(&p)\n\tif len(extErrs) != 0 {\n\t\treturn &Result{\n\t\t\tErrors: extErrs,\n\t\t}\n\t}\n\n\t// validate document\n\tvalidationResult := ValidateDocument(&p.Schema, AST, nil)\n\n\tif !validationResult.IsValid {\n\t\t// run validation finish functions for extensions\n\t\textErrs = validationFinishFn(validationResult.Errors)\n\n\t\t// merge the errors from extensions and the original error from parser\n\t\textErrs = append(extErrs, validationResult.Errors...)\n\t\treturn &Result{\n\t\t\tErrors: extErrs,\n\t\t}\n\t}\n\n\t// run the validationFinishFuncs for extensions\n\textErrs = validationFinishFn(validationResult.Errors)\n\tif len(extErrs) != 0 {\n\t\treturn &Result{\n\t\t\tErrors: extErrs,\n\t\t}\n\t}\n\n\treturn Execute(ExecuteParams{\n\t\tSchema:        p.Schema,\n\t\tRoot:          p.RootObject,\n\t\tAST:           AST,\n\t\tOperationName: p.OperationName,\n\t\tArgs:          p.VariableValues,\n\t\tContext:       p.Context,\n\t})\n}\n"
  },
  {
    "path": "graphql_bench_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/benchutil\"\n)\n\ntype B struct {\n\tQuery  string\n\tSchema graphql.Schema\n}\n\nfunc benchGraphql(bench B, p graphql.Params, t testing.TB) {\n\tresult := graphql.Do(p)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n}\n\n// Benchmark a reasonably large list of small items.\nfunc BenchmarkListQuery_1(b *testing.B) {\n\tnItemsListQueryBenchmark(1)(b)\n}\n\nfunc BenchmarkListQuery_100(b *testing.B) {\n\tnItemsListQueryBenchmark(100)(b)\n}\n\nfunc BenchmarkListQuery_1K(b *testing.B) {\n\tnItemsListQueryBenchmark(1000)(b)\n}\n\nfunc BenchmarkListQuery_10K(b *testing.B) {\n\tnItemsListQueryBenchmark(10 * 1000)(b)\n}\n\nfunc BenchmarkListQuery_100K(b *testing.B) {\n\tnItemsListQueryBenchmark(100 * 1000)(b)\n}\n\nfunc nItemsListQueryBenchmark(x int) func(b *testing.B) {\n\treturn func(b *testing.B) {\n\t\tschema := benchutil.ListSchemaWithXItems(x)\n\n\t\tbench := B{\n\t\t\tQuery: `\n\t\t\t\tquery {\n\t\t\t\t\tcolors {\n\t\t\t\t\t\thex\n\t\t\t\t\t\tr\n\t\t\t\t\t\tg\n\t\t\t\t\t\tb\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\tSchema: schema,\n\t\t}\n\n\t\tfor i := 0; i < b.N; i++ {\n\n\t\t\tparams := graphql.Params{\n\t\t\t\tSchema:        schema,\n\t\t\t\tRequestString: bench.Query,\n\t\t\t}\n\t\t\tbenchGraphql(bench, params, b)\n\t\t}\n\t}\n}\n\nfunc BenchmarkWideQuery_1_1(b *testing.B) {\n\tnFieldsyItemsQueryBenchmark(1, 1)(b)\n}\n\nfunc BenchmarkWideQuery_10_1(b *testing.B) {\n\tnFieldsyItemsQueryBenchmark(10, 1)(b)\n}\n\nfunc BenchmarkWideQuery_100_1(b *testing.B) {\n\tnFieldsyItemsQueryBenchmark(100, 1)(b)\n}\n\nfunc BenchmarkWideQuery_1K_1(b *testing.B) {\n\tnFieldsyItemsQueryBenchmark(1000, 1)(b)\n}\n\nfunc BenchmarkWideQuery_1_10(b *testing.B) {\n\tnFieldsyItemsQueryBenchmark(1, 10)(b)\n}\n\nfunc BenchmarkWideQuery_10_10(b *testing.B) {\n\tnFieldsyItemsQueryBenchmark(10, 10)(b)\n}\n\nfunc BenchmarkWideQuery_100_10(b *testing.B) {\n\tnFieldsyItemsQueryBenchmark(100, 10)(b)\n}\n\nfunc BenchmarkWideQuery_1K_10(b *testing.B) {\n\tnFieldsyItemsQueryBenchmark(1000, 10)(b)\n}\n\nfunc nFieldsyItemsQueryBenchmark(x int, y int) func(b *testing.B) {\n\treturn func(b *testing.B) {\n\t\tschema := benchutil.WideSchemaWithXFieldsAndYItems(x, y)\n\t\tquery := benchutil.WideSchemaQuery(x)\n\n\t\tbench := B{\n\t\t\tQuery:  query,\n\t\t\tSchema: schema,\n\t\t}\n\n\t\tb.ResetTimer()\n\n\t\tfor i := 0; i < b.N; i++ {\n\t\t\tparams := graphql.Params{\n\t\t\t\tSchema:        schema,\n\t\t\t\tRequestString: bench.Query,\n\t\t\t}\n\t\t\tbenchGraphql(bench, params, b)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "graphql_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\ntype T struct {\n\tQuery     string\n\tSchema    graphql.Schema\n\tExpected  interface{}\n\tVariables map[string]interface{}\n}\n\nvar Tests = []T{}\n\nfunc init() {\n\tTests = []T{\n\t\t{\n\t\t\tQuery: `\n\t\t\t\tquery HeroNameQuery {\n\t\t\t\t\thero {\n\t\t\t\t\t\tname\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\tSchema: testutil.StarWarsSchema,\n\t\t\tExpected: &graphql.Result{\n\t\t\t\tData: map[string]interface{}{\n\t\t\t\t\t\"hero\": map[string]interface{}{\n\t\t\t\t\t\t\"name\": \"R2-D2\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tQuery: `\n\t\t\t\tquery HeroNameAndFriendsQuery {\n\t\t\t\t\thero {\n\t\t\t\t\t\tid\n\t\t\t\t\t\tname\n\t\t\t\t\t\tfriends {\n\t\t\t\t\t\t\tname\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\tSchema: testutil.StarWarsSchema,\n\t\t\tExpected: &graphql.Result{\n\t\t\t\tData: map[string]interface{}{\n\t\t\t\t\t\"hero\": map[string]interface{}{\n\t\t\t\t\t\t\"id\":   \"2001\",\n\t\t\t\t\t\t\"name\": \"R2-D2\",\n\t\t\t\t\t\t\"friends\": []interface{}{\n\t\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\t\"name\": \"Luke Skywalker\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\t\"name\": \"Han Solo\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\t\"name\": \"Leia Organa\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tQuery: `\n\t\t\t\tquery HumanByIdQuery($id: String!) {\n\t\t\t\t\thuman(id: $id) {\n\t\t\t\t\t\tname\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\tSchema: testutil.StarWarsSchema,\n\t\t\tExpected: &graphql.Result{\n\t\t\t\tData: map[string]interface{}{\n\t\t\t\t\t\"human\": map[string]interface{}{\n\t\t\t\t\t\t\"name\": \"Darth Vader\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tVariables: map[string]interface{}{\n\t\t\t\t\"id\": \"1001\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc TestQuery(t *testing.T) {\n\tfor _, test := range Tests {\n\t\tparams := graphql.Params{\n\t\t\tSchema:         test.Schema,\n\t\t\tRequestString:  test.Query,\n\t\t\tVariableValues: test.Variables,\n\t\t}\n\t\ttestGraphql(test, params, t)\n\t}\n}\n\nfunc testGraphql(test T, p graphql.Params, t *testing.T) {\n\tresult := graphql.Do(p)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(result, test.Expected) {\n\t\tt.Fatalf(\"wrong result, query: %v, graphql result diff: %v\", test.Query, testutil.Diff(test.Expected, result))\n\t}\n}\n\nfunc TestBasicGraphQLExample(t *testing.T) {\n\t// taken from `graphql-js` README\n\n\thelloFieldResolved := func(p graphql.ResolveParams) (interface{}, error) {\n\t\treturn \"world\", nil\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"RootQueryType\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"hello\": &graphql.Field{\n\t\t\t\t\tDescription: \"Returns `world`\",\n\t\t\t\t\tType:        graphql.String,\n\t\t\t\t\tResolve:     helloFieldResolved,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", err.Error())\n\t}\n\tquery := \"{ hello }\"\n\tvar expected interface{}\n\texpected = map[string]interface{}{\n\t\t\"hello\": \"world\",\n\t}\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(result.Data, expected) {\n\t\tt.Fatalf(\"wrong result, query: %v, graphql result diff: %v\", query, testutil.Diff(expected, result))\n\t}\n\n}\n\nfunc TestThreadsContextFromParamsThrough(t *testing.T) {\n\textractFieldFromContextFn := func(p graphql.ResolveParams) (interface{}, error) {\n\t\treturn p.Context.Value(p.Args[\"key\"]), nil\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"value\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\t\"key\": &graphql.ArgumentConfig{Type: graphql.String},\n\t\t\t\t\t},\n\t\t\t\t\tResolve: extractFieldFromContextFn,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", err.Error())\n\t}\n\tquery := `{ value(key:\"a\") }`\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t\tContext:       context.WithValue(context.TODO(), \"a\", \"xyz\"),\n\t})\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\texpected := map[string]interface{}{\"value\": \"xyz\"}\n\tif !reflect.DeepEqual(result.Data, expected) {\n\t\tt.Fatalf(\"wrong result, query: %v, graphql result diff: %v\", query, testutil.Diff(expected, result))\n\t}\n\n}\n\nfunc TestNewErrorChecksNilNodes(t *testing.T) {\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"graphql_is\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn \"\", nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected errors: %v\", err.Error())\n\t}\n\tquery := `{graphql_is:great(sort:ByPopularity)}{stars}`\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) == 0 {\n\t\tt.Fatalf(\"expected errors, got: %v\", result)\n\t}\n}\n\nfunc TestEmptyStringIsNotNull(t *testing.T) {\n\tcheckForEmptyString := func(p graphql.ResolveParams) (interface{}, error) {\n\t\targ := p.Args[\"arg\"]\n\t\tif arg == nil || arg.(string) != \"\" {\n\t\t\tt.Errorf(\"Expected empty string for input arg, got %#v\", arg)\n\t\t}\n\t\treturn \"yay\", nil\n\t}\n\treturnEmptyString := func(p graphql.ResolveParams) (interface{}, error) {\n\t\treturn \"\", nil\n\t}\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"checkEmptyArg\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\t\"arg\": &graphql.ArgumentConfig{Type: graphql.String},\n\t\t\t\t\t},\n\t\t\t\t\tResolve: checkForEmptyString,\n\t\t\t\t},\n\t\t\t\t\"checkEmptyResult\": &graphql.Field{\n\t\t\t\t\tType:    graphql.String,\n\t\t\t\t\tResolve: returnEmptyString,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", err.Error())\n\t}\n\tquery := `{ checkEmptyArg(arg:\"\") checkEmptyResult }`\n\n\tresult := graphql.Do(graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\texpected := map[string]interface{}{\"checkEmptyArg\": \"yay\", \"checkEmptyResult\": \"\"}\n\tif !reflect.DeepEqual(result.Data, expected) {\n\t\tt.Errorf(\"wrong result, query: %v, graphql result diff: %v\", query, testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "introspection.go",
    "content": "package graphql\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"sort\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/printer\"\n)\n\nconst (\n\tTypeKindScalar      = \"SCALAR\"\n\tTypeKindObject      = \"OBJECT\"\n\tTypeKindInterface   = \"INTERFACE\"\n\tTypeKindUnion       = \"UNION\"\n\tTypeKindEnum        = \"ENUM\"\n\tTypeKindInputObject = \"INPUT_OBJECT\"\n\tTypeKindList        = \"LIST\"\n\tTypeKindNonNull     = \"NON_NULL\"\n)\n\n// SchemaType is type definition for __Schema\nvar SchemaType *Object\n\n// DirectiveType is type definition for __Directive\nvar DirectiveType *Object\n\n// TypeType is type definition for __Type\nvar TypeType *Object\n\n// FieldType is type definition for __Field\nvar FieldType *Object\n\n// InputValueType is type definition for __InputValue\nvar InputValueType *Object\n\n// EnumValueType is type definition for __EnumValue\nvar EnumValueType *Object\n\n// TypeKindEnumType is type definition for __TypeKind\nvar TypeKindEnumType *Enum\n\n// DirectiveLocationEnumType is type definition for __DirectiveLocation\nvar DirectiveLocationEnumType *Enum\n\n// Meta-field definitions.\n\n// SchemaMetaFieldDef Meta field definition for Schema\nvar SchemaMetaFieldDef *FieldDefinition\n\n// TypeMetaFieldDef Meta field definition for types\nvar TypeMetaFieldDef *FieldDefinition\n\n// TypeNameMetaFieldDef Meta field definition for type names\nvar TypeNameMetaFieldDef *FieldDefinition\n\nfunc init() {\n\n\tTypeKindEnumType = NewEnum(EnumConfig{\n\t\tName:        \"__TypeKind\",\n\t\tDescription: \"An enum describing what kind of type a given `__Type` is.\",\n\t\tValues: EnumValueConfigMap{\n\t\t\t\"SCALAR\": &EnumValueConfig{\n\t\t\t\tValue:       TypeKindScalar,\n\t\t\t\tDescription: \"Indicates this type is a scalar.\",\n\t\t\t},\n\t\t\t\"OBJECT\": &EnumValueConfig{\n\t\t\t\tValue: TypeKindObject,\n\t\t\t\tDescription: \"Indicates this type is an object. \" +\n\t\t\t\t\t\"`fields` and `interfaces` are valid fields.\",\n\t\t\t},\n\t\t\t\"INTERFACE\": &EnumValueConfig{\n\t\t\t\tValue: TypeKindInterface,\n\t\t\t\tDescription: \"Indicates this type is an interface. \" +\n\t\t\t\t\t\"`fields` and `possibleTypes` are valid fields.\",\n\t\t\t},\n\t\t\t\"UNION\": &EnumValueConfig{\n\t\t\t\tValue: TypeKindUnion,\n\t\t\t\tDescription: \"Indicates this type is a union. \" +\n\t\t\t\t\t\"`possibleTypes` is a valid field.\",\n\t\t\t},\n\t\t\t\"ENUM\": &EnumValueConfig{\n\t\t\t\tValue: TypeKindEnum,\n\t\t\t\tDescription: \"Indicates this type is an enum. \" +\n\t\t\t\t\t\"`enumValues` is a valid field.\",\n\t\t\t},\n\t\t\t\"INPUT_OBJECT\": &EnumValueConfig{\n\t\t\t\tValue: TypeKindInputObject,\n\t\t\t\tDescription: \"Indicates this type is an input object. \" +\n\t\t\t\t\t\"`inputFields` is a valid field.\",\n\t\t\t},\n\t\t\t\"LIST\": &EnumValueConfig{\n\t\t\t\tValue: TypeKindList,\n\t\t\t\tDescription: \"Indicates this type is a list. \" +\n\t\t\t\t\t\"`ofType` is a valid field.\",\n\t\t\t},\n\t\t\t\"NON_NULL\": &EnumValueConfig{\n\t\t\t\tValue: TypeKindNonNull,\n\t\t\t\tDescription: \"Indicates this type is a non-null. \" +\n\t\t\t\t\t\"`ofType` is a valid field.\",\n\t\t\t},\n\t\t},\n\t})\n\n\tDirectiveLocationEnumType = NewEnum(EnumConfig{\n\t\tName: \"__DirectiveLocation\",\n\t\tDescription: \"A Directive can be adjacent to many parts of the GraphQL language, a \" +\n\t\t\t\"__DirectiveLocation describes one such possible adjacencies.\",\n\t\tValues: EnumValueConfigMap{\n\t\t\t\"QUERY\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationQuery,\n\t\t\t\tDescription: \"Location adjacent to a query operation.\",\n\t\t\t},\n\t\t\t\"MUTATION\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationMutation,\n\t\t\t\tDescription: \"Location adjacent to a mutation operation.\",\n\t\t\t},\n\t\t\t\"SUBSCRIPTION\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationSubscription,\n\t\t\t\tDescription: \"Location adjacent to a subscription operation.\",\n\t\t\t},\n\t\t\t\"FIELD\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationField,\n\t\t\t\tDescription: \"Location adjacent to a field.\",\n\t\t\t},\n\t\t\t\"FRAGMENT_DEFINITION\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationFragmentDefinition,\n\t\t\t\tDescription: \"Location adjacent to a fragment definition.\",\n\t\t\t},\n\t\t\t\"FRAGMENT_SPREAD\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationFragmentSpread,\n\t\t\t\tDescription: \"Location adjacent to a fragment spread.\",\n\t\t\t},\n\t\t\t\"INLINE_FRAGMENT\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationInlineFragment,\n\t\t\t\tDescription: \"Location adjacent to an inline fragment.\",\n\t\t\t},\n\t\t\t\"SCHEMA\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationSchema,\n\t\t\t\tDescription: \"Location adjacent to a schema definition.\",\n\t\t\t},\n\t\t\t\"SCALAR\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationScalar,\n\t\t\t\tDescription: \"Location adjacent to a scalar definition.\",\n\t\t\t},\n\t\t\t\"OBJECT\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationObject,\n\t\t\t\tDescription: \"Location adjacent to an object type definition.\",\n\t\t\t},\n\t\t\t\"FIELD_DEFINITION\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationFieldDefinition,\n\t\t\t\tDescription: \"Location adjacent to a field definition.\",\n\t\t\t},\n\t\t\t\"ARGUMENT_DEFINITION\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationArgumentDefinition,\n\t\t\t\tDescription: \"Location adjacent to an argument definition.\",\n\t\t\t},\n\t\t\t\"INTERFACE\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationInterface,\n\t\t\t\tDescription: \"Location adjacent to an interface definition.\",\n\t\t\t},\n\t\t\t\"UNION\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationUnion,\n\t\t\t\tDescription: \"Location adjacent to a union definition.\",\n\t\t\t},\n\t\t\t\"ENUM\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationEnum,\n\t\t\t\tDescription: \"Location adjacent to an enum definition.\",\n\t\t\t},\n\t\t\t\"ENUM_VALUE\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationEnumValue,\n\t\t\t\tDescription: \"Location adjacent to an enum value definition.\",\n\t\t\t},\n\t\t\t\"INPUT_OBJECT\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationInputObject,\n\t\t\t\tDescription: \"Location adjacent to an input object type definition.\",\n\t\t\t},\n\t\t\t\"INPUT_FIELD_DEFINITION\": &EnumValueConfig{\n\t\t\t\tValue:       DirectiveLocationInputFieldDefinition,\n\t\t\t\tDescription: \"Location adjacent to an input object field definition.\",\n\t\t\t},\n\t\t},\n\t})\n\n\t// Note: some fields (for e.g \"fields\", \"interfaces\") are defined later due to cyclic reference\n\tTypeType = NewObject(ObjectConfig{\n\t\tName: \"__Type\",\n\t\tDescription: \"The fundamental unit of any GraphQL Schema is the type. There are \" +\n\t\t\t\"many kinds of types in GraphQL as represented by the `__TypeKind` enum.\" +\n\t\t\t\"\\n\\nDepending on the kind of a type, certain fields describe \" +\n\t\t\t\"information about that type. Scalar types provide no information \" +\n\t\t\t\"beyond a name and description, while Enum types provide their values. \" +\n\t\t\t\"Object and Interface types provide the fields they describe. Abstract \" +\n\t\t\t\"types, Union and Interface, provide the Object types possible \" +\n\t\t\t\"at runtime. List and NonNull types compose other types.\",\n\n\t\tFields: Fields{\n\t\t\t\"kind\": &Field{\n\t\t\t\tType: NewNonNull(TypeKindEnumType),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tswitch p.Source.(type) {\n\t\t\t\t\tcase *Scalar:\n\t\t\t\t\t\treturn TypeKindScalar, nil\n\t\t\t\t\tcase *Object:\n\t\t\t\t\t\treturn TypeKindObject, nil\n\t\t\t\t\tcase *Interface:\n\t\t\t\t\t\treturn TypeKindInterface, nil\n\t\t\t\t\tcase *Union:\n\t\t\t\t\t\treturn TypeKindUnion, nil\n\t\t\t\t\tcase *Enum:\n\t\t\t\t\t\treturn TypeKindEnum, nil\n\t\t\t\t\tcase *InputObject:\n\t\t\t\t\t\treturn TypeKindInputObject, nil\n\t\t\t\t\tcase *List:\n\t\t\t\t\t\treturn TypeKindList, nil\n\t\t\t\t\tcase *NonNull:\n\t\t\t\t\t\treturn TypeKindNonNull, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, fmt.Errorf(\"Unknown kind of type: %v\", p.Source)\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"name\": &Field{\n\t\t\t\tType: String,\n\t\t\t},\n\t\t\t\"description\": &Field{\n\t\t\t\tType: String,\n\t\t\t},\n\t\t\t\"fields\":        &Field{},\n\t\t\t\"interfaces\":    &Field{},\n\t\t\t\"possibleTypes\": &Field{},\n\t\t\t\"enumValues\":    &Field{},\n\t\t\t\"inputFields\":   &Field{},\n\t\t\t\"ofType\":        &Field{},\n\t\t},\n\t})\n\n\tInputValueType = NewObject(ObjectConfig{\n\t\tName: \"__InputValue\",\n\t\tDescription: \"Arguments provided to Fields or Directives and the input fields of an \" +\n\t\t\t\"InputObject are represented as Input Values which describe their type \" +\n\t\t\t\"and optionally a default value.\",\n\t\tFields: Fields{\n\t\t\t\"name\": &Field{\n\t\t\t\tType: NewNonNull(String),\n\t\t\t},\n\t\t\t\"description\": &Field{\n\t\t\t\tType: String,\n\t\t\t},\n\t\t\t\"type\": &Field{\n\t\t\t\tType: NewNonNull(TypeType),\n\t\t\t},\n\t\t\t\"defaultValue\": &Field{\n\t\t\t\tType: String,\n\t\t\t\tDescription: \"A GraphQL-formatted string representing the default value for this \" +\n\t\t\t\t\t\"input value.\",\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif inputVal, ok := p.Source.(*Argument); ok {\n\t\t\t\t\t\tif inputVal.DefaultValue == nil {\n\t\t\t\t\t\t\treturn nil, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif isNullish(inputVal.DefaultValue) {\n\t\t\t\t\t\t\treturn nil, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\tastVal := astFromValue(inputVal.DefaultValue, inputVal)\n\t\t\t\t\t\treturn printer.Print(astVal), nil\n\t\t\t\t\t}\n\t\t\t\t\tif inputVal, ok := p.Source.(*InputObjectField); ok {\n\t\t\t\t\t\tif inputVal.DefaultValue == nil {\n\t\t\t\t\t\t\treturn nil, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\tastVal := astFromValue(inputVal.DefaultValue, inputVal)\n\t\t\t\t\t\treturn printer.Print(astVal), nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tFieldType = NewObject(ObjectConfig{\n\t\tName: \"__Field\",\n\t\tDescription: \"Object and Interface types are described by a list of Fields, each of \" +\n\t\t\t\"which has a name, potentially a list of arguments, and a return type.\",\n\t\tFields: Fields{\n\t\t\t\"name\": &Field{\n\t\t\t\tType: NewNonNull(String),\n\t\t\t},\n\t\t\t\"description\": &Field{\n\t\t\t\tType: String,\n\t\t\t},\n\t\t\t\"args\": &Field{\n\t\t\t\tType: NewNonNull(NewList(NewNonNull(InputValueType))),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif field, ok := p.Source.(*FieldDefinition); ok {\n\t\t\t\t\t\treturn field.Args, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn []interface{}{}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"type\": &Field{\n\t\t\t\tType: NewNonNull(TypeType),\n\t\t\t},\n\t\t\t\"isDeprecated\": &Field{\n\t\t\t\tType: NewNonNull(Boolean),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif field, ok := p.Source.(*FieldDefinition); ok {\n\t\t\t\t\t\treturn (field.DeprecationReason != \"\"), nil\n\t\t\t\t\t}\n\t\t\t\t\treturn false, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"deprecationReason\": &Field{\n\t\t\t\tType: String,\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif field, ok := p.Source.(*FieldDefinition); ok {\n\t\t\t\t\t\tif field.DeprecationReason != \"\" {\n\t\t\t\t\t\t\treturn field.DeprecationReason, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tDirectiveType = NewObject(ObjectConfig{\n\t\tName: \"__Directive\",\n\t\tDescription: \"A Directive provides a way to describe alternate runtime execution and \" +\n\t\t\t\"type validation behavior in a GraphQL document.\" +\n\t\t\t\"\\n\\nIn some cases, you need to provide options to alter GraphQL's \" +\n\t\t\t\"execution behavior in ways field arguments will not suffice, such as \" +\n\t\t\t\"conditionally including or skipping a field. Directives provide this by \" +\n\t\t\t\"describing additional information to the executor.\",\n\t\tFields: Fields{\n\t\t\t\"name\": &Field{\n\t\t\t\tType: NewNonNull(String),\n\t\t\t},\n\t\t\t\"description\": &Field{\n\t\t\t\tType: String,\n\t\t\t},\n\t\t\t\"locations\": &Field{\n\t\t\t\tType: NewNonNull(NewList(\n\t\t\t\t\tNewNonNull(DirectiveLocationEnumType),\n\t\t\t\t)),\n\t\t\t},\n\t\t\t\"args\": &Field{\n\t\t\t\tType: NewNonNull(NewList(\n\t\t\t\t\tNewNonNull(InputValueType),\n\t\t\t\t)),\n\t\t\t},\n\t\t\t// NOTE: the following three fields are deprecated and are no longer part\n\t\t\t// of the GraphQL specification.\n\t\t\t\"onOperation\": &Field{\n\t\t\t\tDeprecationReason: \"Use `locations`.\",\n\t\t\t\tType:              NewNonNull(Boolean),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif dir, ok := p.Source.(*Directive); ok {\n\t\t\t\t\t\tres := false\n\t\t\t\t\t\tfor _, loc := range dir.Locations {\n\t\t\t\t\t\t\tif loc == DirectiveLocationQuery ||\n\t\t\t\t\t\t\t\tloc == DirectiveLocationMutation ||\n\t\t\t\t\t\t\t\tloc == DirectiveLocationSubscription {\n\t\t\t\t\t\t\t\tres = true\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn res, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn false, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"onFragment\": &Field{\n\t\t\t\tDeprecationReason: \"Use `locations`.\",\n\t\t\t\tType:              NewNonNull(Boolean),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif dir, ok := p.Source.(*Directive); ok {\n\t\t\t\t\t\tres := false\n\t\t\t\t\t\tfor _, loc := range dir.Locations {\n\t\t\t\t\t\t\tif loc == DirectiveLocationFragmentSpread ||\n\t\t\t\t\t\t\t\tloc == DirectiveLocationInlineFragment ||\n\t\t\t\t\t\t\t\tloc == DirectiveLocationFragmentDefinition {\n\t\t\t\t\t\t\t\tres = true\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn res, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn false, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"onField\": &Field{\n\t\t\t\tDeprecationReason: \"Use `locations`.\",\n\t\t\t\tType:              NewNonNull(Boolean),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif dir, ok := p.Source.(*Directive); ok {\n\t\t\t\t\t\tres := false\n\t\t\t\t\t\tfor _, loc := range dir.Locations {\n\t\t\t\t\t\t\tif loc == DirectiveLocationField {\n\t\t\t\t\t\t\t\tres = true\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn res, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn false, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tSchemaType = NewObject(ObjectConfig{\n\t\tName: \"__Schema\",\n\t\tDescription: `A GraphQL Schema defines the capabilities of a GraphQL server. ` +\n\t\t\t`It exposes all available types and directives on the server, as well as ` +\n\t\t\t`the entry points for query, mutation, and subscription operations.`,\n\t\tFields: Fields{\n\t\t\t\"types\": &Field{\n\t\t\t\tDescription: \"A list of all types supported by this server.\",\n\t\t\t\tType: NewNonNull(NewList(\n\t\t\t\t\tNewNonNull(TypeType),\n\t\t\t\t)),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif schema, ok := p.Source.(Schema); ok {\n\t\t\t\t\t\tresults := []Type{}\n\t\t\t\t\t\tfor _, ttype := range schema.TypeMap() {\n\t\t\t\t\t\t\tresults = append(results, ttype)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn results, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn []Type{}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"queryType\": &Field{\n\t\t\t\tDescription: \"The type that query operations will be rooted at.\",\n\t\t\t\tType:        NewNonNull(TypeType),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif schema, ok := p.Source.(Schema); ok {\n\t\t\t\t\t\treturn schema.QueryType(), nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"mutationType\": &Field{\n\t\t\t\tDescription: `If this server supports mutation, the type that ` +\n\t\t\t\t\t`mutation operations will be rooted at.`,\n\t\t\t\tType: TypeType,\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif schema, ok := p.Source.(Schema); ok {\n\t\t\t\t\t\tif schema.MutationType() != nil {\n\t\t\t\t\t\t\treturn schema.MutationType(), nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"subscriptionType\": &Field{\n\t\t\t\tDescription: `If this server support subscription, the type that ` +\n\t\t\t\t\t`subscription operations will be rooted at.`,\n\t\t\t\tType: TypeType,\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif schema, ok := p.Source.(Schema); ok {\n\t\t\t\t\t\tif schema.SubscriptionType() != nil {\n\t\t\t\t\t\t\treturn schema.SubscriptionType(), nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"directives\": &Field{\n\t\t\t\tDescription: `A list of all directives supported by this server.`,\n\t\t\t\tType: NewNonNull(NewList(\n\t\t\t\t\tNewNonNull(DirectiveType),\n\t\t\t\t)),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif schema, ok := p.Source.(Schema); ok {\n\t\t\t\t\t\treturn schema.Directives(), nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\tEnumValueType = NewObject(ObjectConfig{\n\t\tName: \"__EnumValue\",\n\t\tDescription: \"One possible value for a given Enum. Enum values are unique values, not \" +\n\t\t\t\"a placeholder for a string or numeric value. However an Enum value is \" +\n\t\t\t\"returned in a JSON response as a string.\",\n\t\tFields: Fields{\n\t\t\t\"name\": &Field{\n\t\t\t\tType: NewNonNull(String),\n\t\t\t},\n\t\t\t\"description\": &Field{\n\t\t\t\tType: String,\n\t\t\t},\n\t\t\t\"isDeprecated\": &Field{\n\t\t\t\tType: NewNonNull(Boolean),\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif field, ok := p.Source.(*EnumValueDefinition); ok {\n\t\t\t\t\t\treturn (field.DeprecationReason != \"\"), nil\n\t\t\t\t\t}\n\t\t\t\t\treturn false, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"deprecationReason\": &Field{\n\t\t\t\tType: String,\n\t\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\t\tif field, ok := p.Source.(*EnumValueDefinition); ok {\n\t\t\t\t\t\tif field.DeprecationReason != \"\" {\n\t\t\t\t\t\t\treturn field.DeprecationReason, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\n\t// Again, adding field configs to __Type that have cyclic reference here\n\t// because golang don't like them too much during init/compile-time\n\tTypeType.AddFieldConfig(\"fields\", &Field{\n\t\tType: NewList(NewNonNull(FieldType)),\n\t\tArgs: FieldConfigArgument{\n\t\t\t\"includeDeprecated\": &ArgumentConfig{\n\t\t\t\tType:         Boolean,\n\t\t\t\tDefaultValue: false,\n\t\t\t},\n\t\t},\n\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\tincludeDeprecated, _ := p.Args[\"includeDeprecated\"].(bool)\n\t\t\tswitch ttype := p.Source.(type) {\n\t\t\tcase *Object:\n\t\t\t\tif ttype == nil {\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t\tfields := []*FieldDefinition{}\n\t\t\t\tvar fieldNames sort.StringSlice\n\t\t\t\tfor name, field := range ttype.Fields() {\n\t\t\t\t\tif !includeDeprecated && field.DeprecationReason != \"\" {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfieldNames = append(fieldNames, name)\n\t\t\t\t}\n\t\t\t\tsort.Sort(fieldNames)\n\t\t\t\tfor _, name := range fieldNames {\n\t\t\t\t\tfields = append(fields, ttype.Fields()[name])\n\t\t\t\t}\n\t\t\t\treturn fields, nil\n\t\t\tcase *Interface:\n\t\t\t\tif ttype == nil {\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t\tfields := []*FieldDefinition{}\n\t\t\t\tfor _, field := range ttype.Fields() {\n\t\t\t\t\tif !includeDeprecated && field.DeprecationReason != \"\" {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfields = append(fields, field)\n\t\t\t\t}\n\t\t\t\treturn fields, nil\n\t\t\t}\n\t\t\treturn nil, nil\n\t\t},\n\t})\n\tTypeType.AddFieldConfig(\"interfaces\", &Field{\n\t\tType: NewList(NewNonNull(TypeType)),\n\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\tif ttype, ok := p.Source.(*Object); ok {\n\t\t\t\treturn ttype.Interfaces(), nil\n\t\t\t}\n\t\t\treturn nil, nil\n\t\t},\n\t})\n\tTypeType.AddFieldConfig(\"possibleTypes\", &Field{\n\t\tType: NewList(NewNonNull(TypeType)),\n\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\tswitch ttype := p.Source.(type) {\n\t\t\tcase *Interface:\n\t\t\t\treturn p.Info.Schema.PossibleTypes(ttype), nil\n\t\t\tcase *Union:\n\t\t\t\treturn p.Info.Schema.PossibleTypes(ttype), nil\n\t\t\t}\n\t\t\treturn nil, nil\n\t\t},\n\t})\n\tTypeType.AddFieldConfig(\"enumValues\", &Field{\n\t\tType: NewList(NewNonNull(EnumValueType)),\n\t\tArgs: FieldConfigArgument{\n\t\t\t\"includeDeprecated\": &ArgumentConfig{\n\t\t\t\tType:         Boolean,\n\t\t\t\tDefaultValue: false,\n\t\t\t},\n\t\t},\n\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\tincludeDeprecated, _ := p.Args[\"includeDeprecated\"].(bool)\n\t\t\tif ttype, ok := p.Source.(*Enum); ok {\n\t\t\t\tif includeDeprecated {\n\t\t\t\t\treturn ttype.Values(), nil\n\t\t\t\t}\n\t\t\t\tvalues := []*EnumValueDefinition{}\n\t\t\t\tfor _, value := range ttype.Values() {\n\t\t\t\t\tif value.DeprecationReason != \"\" {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t}\n\t\t\t\treturn values, nil\n\t\t\t}\n\t\t\treturn nil, nil\n\t\t},\n\t})\n\tTypeType.AddFieldConfig(\"inputFields\", &Field{\n\t\tType: NewList(NewNonNull(InputValueType)),\n\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\tif ttype, ok := p.Source.(*InputObject); ok {\n\t\t\t\tfields := []*InputObjectField{}\n\t\t\t\tfor _, field := range ttype.Fields() {\n\t\t\t\t\tfields = append(fields, field)\n\t\t\t\t}\n\t\t\t\treturn fields, nil\n\t\t\t}\n\t\t\treturn nil, nil\n\t\t},\n\t})\n\tTypeType.AddFieldConfig(\"ofType\", &Field{\n\t\tType: TypeType,\n\t})\n\n\tSchemaType.ensureCache()\n\tDirectiveType.ensureCache()\n\tTypeType.ensureCache()\n\tFieldType.ensureCache()\n\tInputValueType.ensureCache()\n\tEnumValueType.ensureCache()\n\n\t// Note that these are FieldDefinition and not FieldConfig,\n\t// so the format for args is different.\n\tSchemaMetaFieldDef = &FieldDefinition{\n\t\tName:        \"__schema\",\n\t\tType:        NewNonNull(SchemaType),\n\t\tDescription: \"Access the current type schema of this server.\",\n\t\tArgs:        []*Argument{},\n\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\treturn p.Info.Schema, nil\n\t\t},\n\t}\n\tTypeMetaFieldDef = &FieldDefinition{\n\t\tName:        \"__type\",\n\t\tType:        TypeType,\n\t\tDescription: \"Request the type information of a single type.\",\n\t\tArgs: []*Argument{\n\t\t\t{\n\t\t\t\tPrivateName: \"name\",\n\t\t\t\tType:        NewNonNull(String),\n\t\t\t},\n\t\t},\n\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\tname, ok := p.Args[\"name\"].(string)\n\t\t\tif !ok {\n\t\t\t\treturn nil, nil\n\t\t\t}\n\t\t\treturn p.Info.Schema.Type(name), nil\n\t\t},\n\t}\n\n\tTypeNameMetaFieldDef = &FieldDefinition{\n\t\tName:        \"__typename\",\n\t\tType:        NewNonNull(String),\n\t\tDescription: \"The name of the current Object type at runtime.\",\n\t\tArgs:        []*Argument{},\n\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\treturn p.Info.ParentType.Name(), nil\n\t\t},\n\t}\n\n}\n\n// Produces a GraphQL Value AST given a Golang value.\n//\n// Optionally, a GraphQL type may be provided, which will be used to\n// disambiguate between value primitives.\n//\n// | JSON Value    | GraphQL Value        |\n// | ------------- | -------------------- |\n// | Object        | Input Object         |\n// | Array         | List                 |\n// | Boolean       | Boolean              |\n// | String        | String / Enum Value  |\n// | Number        | Int / Float          |\n\nfunc astFromValue(value interface{}, ttype Type) ast.Value {\n\n\tif ttype, ok := ttype.(*NonNull); ok {\n\t\t// Note: we're not checking that the result is non-null.\n\t\t// This function is not responsible for validating the input value.\n\t\tval := astFromValue(value, ttype.OfType)\n\t\treturn val\n\t}\n\tif isNullish(value) {\n\t\treturn nil\n\t}\n\tvalueVal := reflect.ValueOf(value)\n\tif !valueVal.IsValid() {\n\t\treturn nil\n\t}\n\tif valueVal.Type().Kind() == reflect.Ptr {\n\t\tvalueVal = valueVal.Elem()\n\t}\n\tif !valueVal.IsValid() {\n\t\treturn nil\n\t}\n\n\t// Convert Golang slice to GraphQL list. If the Type is a list, but\n\t// the value is not an array, convert the value using the list's item type.\n\tif ttype, ok := ttype.(*List); ok {\n\t\tif valueVal.Type().Kind() == reflect.Slice {\n\t\t\titemType := ttype.OfType\n\t\t\tvalues := []ast.Value{}\n\t\t\tfor i := 0; i < valueVal.Len(); i++ {\n\t\t\t\titem := valueVal.Index(i).Interface()\n\t\t\t\titemAST := astFromValue(item, itemType)\n\t\t\t\tif itemAST != nil {\n\t\t\t\t\tvalues = append(values, itemAST)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ast.NewListValue(&ast.ListValue{\n\t\t\t\tValues: values,\n\t\t\t})\n\t\t}\n\t\t// Because GraphQL will accept single values as a \"list of one\" when\n\t\t// expecting a list, if there's a non-array value and an expected list type,\n\t\t// create an AST using the list's item type.\n\t\tval := astFromValue(value, ttype.OfType)\n\t\treturn val\n\t}\n\n\tif valueVal.Type().Kind() == reflect.Map {\n\t\t// TODO: implement astFromValue from Map to Value\n\t}\n\n\tif value, ok := value.(bool); ok {\n\t\treturn ast.NewBooleanValue(&ast.BooleanValue{\n\t\t\tValue: value,\n\t\t})\n\t}\n\tif value, ok := value.(int); ok {\n\t\tif ttype == Float {\n\t\t\treturn ast.NewIntValue(&ast.IntValue{\n\t\t\t\tValue: fmt.Sprintf(\"%v.0\", value),\n\t\t\t})\n\t\t}\n\t\treturn ast.NewIntValue(&ast.IntValue{\n\t\t\tValue: fmt.Sprintf(\"%v\", value),\n\t\t})\n\t}\n\tif value, ok := value.(float32); ok {\n\t\treturn ast.NewFloatValue(&ast.FloatValue{\n\t\t\tValue: fmt.Sprintf(\"%v\", value),\n\t\t})\n\t}\n\tif value, ok := value.(float64); ok {\n\t\treturn ast.NewFloatValue(&ast.FloatValue{\n\t\t\tValue: fmt.Sprintf(\"%v\", value),\n\t\t})\n\t}\n\n\tif value, ok := value.(string); ok {\n\t\tif _, ok := ttype.(*Enum); ok {\n\t\t\treturn ast.NewEnumValue(&ast.EnumValue{\n\t\t\t\tValue: fmt.Sprintf(\"%v\", value),\n\t\t\t})\n\t\t}\n\t\treturn ast.NewStringValue(&ast.StringValue{\n\t\t\tValue: fmt.Sprintf(\"%v\", value),\n\t\t})\n\t}\n\n\t// fallback, treat as string\n\treturn ast.NewStringValue(&ast.StringValue{\n\t\tValue: fmt.Sprintf(\"%v\", value),\n\t})\n}\n"
  },
  {
    "path": "introspection_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc g(t *testing.T, p graphql.Params) *graphql.Result {\n\treturn graphql.Do(p)\n}\n\nfunc TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) {\n\temptySchema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"QueryRoot\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"onlyField\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\texpectedDataSubSet := map[string]interface{}{\n\t\t\"__schema\": map[string]interface{}{\n\t\t\t\"mutationType\":     nil,\n\t\t\t\"subscriptionType\": nil,\n\t\t\t\"queryType\": map[string]interface{}{\n\t\t\t\t\"name\": \"QueryRoot\",\n\t\t\t},\n\t\t\t\"types\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\":          \"OBJECT\",\n\t\t\t\t\t\"name\":          \"QueryRoot\",\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    []interface{}{},\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\"name\": \"__Schema\",\n\t\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"types\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"__Type\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"queryType\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\"name\": \"__Type\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"mutationType\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\t\t\t\"name\": \"__Type\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"subscriptionType\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\t\t\t\"name\": \"__Type\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"directives\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"__Directive\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    []interface{}{},\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\"name\": \"__Type\",\n\t\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"kind\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"ENUM\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"__TypeKind\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"fields\",\n\t\t\t\t\t\t\t\"args\": []interface{}{\n\t\t\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"name\": \"includeDeprecated\",\n\t\t\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"defaultValue\": \"false\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\":   \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\"name\":   \"__Field\",\n\t\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"interfaces\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\":   \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\"name\":   \"__Type\",\n\t\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"possibleTypes\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\":   \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\"name\":   \"__Type\",\n\t\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"enumValues\",\n\t\t\t\t\t\t\t\"args\": []interface{}{\n\t\t\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"name\": \"includeDeprecated\",\n\t\t\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"defaultValue\": \"false\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\":   \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\"name\":   \"__EnumValue\",\n\t\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"inputFields\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\":   \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\"name\":   \"__InputValue\",\n\t\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"ofType\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"OBJECT\",\n\t\t\t\t\t\t\t\t\"name\":   \"__Type\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    []interface{}{},\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\":        \"ENUM\",\n\t\t\t\t\t\"name\":        \"__TypeKind\",\n\t\t\t\t\t\"fields\":      nil,\n\t\t\t\t\t\"inputFields\": nil,\n\t\t\t\t\t\"interfaces\":  nil,\n\t\t\t\t\t\"enumValues\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"SCALAR\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"OBJECT\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"INTERFACE\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"UNION\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"ENUM\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"INPUT_OBJECT\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"LIST\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"NON_NULL\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\":          \"SCALAR\",\n\t\t\t\t\t\"name\":          \"String\",\n\t\t\t\t\t\"fields\":        nil,\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    nil,\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\":          \"SCALAR\",\n\t\t\t\t\t\"name\":          \"Boolean\",\n\t\t\t\t\t\"fields\":        nil,\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    nil,\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\"name\": \"__Field\",\n\t\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"args\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"__InputValue\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"__Type\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"isDeprecated\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"deprecationReason\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    []interface{}{},\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\"name\": \"__InputValue\",\n\t\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"type\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"__Type\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"defaultValue\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    []interface{}{},\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\"name\": \"__EnumValue\",\n\t\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"isDeprecated\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"deprecationReason\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    []interface{}{},\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\"name\": \"__Directive\",\n\t\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"description\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"locations\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\t\"kind\": \"ENUM\",\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"__DirectiveLocation\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"args\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\t\"kind\": \"OBJECT\",\n\t\t\t\t\t\t\t\t\t\t\t\"name\": \"__InputValue\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"onOperation\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      true,\n\t\t\t\t\t\t\t\"deprecationReason\": \"Use `locations`.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"onFragment\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      true,\n\t\t\t\t\t\t\t\"deprecationReason\": \"Use `locations`.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"onField\",\n\t\t\t\t\t\t\t\"args\": []interface{}{},\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"isDeprecated\":      true,\n\t\t\t\t\t\t\t\"deprecationReason\": \"Use `locations`.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"inputFields\":   nil,\n\t\t\t\t\t\"interfaces\":    []interface{}{},\n\t\t\t\t\t\"enumValues\":    nil,\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\":        \"ENUM\",\n\t\t\t\t\t\"name\":        \"__DirectiveLocation\",\n\t\t\t\t\t\"fields\":      nil,\n\t\t\t\t\t\"inputFields\": nil,\n\t\t\t\t\t\"interfaces\":  nil,\n\t\t\t\t\t\"enumValues\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"QUERY\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"MUTATION\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"SUBSCRIPTION\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"FIELD\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"FRAGMENT_DEFINITION\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"FRAGMENT_SPREAD\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\":              \"INLINE_FRAGMENT\",\n\t\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"possibleTypes\": nil,\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"directives\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\": \"include\",\n\t\t\t\t\t\"locations\": []interface{}{\n\t\t\t\t\t\t\"FIELD\",\n\t\t\t\t\t\t\"FRAGMENT_SPREAD\",\n\t\t\t\t\t\t\"INLINE_FRAGMENT\",\n\t\t\t\t\t},\n\t\t\t\t\t\"args\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"defaultValue\": nil,\n\t\t\t\t\t\t\t\"name\":         \"if\",\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t// deprecated, but included for coverage till removed\n\t\t\t\t\t\"onOperation\": false,\n\t\t\t\t\t\"onFragment\":  true,\n\t\t\t\t\t\"onField\":     true,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\": \"skip\",\n\t\t\t\t\t\"locations\": []interface{}{\n\t\t\t\t\t\t\"FIELD\",\n\t\t\t\t\t\t\"FRAGMENT_SPREAD\",\n\t\t\t\t\t\t\"INLINE_FRAGMENT\",\n\t\t\t\t\t},\n\t\t\t\t\t\"args\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"defaultValue\": nil,\n\t\t\t\t\t\t\t\"name\":         \"if\",\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"NON_NULL\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"Boolean\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t// deprecated, but included for coverage till removed\n\t\t\t\t\t\"onOperation\": false,\n\t\t\t\t\t\"onFragment\":  true,\n\t\t\t\t\t\"onField\":     true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        emptySchema,\n\t\tRequestString: testutil.IntrospectionQuery,\n\t})\n\tif !testutil.ContainSubset(result.Data.(map[string]interface{}), expectedDataSubSet) {\n\t\tt.Fatalf(\"unexpected, result does not contain subset of expected data\")\n\t}\n}\n\nfunc TestIntrospection_ExecutesAnInputObject(t *testing.T) {\n\n\ttestInputObject := graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"TestInputObject\",\n\t\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\t\"a\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType:         graphql.String,\n\t\t\t\tDefaultValue: \"foo\",\n\t\t\t},\n\t\t\t\"b\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.NewList(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\ttestType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"TestType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"complex\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: testInputObject,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn p.Args[\"complex\"], nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: testType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        __schema {\n          types {\n            kind\n            name\n            inputFields {\n              name\n              type { ...TypeRef }\n              defaultValue\n            }\n          }\n        }\n      }\n\n      fragment TypeRef on __Type {\n        kind\n        name\n        ofType {\n          kind\n          name\n          ofType {\n            kind\n            name\n            ofType {\n              kind\n              name\n            }\n          }\n        }\n      }\n    `\n\texpectedDataSubSet := map[string]interface{}{\n\t\t\"__schema\": map[string]interface{}{\n\t\t\t\"types\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"kind\": \"INPUT_OBJECT\",\n\t\t\t\t\t\"name\": \"TestInputObject\",\n\t\t\t\t\t\"inputFields\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"a\",\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"defaultValue\": `\"foo\"`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"name\": \"b\",\n\t\t\t\t\t\t\t\"type\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"kind\": \"LIST\",\n\t\t\t\t\t\t\t\t\"name\": nil,\n\t\t\t\t\t\t\t\t\"ofType\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"kind\":   \"SCALAR\",\n\t\t\t\t\t\t\t\t\t\"name\":   \"String\",\n\t\t\t\t\t\t\t\t\t\"ofType\": nil,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"defaultValue\": nil,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.ContainSubset(result.Data.(map[string]interface{}), expectedDataSubSet) {\n\t\tt.Fatalf(\"unexpected, result does not contain subset of expected data\")\n\t}\n}\n\nfunc TestIntrospection_SupportsThe__TypeRootField(t *testing.T) {\n\n\ttestType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"TestType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"testField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: testType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        __type(name: \"TestType\") {\n          name\n        }\n      }\n    `\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__type\": map[string]interface{}{\n\t\t\t\t\"name\": \"TestType\",\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestIntrospection_IdentifiesDeprecatedFields(t *testing.T) {\n\n\ttestType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"TestType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"nonDeprecated\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"deprecated\": &graphql.Field{\n\t\t\t\tType:              graphql.String,\n\t\t\t\tDeprecationReason: \"Removed in 1.0\",\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: testType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        __type(name: \"TestType\") {\n          name\n          fields(includeDeprecated: true) {\n            name\n            isDeprecated,\n            deprecationReason\n          }\n        }\n      }\n    `\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__type\": map[string]interface{}{\n\t\t\t\t\"name\": \"TestType\",\n\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":              \"nonDeprecated\",\n\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":              \"deprecated\",\n\t\t\t\t\t\t\"isDeprecated\":      true,\n\t\t\t\t\t\t\"deprecationReason\": \"Removed in 1.0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.ContainSubset(result.Data.(map[string]interface{}), expected.Data.(map[string]interface{})) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestIntrospection_RespectsTheIncludeDeprecatedParameterForFields(t *testing.T) {\n\n\ttestType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"TestType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"nonDeprecated\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"deprecated\": &graphql.Field{\n\t\t\t\tType:              graphql.String,\n\t\t\t\tDeprecationReason: \"Removed in 1.0\",\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: testType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        __type(name: \"TestType\") {\n          name\n          trueFields: fields(includeDeprecated: true) {\n            name\n          }\n          falseFields: fields(includeDeprecated: false) {\n            name\n          }\n          omittedFields: fields {\n            name\n          }\n        }\n      }\n    `\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__type\": map[string]interface{}{\n\t\t\t\t\"name\": \"TestType\",\n\t\t\t\t\"trueFields\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"nonDeprecated\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"deprecated\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"falseFields\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"nonDeprecated\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"omittedFields\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"nonDeprecated\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.ContainSubset(result.Data.(map[string]interface{}), expected.Data.(map[string]interface{})) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestIntrospection_IdentifiesDeprecatedEnumValues(t *testing.T) {\n\n\ttestEnum := graphql.NewEnum(graphql.EnumConfig{\n\t\tName: \"TestEnum\",\n\t\tValues: graphql.EnumValueConfigMap{\n\t\t\t\"NONDEPRECATED\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 0,\n\t\t\t},\n\t\t\t\"DEPRECATED\": &graphql.EnumValueConfig{\n\t\t\t\tValue:             1,\n\t\t\t\tDeprecationReason: \"Removed in 1.0\",\n\t\t\t},\n\t\t\t\"ALSONONDEPRECATED\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 2,\n\t\t\t},\n\t\t},\n\t})\n\ttestType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"TestType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"testEnum\": &graphql.Field{\n\t\t\t\tType: testEnum,\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: testType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        __type(name: \"TestEnum\") {\n          name\n          enumValues(includeDeprecated: true) {\n            name\n            isDeprecated,\n            deprecationReason\n          }\n        }\n      }\n    `\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__type\": map[string]interface{}{\n\t\t\t\t\"name\": \"TestEnum\",\n\t\t\t\t\"enumValues\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":              \"NONDEPRECATED\",\n\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":              \"DEPRECATED\",\n\t\t\t\t\t\t\"isDeprecated\":      true,\n\t\t\t\t\t\t\"deprecationReason\": \"Removed in 1.0\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":              \"ALSONONDEPRECATED\",\n\t\t\t\t\t\t\"isDeprecated\":      false,\n\t\t\t\t\t\t\"deprecationReason\": nil,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.ContainSubset(result.Data.(map[string]interface{}), expected.Data.(map[string]interface{})) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestIntrospection_RespectsTheIncludeDeprecatedParameterForEnumValues(t *testing.T) {\n\n\ttestEnum := graphql.NewEnum(graphql.EnumConfig{\n\t\tName: \"TestEnum\",\n\t\tValues: graphql.EnumValueConfigMap{\n\t\t\t\"NONDEPRECATED\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 0,\n\t\t\t},\n\t\t\t\"DEPRECATED\": &graphql.EnumValueConfig{\n\t\t\t\tValue:             1,\n\t\t\t\tDeprecationReason: \"Removed in 1.0\",\n\t\t\t},\n\t\t\t\"ALSONONDEPRECATED\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 2,\n\t\t\t},\n\t\t},\n\t})\n\ttestType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"TestType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"testEnum\": &graphql.Field{\n\t\t\t\tType: testEnum,\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: testType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        __type(name: \"TestEnum\") {\n          name\n          trueValues: enumValues(includeDeprecated: true) {\n            name\n          }\n          falseValues: enumValues(includeDeprecated: false) {\n            name\n          }\n          omittedValues: enumValues {\n            name\n          }\n        }\n      }\n    `\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__type\": map[string]interface{}{\n\t\t\t\t\"name\": \"TestEnum\",\n\t\t\t\t\"trueValues\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"NONDEPRECATED\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"DEPRECATED\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"ALSONONDEPRECATED\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"falseValues\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"NONDEPRECATED\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"ALSONONDEPRECATED\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"omittedValues\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"NONDEPRECATED\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"ALSONONDEPRECATED\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.ContainSubset(result.Data.(map[string]interface{}), expected.Data.(map[string]interface{})) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestIntrospection_FailsAsExpectedOnThe__TypeRootFieldWithoutAnArg(t *testing.T) {\n\n\ttestType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"TestType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"testField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: testType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        __type {\n          name\n        }\n      }\n    `\n\texpected := &graphql.Result{\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Field \"__type\" argument \"name\" of type \"String!\" ` +\n\t\t\t\t\t`is required but not provided.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 3, Column: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestIntrospection_ExposesDescriptionsOnTypesAndFields(t *testing.T) {\n\n\tqueryRoot := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"QueryRoot\",\n\t\tFields: graphql.Fields{\n\t\t\t\"onlyField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryRoot,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        schemaType: __type(name: \"__Schema\") {\n          name,\n          description,\n          fields {\n            name,\n            description\n          }\n        }\n      }\n    `\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"schemaType\": map[string]interface{}{\n\t\t\t\t\"name\": \"__Schema\",\n\t\t\t\t\"description\": `A GraphQL Schema defines the capabilities of a GraphQL ` +\n\t\t\t\t\t`server. It exposes all available types and directives on ` +\n\t\t\t\t\t`the server, as well as the entry points for query, mutation, ` +\n\t\t\t\t\t`and subscription operations.`,\n\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"types\",\n\t\t\t\t\t\t\"description\": \"A list of all types supported by this server.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"queryType\",\n\t\t\t\t\t\t\"description\": \"The type that query operations will be rooted at.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"mutationType\",\n\t\t\t\t\t\t\"description\": \"If this server supports mutation, the type that \" +\n\t\t\t\t\t\t\t\"mutation operations will be rooted at.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"subscriptionType\",\n\t\t\t\t\t\t\"description\": \"If this server support subscription, the type that \" +\n\t\t\t\t\t\t\t\"subscription operations will be rooted at.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"directives\",\n\t\t\t\t\t\t\"description\": \"A list of all directives supported by this server.\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.ContainSubset(result.Data.(map[string]interface{}), expected.Data.(map[string]interface{})) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestIntrospection_ExposesDescriptionsOnEnums(t *testing.T) {\n\n\tqueryRoot := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"QueryRoot\",\n\t\tFields: graphql.Fields{\n\t\t\t\"onlyField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryRoot,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error creating Schema: %v\", err.Error())\n\t}\n\tquery := `\n      {\n        typeKindType: __type(name: \"__TypeKind\") {\n          name,\n          description,\n          enumValues {\n            name,\n            description\n          }\n        }\n      }\n    `\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"typeKindType\": map[string]interface{}{\n\t\t\t\t\"name\":        \"__TypeKind\",\n\t\t\t\t\"description\": \"An enum describing what kind of type a given `__Type` is.\",\n\t\t\t\t\"enumValues\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"SCALAR\",\n\t\t\t\t\t\t\"description\": \"Indicates this type is a scalar.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"OBJECT\",\n\t\t\t\t\t\t\"description\": \"Indicates this type is an object. `fields` and `interfaces` are valid fields.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"INTERFACE\",\n\t\t\t\t\t\t\"description\": \"Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"UNION\",\n\t\t\t\t\t\t\"description\": \"Indicates this type is a union. `possibleTypes` is a valid field.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"ENUM\",\n\t\t\t\t\t\t\"description\": \"Indicates this type is an enum. `enumValues` is a valid field.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"INPUT_OBJECT\",\n\t\t\t\t\t\t\"description\": \"Indicates this type is an input object. `inputFields` is a valid field.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"LIST\",\n\t\t\t\t\t\t\"description\": \"Indicates this type is a list. `ofType` is a valid field.\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\":        \"NON_NULL\",\n\t\t\t\t\t\t\"description\": \"Indicates this type is a non-null. `ofType` is a valid field.\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        schema,\n\t\tRequestString: query,\n\t})\n\tif !testutil.ContainSubset(result.Data.(map[string]interface{}), expected.Data.(map[string]interface{})) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "kitchen-sink.graphql",
    "content": "# Filename: kitchen-sink.graphql\n\nquery namedQuery($foo: ComplexFooType, $bar: Bar = DefaultBarValue) {\n  customUser: user(id: [987, 654]) {\n    id,\n    ... on User @defer {\n      field2 {\n        id ,\n        alias: field1(first:10, after:$foo,) @include(if: $foo) {\n          id,\n          ...frag\n        }\n      }\n    }\n    ... @skip(unless: $foo) {\n      id\n    }\n    ... {\n      id\n    }\n  }\n}\n\nmutation favPost {\n  fav(post: 123) @defer {\n    post {\n      id\n    }\n  }\n}\n\nsubscription PostFavSubscription($input: StoryLikeSubscribeInput) {\n  postFavSubscribe(input: $input) {\n    post {\n      favers {\n        count\n      }\n      favSentence {\n        text\n      }\n    }\n  }\n}\n\nfragment frag on Follower {\n  foo(size: $size, bar: $b, obj: {key: \"value\"})\n}\n\n{\n  unnamed(truthyVal: true, falseyVal: false),\n  query\n}\n"
  },
  {
    "path": "language/ast/arguments.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\n// Argument implements Node\ntype Argument struct {\n\tKind  string\n\tLoc   *Location\n\tName  *Name\n\tValue Value\n}\n\nfunc NewArgument(arg *Argument) *Argument {\n\tif arg == nil {\n\t\targ = &Argument{}\n\t}\n\targ.Kind = kinds.Argument\n\treturn arg\n}\n\nfunc (arg *Argument) GetKind() string {\n\treturn arg.Kind\n}\n\nfunc (arg *Argument) GetLoc() *Location {\n\treturn arg.Loc\n}\n"
  },
  {
    "path": "language/ast/definitions.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\ntype Definition interface {\n\tGetOperation() string\n\tGetVariableDefinitions() []*VariableDefinition\n\tGetSelectionSet() *SelectionSet\n\tGetKind() string\n\tGetLoc() *Location\n}\n\n// Ensure that all definition types implements Definition interface\nvar _ Definition = (*OperationDefinition)(nil)\nvar _ Definition = (*FragmentDefinition)(nil)\nvar _ Definition = (TypeSystemDefinition)(nil) // experimental non-spec addition.\n\n// Note: subscription is an experimental non-spec addition.\nconst (\n\tOperationTypeQuery        = \"query\"\n\tOperationTypeMutation     = \"mutation\"\n\tOperationTypeSubscription = \"subscription\"\n)\n\n// OperationDefinition implements Node, Definition\ntype OperationDefinition struct {\n\tKind                string\n\tLoc                 *Location\n\tOperation           string\n\tName                *Name\n\tVariableDefinitions []*VariableDefinition\n\tDirectives          []*Directive\n\tSelectionSet        *SelectionSet\n}\n\nfunc NewOperationDefinition(op *OperationDefinition) *OperationDefinition {\n\tif op == nil {\n\t\top = &OperationDefinition{}\n\t}\n\top.Kind = kinds.OperationDefinition\n\treturn op\n}\n\nfunc (op *OperationDefinition) GetKind() string {\n\treturn op.Kind\n}\n\nfunc (op *OperationDefinition) GetLoc() *Location {\n\treturn op.Loc\n}\n\nfunc (op *OperationDefinition) GetOperation() string {\n\treturn op.Operation\n}\n\nfunc (op *OperationDefinition) GetName() *Name {\n\treturn op.Name\n}\n\nfunc (op *OperationDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn op.VariableDefinitions\n}\n\nfunc (op *OperationDefinition) GetDirectives() []*Directive {\n\treturn op.Directives\n}\n\nfunc (op *OperationDefinition) GetSelectionSet() *SelectionSet {\n\treturn op.SelectionSet\n}\n\n// FragmentDefinition implements Node, Definition\ntype FragmentDefinition struct {\n\tKind                string\n\tLoc                 *Location\n\tOperation           string\n\tName                *Name\n\tVariableDefinitions []*VariableDefinition\n\tTypeCondition       *Named\n\tDirectives          []*Directive\n\tSelectionSet        *SelectionSet\n}\n\nfunc NewFragmentDefinition(fd *FragmentDefinition) *FragmentDefinition {\n\tif fd == nil {\n\t\tfd = &FragmentDefinition{}\n\t}\n\treturn &FragmentDefinition{\n\t\tKind:                kinds.FragmentDefinition,\n\t\tLoc:                 fd.Loc,\n\t\tOperation:           fd.Operation,\n\t\tName:                fd.Name,\n\t\tVariableDefinitions: fd.VariableDefinitions,\n\t\tTypeCondition:       fd.TypeCondition,\n\t\tDirectives:          fd.Directives,\n\t\tSelectionSet:        fd.SelectionSet,\n\t}\n}\n\nfunc (fd *FragmentDefinition) GetKind() string {\n\treturn fd.Kind\n}\n\nfunc (fd *FragmentDefinition) GetLoc() *Location {\n\treturn fd.Loc\n}\n\nfunc (fd *FragmentDefinition) GetOperation() string {\n\treturn fd.Operation\n}\n\nfunc (fd *FragmentDefinition) GetName() *Name {\n\treturn fd.Name\n}\n\nfunc (fd *FragmentDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn fd.VariableDefinitions\n}\n\nfunc (fd *FragmentDefinition) GetSelectionSet() *SelectionSet {\n\treturn fd.SelectionSet\n}\n\n// VariableDefinition implements Node\ntype VariableDefinition struct {\n\tKind         string\n\tLoc          *Location\n\tVariable     *Variable\n\tType         Type\n\tDefaultValue Value\n}\n\nfunc NewVariableDefinition(vd *VariableDefinition) *VariableDefinition {\n\tif vd == nil {\n\t\tvd = &VariableDefinition{}\n\t}\n\tvd.Kind = kinds.VariableDefinition\n\treturn vd\n}\n\nfunc (vd *VariableDefinition) GetKind() string {\n\treturn vd.Kind\n}\n\nfunc (vd *VariableDefinition) GetLoc() *Location {\n\treturn vd.Loc\n}\n\n// TypeExtensionDefinition implements Node, Definition\ntype TypeExtensionDefinition struct {\n\tKind       string\n\tLoc        *Location\n\tDefinition *ObjectDefinition\n}\n\nfunc NewTypeExtensionDefinition(def *TypeExtensionDefinition) *TypeExtensionDefinition {\n\tif def == nil {\n\t\tdef = &TypeExtensionDefinition{}\n\t}\n\treturn &TypeExtensionDefinition{\n\t\tKind:       kinds.TypeExtensionDefinition,\n\t\tLoc:        def.Loc,\n\t\tDefinition: def.Definition,\n\t}\n}\n\nfunc (def *TypeExtensionDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *TypeExtensionDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *TypeExtensionDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *TypeExtensionDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *TypeExtensionDefinition) GetOperation() string {\n\treturn \"\"\n}\n\n// DirectiveDefinition implements Node, Definition\ntype DirectiveDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tName        *Name\n\tDescription *StringValue\n\tArguments   []*InputValueDefinition\n\tLocations   []*Name\n}\n\nfunc NewDirectiveDefinition(def *DirectiveDefinition) *DirectiveDefinition {\n\tif def == nil {\n\t\tdef = &DirectiveDefinition{}\n\t}\n\treturn &DirectiveDefinition{\n\t\tKind:        kinds.DirectiveDefinition,\n\t\tLoc:         def.Loc,\n\t\tName:        def.Name,\n\t\tDescription: def.Description,\n\t\tArguments:   def.Arguments,\n\t\tLocations:   def.Locations,\n\t}\n}\n\nfunc (def *DirectiveDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *DirectiveDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *DirectiveDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *DirectiveDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *DirectiveDefinition) GetOperation() string {\n\treturn \"\"\n}\n\nfunc (def *DirectiveDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n"
  },
  {
    "path": "language/ast/directives.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\n// Directive implements Node\ntype Directive struct {\n\tKind      string\n\tLoc       *Location\n\tName      *Name\n\tArguments []*Argument\n}\n\nfunc NewDirective(dir *Directive) *Directive {\n\tif dir == nil {\n\t\tdir = &Directive{}\n\t}\n\treturn &Directive{\n\t\tKind:      kinds.Directive,\n\t\tLoc:       dir.Loc,\n\t\tName:      dir.Name,\n\t\tArguments: dir.Arguments,\n\t}\n}\n\nfunc (dir *Directive) GetKind() string {\n\treturn dir.Kind\n}\n\nfunc (dir *Directive) GetLoc() *Location {\n\treturn dir.Loc\n}\n"
  },
  {
    "path": "language/ast/document.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\n// Document implements Node\ntype Document struct {\n\tKind        string\n\tLoc         *Location\n\tDefinitions []Node\n}\n\nfunc NewDocument(d *Document) *Document {\n\tif d == nil {\n\t\td = &Document{}\n\t}\n\treturn &Document{\n\t\tKind:        kinds.Document,\n\t\tLoc:         d.Loc,\n\t\tDefinitions: d.Definitions,\n\t}\n}\n\nfunc (node *Document) GetKind() string {\n\treturn node.Kind\n}\n\nfunc (node *Document) GetLoc() *Location {\n\treturn node.Loc\n}\n"
  },
  {
    "path": "language/ast/location.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\ntype Location struct {\n\tStart  int\n\tEnd    int\n\tSource *source.Source\n}\n\nfunc NewLocation(loc *Location) *Location {\n\tif loc == nil {\n\t\tloc = &Location{}\n\t}\n\treturn &Location{\n\t\tStart:  loc.Start,\n\t\tEnd:    loc.End,\n\t\tSource: loc.Source,\n\t}\n}\n"
  },
  {
    "path": "language/ast/name.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\n// Name implements Node\ntype Name struct {\n\tKind  string\n\tLoc   *Location\n\tValue string\n}\n\nfunc NewName(node *Name) *Name {\n\tif node == nil {\n\t\tnode = &Name{}\n\t}\n\tnode.Kind = kinds.Name\n\treturn node\n}\n\nfunc (node *Name) GetKind() string {\n\treturn node.Kind\n}\n\nfunc (node *Name) GetLoc() *Location {\n\treturn node.Loc\n}\n"
  },
  {
    "path": "language/ast/node.go",
    "content": "package ast\n\ntype Node interface {\n\tGetKind() string\n\tGetLoc() *Location\n}\n\n// The list of all possible AST node graphql.\n// Ensure that all node types implements Node interface\nvar _ Node = (*Name)(nil)\nvar _ Node = (*Document)(nil)\nvar _ Node = (*OperationDefinition)(nil)\nvar _ Node = (*VariableDefinition)(nil)\nvar _ Node = (*Variable)(nil)\nvar _ Node = (*SelectionSet)(nil)\nvar _ Node = (*Field)(nil)\nvar _ Node = (*Argument)(nil)\nvar _ Node = (*FragmentSpread)(nil)\nvar _ Node = (*InlineFragment)(nil)\nvar _ Node = (*FragmentDefinition)(nil)\nvar _ Node = (*IntValue)(nil)\nvar _ Node = (*FloatValue)(nil)\nvar _ Node = (*StringValue)(nil)\nvar _ Node = (*BooleanValue)(nil)\nvar _ Node = (*EnumValue)(nil)\nvar _ Node = (*ListValue)(nil)\nvar _ Node = (*ObjectValue)(nil)\nvar _ Node = (*ObjectField)(nil)\nvar _ Node = (*Directive)(nil)\nvar _ Node = (*Named)(nil)\nvar _ Node = (*List)(nil)\nvar _ Node = (*NonNull)(nil)\nvar _ Node = (*SchemaDefinition)(nil)\nvar _ Node = (*OperationTypeDefinition)(nil)\nvar _ Node = (*ScalarDefinition)(nil)\nvar _ Node = (*ObjectDefinition)(nil)\nvar _ Node = (*FieldDefinition)(nil)\nvar _ Node = (*InputValueDefinition)(nil)\nvar _ Node = (*InterfaceDefinition)(nil)\nvar _ Node = (*UnionDefinition)(nil)\nvar _ Node = (*EnumDefinition)(nil)\nvar _ Node = (*EnumValueDefinition)(nil)\nvar _ Node = (*InputObjectDefinition)(nil)\nvar _ Node = (*TypeExtensionDefinition)(nil)\nvar _ Node = (*DirectiveDefinition)(nil)\n"
  },
  {
    "path": "language/ast/selections.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\ntype Selection interface {\n\tGetSelectionSet() *SelectionSet\n}\n\n// Ensure that all definition types implements Selection interface\nvar _ Selection = (*Field)(nil)\nvar _ Selection = (*FragmentSpread)(nil)\nvar _ Selection = (*InlineFragment)(nil)\n\n// Field implements Node, Selection\ntype Field struct {\n\tKind         string\n\tLoc          *Location\n\tAlias        *Name\n\tName         *Name\n\tArguments    []*Argument\n\tDirectives   []*Directive\n\tSelectionSet *SelectionSet\n}\n\nfunc NewField(f *Field) *Field {\n\tif f == nil {\n\t\tf = &Field{}\n\t}\n\tf.Kind = kinds.Field\n\treturn f\n}\n\nfunc (f *Field) GetKind() string {\n\treturn f.Kind\n}\n\nfunc (f *Field) GetLoc() *Location {\n\treturn f.Loc\n}\n\nfunc (f *Field) GetSelectionSet() *SelectionSet {\n\treturn f.SelectionSet\n}\n\n// FragmentSpread implements Node, Selection\ntype FragmentSpread struct {\n\tKind       string\n\tLoc        *Location\n\tName       *Name\n\tDirectives []*Directive\n}\n\nfunc NewFragmentSpread(fs *FragmentSpread) *FragmentSpread {\n\tif fs == nil {\n\t\tfs = &FragmentSpread{}\n\t}\n\treturn &FragmentSpread{\n\t\tKind:       kinds.FragmentSpread,\n\t\tLoc:        fs.Loc,\n\t\tName:       fs.Name,\n\t\tDirectives: fs.Directives,\n\t}\n}\n\nfunc (fs *FragmentSpread) GetKind() string {\n\treturn fs.Kind\n}\n\nfunc (fs *FragmentSpread) GetLoc() *Location {\n\treturn fs.Loc\n}\n\nfunc (fs *FragmentSpread) GetSelectionSet() *SelectionSet {\n\treturn nil\n}\n\n// InlineFragment implements Node, Selection\ntype InlineFragment struct {\n\tKind          string\n\tLoc           *Location\n\tTypeCondition *Named\n\tDirectives    []*Directive\n\tSelectionSet  *SelectionSet\n}\n\nfunc NewInlineFragment(f *InlineFragment) *InlineFragment {\n\tif f == nil {\n\t\tf = &InlineFragment{}\n\t}\n\treturn &InlineFragment{\n\t\tKind:          kinds.InlineFragment,\n\t\tLoc:           f.Loc,\n\t\tTypeCondition: f.TypeCondition,\n\t\tDirectives:    f.Directives,\n\t\tSelectionSet:  f.SelectionSet,\n\t}\n}\n\nfunc (f *InlineFragment) GetKind() string {\n\treturn f.Kind\n}\n\nfunc (f *InlineFragment) GetLoc() *Location {\n\treturn f.Loc\n}\n\nfunc (f *InlineFragment) GetSelectionSet() *SelectionSet {\n\treturn f.SelectionSet\n}\n\n// SelectionSet implements Node\ntype SelectionSet struct {\n\tKind       string\n\tLoc        *Location\n\tSelections []Selection\n}\n\nfunc NewSelectionSet(ss *SelectionSet) *SelectionSet {\n\tif ss == nil {\n\t\tss = &SelectionSet{}\n\t}\n\tss.Kind = kinds.SelectionSet\n\treturn ss\n}\n\nfunc (ss *SelectionSet) GetKind() string {\n\treturn ss.Kind\n}\n\nfunc (ss *SelectionSet) GetLoc() *Location {\n\treturn ss.Loc\n}\n"
  },
  {
    "path": "language/ast/type_definitions.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\n// DescribableNode are nodes that have descriptions associated with them.\ntype DescribableNode interface {\n\tGetDescription() *StringValue\n}\n\ntype TypeDefinition interface {\n\tDescribableNode\n\tGetOperation() string\n\tGetVariableDefinitions() []*VariableDefinition\n\tGetSelectionSet() *SelectionSet\n\tGetKind() string\n\tGetLoc() *Location\n}\n\nvar _ TypeDefinition = (*ScalarDefinition)(nil)\nvar _ TypeDefinition = (*ObjectDefinition)(nil)\nvar _ TypeDefinition = (*InterfaceDefinition)(nil)\nvar _ TypeDefinition = (*UnionDefinition)(nil)\nvar _ TypeDefinition = (*EnumDefinition)(nil)\nvar _ TypeDefinition = (*InputObjectDefinition)(nil)\n\ntype TypeSystemDefinition interface {\n\tGetOperation() string\n\tGetVariableDefinitions() []*VariableDefinition\n\tGetSelectionSet() *SelectionSet\n\tGetKind() string\n\tGetLoc() *Location\n}\n\nvar _ TypeSystemDefinition = (*SchemaDefinition)(nil)\nvar _ TypeSystemDefinition = (TypeDefinition)(nil)\nvar _ TypeSystemDefinition = (*TypeExtensionDefinition)(nil)\nvar _ TypeSystemDefinition = (*DirectiveDefinition)(nil)\n\n// SchemaDefinition implements Node, Definition\ntype SchemaDefinition struct {\n\tKind           string\n\tLoc            *Location\n\tDirectives     []*Directive\n\tOperationTypes []*OperationTypeDefinition\n}\n\nfunc NewSchemaDefinition(def *SchemaDefinition) *SchemaDefinition {\n\tif def == nil {\n\t\tdef = &SchemaDefinition{}\n\t}\n\treturn &SchemaDefinition{\n\t\tKind:           kinds.SchemaDefinition,\n\t\tLoc:            def.Loc,\n\t\tDirectives:     def.Directives,\n\t\tOperationTypes: def.OperationTypes,\n\t}\n}\n\nfunc (def *SchemaDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *SchemaDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *SchemaDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *SchemaDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *SchemaDefinition) GetOperation() string {\n\treturn \"\"\n}\n\n// OperationTypeDefinition implements Node, Definition\ntype OperationTypeDefinition struct {\n\tKind      string\n\tLoc       *Location\n\tOperation string\n\tType      *Named\n}\n\nfunc NewOperationTypeDefinition(def *OperationTypeDefinition) *OperationTypeDefinition {\n\tif def == nil {\n\t\tdef = &OperationTypeDefinition{}\n\t}\n\treturn &OperationTypeDefinition{\n\t\tKind:      kinds.OperationTypeDefinition,\n\t\tLoc:       def.Loc,\n\t\tOperation: def.Operation,\n\t\tType:      def.Type,\n\t}\n}\n\nfunc (def *OperationTypeDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *OperationTypeDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\n// ScalarDefinition implements Node, Definition\ntype ScalarDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tDescription *StringValue\n\tName        *Name\n\tDirectives  []*Directive\n}\n\nfunc NewScalarDefinition(def *ScalarDefinition) *ScalarDefinition {\n\tif def == nil {\n\t\tdef = &ScalarDefinition{}\n\t}\n\treturn &ScalarDefinition{\n\t\tKind:        kinds.ScalarDefinition,\n\t\tLoc:         def.Loc,\n\t\tDescription: def.Description,\n\t\tName:        def.Name,\n\t\tDirectives:  def.Directives,\n\t}\n}\n\nfunc (def *ScalarDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *ScalarDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *ScalarDefinition) GetName() *Name {\n\treturn def.Name\n}\n\nfunc (def *ScalarDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *ScalarDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *ScalarDefinition) GetOperation() string {\n\treturn \"\"\n}\n\nfunc (def *ScalarDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n\n// ObjectDefinition implements Node, Definition\ntype ObjectDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tName        *Name\n\tDescription *StringValue\n\tInterfaces  []*Named\n\tDirectives  []*Directive\n\tFields      []*FieldDefinition\n}\n\nfunc NewObjectDefinition(def *ObjectDefinition) *ObjectDefinition {\n\tif def == nil {\n\t\tdef = &ObjectDefinition{}\n\t}\n\treturn &ObjectDefinition{\n\t\tKind:        kinds.ObjectDefinition,\n\t\tLoc:         def.Loc,\n\t\tName:        def.Name,\n\t\tDescription: def.Description,\n\t\tInterfaces:  def.Interfaces,\n\t\tDirectives:  def.Directives,\n\t\tFields:      def.Fields,\n\t}\n}\n\nfunc (def *ObjectDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *ObjectDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *ObjectDefinition) GetName() *Name {\n\treturn def.Name\n}\n\nfunc (def *ObjectDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *ObjectDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *ObjectDefinition) GetOperation() string {\n\treturn \"\"\n}\n\nfunc (def *ObjectDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n\n// FieldDefinition implements Node\ntype FieldDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tName        *Name\n\tDescription *StringValue\n\tArguments   []*InputValueDefinition\n\tType        Type\n\tDirectives  []*Directive\n}\n\nfunc NewFieldDefinition(def *FieldDefinition) *FieldDefinition {\n\tif def == nil {\n\t\tdef = &FieldDefinition{}\n\t}\n\treturn &FieldDefinition{\n\t\tKind:        kinds.FieldDefinition,\n\t\tLoc:         def.Loc,\n\t\tName:        def.Name,\n\t\tDescription: def.Description,\n\t\tArguments:   def.Arguments,\n\t\tType:        def.Type,\n\t\tDirectives:  def.Directives,\n\t}\n}\n\nfunc (def *FieldDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *FieldDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *FieldDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n\n// InputValueDefinition implements Node\ntype InputValueDefinition struct {\n\tKind         string\n\tLoc          *Location\n\tName         *Name\n\tDescription  *StringValue\n\tType         Type\n\tDefaultValue Value\n\tDirectives   []*Directive\n}\n\nfunc NewInputValueDefinition(def *InputValueDefinition) *InputValueDefinition {\n\tif def == nil {\n\t\tdef = &InputValueDefinition{}\n\t}\n\treturn &InputValueDefinition{\n\t\tKind:         kinds.InputValueDefinition,\n\t\tLoc:          def.Loc,\n\t\tName:         def.Name,\n\t\tDescription:  def.Description,\n\t\tType:         def.Type,\n\t\tDefaultValue: def.DefaultValue,\n\t\tDirectives:   def.Directives,\n\t}\n}\n\nfunc (def *InputValueDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *InputValueDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *InputValueDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n\n// InterfaceDefinition implements Node, Definition\ntype InterfaceDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tName        *Name\n\tDescription *StringValue\n\tDirectives  []*Directive\n\tFields      []*FieldDefinition\n}\n\nfunc NewInterfaceDefinition(def *InterfaceDefinition) *InterfaceDefinition {\n\tif def == nil {\n\t\tdef = &InterfaceDefinition{}\n\t}\n\treturn &InterfaceDefinition{\n\t\tKind:        kinds.InterfaceDefinition,\n\t\tLoc:         def.Loc,\n\t\tName:        def.Name,\n\t\tDescription: def.Description,\n\t\tDirectives:  def.Directives,\n\t\tFields:      def.Fields,\n\t}\n}\n\nfunc (def *InterfaceDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *InterfaceDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *InterfaceDefinition) GetName() *Name {\n\treturn def.Name\n}\n\nfunc (def *InterfaceDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *InterfaceDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *InterfaceDefinition) GetOperation() string {\n\treturn \"\"\n}\n\nfunc (def *InterfaceDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n\n// UnionDefinition implements Node, Definition\ntype UnionDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tName        *Name\n\tDescription *StringValue\n\tDirectives  []*Directive\n\tTypes       []*Named\n}\n\nfunc NewUnionDefinition(def *UnionDefinition) *UnionDefinition {\n\tif def == nil {\n\t\tdef = &UnionDefinition{}\n\t}\n\treturn &UnionDefinition{\n\t\tKind:        kinds.UnionDefinition,\n\t\tLoc:         def.Loc,\n\t\tName:        def.Name,\n\t\tDescription: def.Description,\n\t\tDirectives:  def.Directives,\n\t\tTypes:       def.Types,\n\t}\n}\n\nfunc (def *UnionDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *UnionDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *UnionDefinition) GetName() *Name {\n\treturn def.Name\n}\n\nfunc (def *UnionDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *UnionDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *UnionDefinition) GetOperation() string {\n\treturn \"\"\n}\n\nfunc (def *UnionDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n\n// EnumDefinition implements Node, Definition\ntype EnumDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tName        *Name\n\tDescription *StringValue\n\tDirectives  []*Directive\n\tValues      []*EnumValueDefinition\n}\n\nfunc NewEnumDefinition(def *EnumDefinition) *EnumDefinition {\n\tif def == nil {\n\t\tdef = &EnumDefinition{}\n\t}\n\treturn &EnumDefinition{\n\t\tKind:        kinds.EnumDefinition,\n\t\tLoc:         def.Loc,\n\t\tName:        def.Name,\n\t\tDescription: def.Description,\n\t\tDirectives:  def.Directives,\n\t\tValues:      def.Values,\n\t}\n}\n\nfunc (def *EnumDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *EnumDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *EnumDefinition) GetName() *Name {\n\treturn def.Name\n}\n\nfunc (def *EnumDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *EnumDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *EnumDefinition) GetOperation() string {\n\treturn \"\"\n}\n\nfunc (def *EnumDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n\n// EnumValueDefinition implements Node, Definition\ntype EnumValueDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tName        *Name\n\tDescription *StringValue\n\tDirectives  []*Directive\n}\n\nfunc NewEnumValueDefinition(def *EnumValueDefinition) *EnumValueDefinition {\n\tif def == nil {\n\t\tdef = &EnumValueDefinition{}\n\t}\n\treturn &EnumValueDefinition{\n\t\tKind:        kinds.EnumValueDefinition,\n\t\tLoc:         def.Loc,\n\t\tName:        def.Name,\n\t\tDescription: def.Description,\n\t\tDirectives:  def.Directives,\n\t}\n}\n\nfunc (def *EnumValueDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *EnumValueDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *EnumValueDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n\n// InputObjectDefinition implements Node, Definition\ntype InputObjectDefinition struct {\n\tKind        string\n\tLoc         *Location\n\tName        *Name\n\tDescription *StringValue\n\tDirectives  []*Directive\n\tFields      []*InputValueDefinition\n}\n\nfunc NewInputObjectDefinition(def *InputObjectDefinition) *InputObjectDefinition {\n\tif def == nil {\n\t\tdef = &InputObjectDefinition{}\n\t}\n\treturn &InputObjectDefinition{\n\t\tKind:        kinds.InputObjectDefinition,\n\t\tLoc:         def.Loc,\n\t\tName:        def.Name,\n\t\tDescription: def.Description,\n\t\tDirectives:  def.Directives,\n\t\tFields:      def.Fields,\n\t}\n}\n\nfunc (def *InputObjectDefinition) GetKind() string {\n\treturn def.Kind\n}\n\nfunc (def *InputObjectDefinition) GetLoc() *Location {\n\treturn def.Loc\n}\n\nfunc (def *InputObjectDefinition) GetName() *Name {\n\treturn def.Name\n}\n\nfunc (def *InputObjectDefinition) GetVariableDefinitions() []*VariableDefinition {\n\treturn []*VariableDefinition{}\n}\n\nfunc (def *InputObjectDefinition) GetSelectionSet() *SelectionSet {\n\treturn &SelectionSet{}\n}\n\nfunc (def *InputObjectDefinition) GetOperation() string {\n\treturn \"\"\n}\n\nfunc (def *InputObjectDefinition) GetDescription() *StringValue {\n\treturn def.Description\n}\n"
  },
  {
    "path": "language/ast/types.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\ntype Type interface {\n\tGetKind() string\n\tGetLoc() *Location\n\tString() string\n}\n\n// Ensure that all value types implements Value interface\nvar _ Type = (*Named)(nil)\nvar _ Type = (*List)(nil)\nvar _ Type = (*NonNull)(nil)\n\n// Named implements Node, Type\ntype Named struct {\n\tKind string\n\tLoc  *Location\n\tName *Name\n}\n\nfunc NewNamed(t *Named) *Named {\n\tif t == nil {\n\t\tt = &Named{}\n\t}\n\tt.Kind = kinds.Named\n\treturn t\n}\n\nfunc (t *Named) GetKind() string {\n\treturn t.Kind\n}\n\nfunc (t *Named) GetLoc() *Location {\n\treturn t.Loc\n}\n\nfunc (t *Named) String() string {\n\treturn t.GetKind()\n}\n\n// List implements Node, Type\ntype List struct {\n\tKind string\n\tLoc  *Location\n\tType Type\n}\n\nfunc NewList(t *List) *List {\n\tif t == nil {\n\t\tt = &List{}\n\t}\n\treturn &List{\n\t\tKind: kinds.List,\n\t\tLoc:  t.Loc,\n\t\tType: t.Type,\n\t}\n}\n\nfunc (t *List) GetKind() string {\n\treturn t.Kind\n}\n\nfunc (t *List) GetLoc() *Location {\n\treturn t.Loc\n}\n\nfunc (t *List) String() string {\n\treturn t.GetKind()\n}\n\n// NonNull implements Node, Type\ntype NonNull struct {\n\tKind string\n\tLoc  *Location\n\tType Type\n}\n\nfunc NewNonNull(t *NonNull) *NonNull {\n\tif t == nil {\n\t\tt = &NonNull{}\n\t}\n\treturn &NonNull{\n\t\tKind: kinds.NonNull,\n\t\tLoc:  t.Loc,\n\t\tType: t.Type,\n\t}\n}\n\nfunc (t *NonNull) GetKind() string {\n\treturn t.Kind\n}\n\nfunc (t *NonNull) GetLoc() *Location {\n\treturn t.Loc\n}\n\nfunc (t *NonNull) String() string {\n\treturn t.GetKind()\n}\n"
  },
  {
    "path": "language/ast/values.go",
    "content": "package ast\n\nimport (\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\ntype Value interface {\n\tGetValue() interface{}\n\tGetKind() string\n\tGetLoc() *Location\n}\n\n// Ensure that all value types implements Value interface\nvar _ Value = (*Variable)(nil)\nvar _ Value = (*IntValue)(nil)\nvar _ Value = (*FloatValue)(nil)\nvar _ Value = (*StringValue)(nil)\nvar _ Value = (*BooleanValue)(nil)\nvar _ Value = (*EnumValue)(nil)\nvar _ Value = (*ListValue)(nil)\nvar _ Value = (*ObjectValue)(nil)\n\n// Variable implements Node, Value\ntype Variable struct {\n\tKind string\n\tLoc  *Location\n\tName *Name\n}\n\nfunc NewVariable(v *Variable) *Variable {\n\tif v == nil {\n\t\tv = &Variable{}\n\t}\n\tv.Kind = kinds.Variable\n\treturn v\n}\n\nfunc (v *Variable) GetKind() string {\n\treturn v.Kind\n}\n\nfunc (v *Variable) GetLoc() *Location {\n\treturn v.Loc\n}\n\n// GetValue alias to Variable.GetName()\nfunc (v *Variable) GetValue() interface{} {\n\treturn v.GetName()\n}\n\nfunc (v *Variable) GetName() interface{} {\n\treturn v.Name\n}\n\n// IntValue implements Node, Value\ntype IntValue struct {\n\tKind  string\n\tLoc   *Location\n\tValue string\n}\n\nfunc NewIntValue(v *IntValue) *IntValue {\n\tif v == nil {\n\t\tv = &IntValue{}\n\t}\n\treturn &IntValue{\n\t\tKind:  kinds.IntValue,\n\t\tLoc:   v.Loc,\n\t\tValue: v.Value,\n\t}\n}\n\nfunc (v *IntValue) GetKind() string {\n\treturn v.Kind\n}\n\nfunc (v *IntValue) GetLoc() *Location {\n\treturn v.Loc\n}\n\nfunc (v *IntValue) GetValue() interface{} {\n\treturn v.Value\n}\n\n// FloatValue implements Node, Value\ntype FloatValue struct {\n\tKind  string\n\tLoc   *Location\n\tValue string\n}\n\nfunc NewFloatValue(v *FloatValue) *FloatValue {\n\tif v == nil {\n\t\tv = &FloatValue{}\n\t}\n\treturn &FloatValue{\n\t\tKind:  kinds.FloatValue,\n\t\tLoc:   v.Loc,\n\t\tValue: v.Value,\n\t}\n}\n\nfunc (v *FloatValue) GetKind() string {\n\treturn v.Kind\n}\n\nfunc (v *FloatValue) GetLoc() *Location {\n\treturn v.Loc\n}\n\nfunc (v *FloatValue) GetValue() interface{} {\n\treturn v.Value\n}\n\n// StringValue implements Node, Value\ntype StringValue struct {\n\tKind  string\n\tLoc   *Location\n\tValue string\n}\n\nfunc NewStringValue(v *StringValue) *StringValue {\n\tif v == nil {\n\t\tv = &StringValue{}\n\t}\n\treturn &StringValue{\n\t\tKind:  kinds.StringValue,\n\t\tLoc:   v.Loc,\n\t\tValue: v.Value,\n\t}\n}\n\nfunc (v *StringValue) GetKind() string {\n\treturn v.Kind\n}\n\nfunc (v *StringValue) GetLoc() *Location {\n\treturn v.Loc\n}\n\nfunc (v *StringValue) GetValue() interface{} {\n\treturn v.Value\n}\n\n// BooleanValue implements Node, Value\ntype BooleanValue struct {\n\tKind  string\n\tLoc   *Location\n\tValue bool\n}\n\nfunc NewBooleanValue(v *BooleanValue) *BooleanValue {\n\tif v == nil {\n\t\tv = &BooleanValue{}\n\t}\n\treturn &BooleanValue{\n\t\tKind:  kinds.BooleanValue,\n\t\tLoc:   v.Loc,\n\t\tValue: v.Value,\n\t}\n}\n\nfunc (v *BooleanValue) GetKind() string {\n\treturn v.Kind\n}\n\nfunc (v *BooleanValue) GetLoc() *Location {\n\treturn v.Loc\n}\n\nfunc (v *BooleanValue) GetValue() interface{} {\n\treturn v.Value\n}\n\n// EnumValue implements Node, Value\ntype EnumValue struct {\n\tKind  string\n\tLoc   *Location\n\tValue string\n}\n\nfunc NewEnumValue(v *EnumValue) *EnumValue {\n\tif v == nil {\n\t\tv = &EnumValue{}\n\t}\n\treturn &EnumValue{\n\t\tKind:  kinds.EnumValue,\n\t\tLoc:   v.Loc,\n\t\tValue: v.Value,\n\t}\n}\n\nfunc (v *EnumValue) GetKind() string {\n\treturn v.Kind\n}\n\nfunc (v *EnumValue) GetLoc() *Location {\n\treturn v.Loc\n}\n\nfunc (v *EnumValue) GetValue() interface{} {\n\treturn v.Value\n}\n\n// ListValue implements Node, Value\ntype ListValue struct {\n\tKind   string\n\tLoc    *Location\n\tValues []Value\n}\n\nfunc NewListValue(v *ListValue) *ListValue {\n\tif v == nil {\n\t\tv = &ListValue{}\n\t}\n\treturn &ListValue{\n\t\tKind:   kinds.ListValue,\n\t\tLoc:    v.Loc,\n\t\tValues: v.Values,\n\t}\n}\n\nfunc (v *ListValue) GetKind() string {\n\treturn v.Kind\n}\n\nfunc (v *ListValue) GetLoc() *Location {\n\treturn v.Loc\n}\n\n// GetValue alias to ListValue.GetValues()\nfunc (v *ListValue) GetValue() interface{} {\n\treturn v.GetValues()\n}\n\nfunc (v *ListValue) GetValues() interface{} {\n\t// TODO: verify ObjectValue.GetValue()\n\treturn v.Values\n}\n\n// ObjectValue implements Node, Value\ntype ObjectValue struct {\n\tKind   string\n\tLoc    *Location\n\tFields []*ObjectField\n}\n\nfunc NewObjectValue(v *ObjectValue) *ObjectValue {\n\tif v == nil {\n\t\tv = &ObjectValue{}\n\t}\n\treturn &ObjectValue{\n\t\tKind:   kinds.ObjectValue,\n\t\tLoc:    v.Loc,\n\t\tFields: v.Fields,\n\t}\n}\n\nfunc (v *ObjectValue) GetKind() string {\n\treturn v.Kind\n}\n\nfunc (v *ObjectValue) GetLoc() *Location {\n\treturn v.Loc\n}\n\nfunc (v *ObjectValue) GetValue() interface{} {\n\t// TODO: verify ObjectValue.GetValue()\n\treturn v.Fields\n}\n\n// ObjectField implements Node, Value\ntype ObjectField struct {\n\tKind  string\n\tName  *Name\n\tLoc   *Location\n\tValue Value\n}\n\nfunc NewObjectField(f *ObjectField) *ObjectField {\n\tif f == nil {\n\t\tf = &ObjectField{}\n\t}\n\treturn &ObjectField{\n\t\tKind:  kinds.ObjectField,\n\t\tLoc:   f.Loc,\n\t\tName:  f.Name,\n\t\tValue: f.Value,\n\t}\n}\n\nfunc (f *ObjectField) GetKind() string {\n\treturn f.Kind\n}\n\nfunc (f *ObjectField) GetLoc() *Location {\n\treturn f.Loc\n}\n\nfunc (f *ObjectField) GetValue() interface{} {\n\treturn f.Value\n}\n"
  },
  {
    "path": "language/kinds/kinds.go",
    "content": "package kinds\n\nconst (\n\t// Name\n\tName = \"Name\"\n\n\t// Document\n\tDocument            = \"Document\"\n\tOperationDefinition = \"OperationDefinition\"\n\tVariableDefinition  = \"VariableDefinition\"\n\tVariable            = \"Variable\"\n\tSelectionSet        = \"SelectionSet\"\n\tField               = \"Field\"\n\tArgument            = \"Argument\"\n\n\t// Fragments\n\tFragmentSpread     = \"FragmentSpread\"\n\tInlineFragment     = \"InlineFragment\"\n\tFragmentDefinition = \"FragmentDefinition\"\n\n\t// Values\n\tIntValue     = \"IntValue\"\n\tFloatValue   = \"FloatValue\"\n\tStringValue  = \"StringValue\"\n\tBooleanValue = \"BooleanValue\"\n\tEnumValue    = \"EnumValue\"\n\tListValue    = \"ListValue\"\n\tObjectValue  = \"ObjectValue\"\n\tObjectField  = \"ObjectField\"\n\n\t// Directives\n\tDirective = \"Directive\"\n\n\t// Types\n\tNamed   = \"Named\"   // previously NamedType\n\tList    = \"List\"    // previously ListType\n\tNonNull = \"NonNull\" // previously NonNull\n\n\t// Type System Definitions\n\tSchemaDefinition        = \"SchemaDefinition\"\n\tOperationTypeDefinition = \"OperationTypeDefinition\"\n\n\t// Types Definitions\n\tScalarDefinition      = \"ScalarDefinition\" // previously ScalarTypeDefinition\n\tObjectDefinition      = \"ObjectDefinition\" // previously ObjectTypeDefinition\n\tFieldDefinition       = \"FieldDefinition\"\n\tInputValueDefinition  = \"InputValueDefinition\"\n\tInterfaceDefinition   = \"InterfaceDefinition\" // previously InterfaceTypeDefinition\n\tUnionDefinition       = \"UnionDefinition\"     // previously UnionTypeDefinition\n\tEnumDefinition        = \"EnumDefinition\"      // previously EnumTypeDefinition\n\tEnumValueDefinition   = \"EnumValueDefinition\"\n\tInputObjectDefinition = \"InputObjectDefinition\" // previously InputObjectTypeDefinition\n\n\t// Types Extensions\n\tTypeExtensionDefinition = \"TypeExtensionDefinition\"\n\n\t// Directive Definitions\n\tDirectiveDefinition = \"DirectiveDefinition\"\n)\n"
  },
  {
    "path": "language/lexer/lexer.go",
    "content": "package lexer\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\ntype TokenKind int\n\nconst (\n\tEOF TokenKind = iota + 1\n\tBANG\n\tDOLLAR\n\tPAREN_L\n\tPAREN_R\n\tSPREAD\n\tCOLON\n\tEQUALS\n\tAT\n\tBRACKET_L\n\tBRACKET_R\n\tBRACE_L\n\tPIPE\n\tBRACE_R\n\tNAME\n\tINT\n\tFLOAT\n\tSTRING\n\tBLOCK_STRING\n\tAMP\n)\n\nvar tokenDescription = map[TokenKind]string{\n\tEOF:          \"EOF\",\n\tBANG:         \"!\",\n\tDOLLAR:       \"$\",\n\tPAREN_L:      \"(\",\n\tPAREN_R:      \")\",\n\tSPREAD:       \"...\",\n\tCOLON:        \":\",\n\tEQUALS:       \"=\",\n\tAT:           \"@\",\n\tBRACKET_L:    \"[\",\n\tBRACKET_R:    \"]\",\n\tBRACE_L:      \"{\",\n\tPIPE:         \"|\",\n\tBRACE_R:      \"}\",\n\tNAME:         \"Name\",\n\tINT:          \"Int\",\n\tFLOAT:        \"Float\",\n\tSTRING:       \"String\",\n\tBLOCK_STRING: \"BlockString\",\n\tAMP:          \"&\",\n}\n\nfunc (kind TokenKind) String() string {\n\treturn tokenDescription[kind]\n}\n\n// NAME -> keyword relationship\nconst (\n\tFRAGMENT     = \"fragment\"\n\tQUERY        = \"query\"\n\tMUTATION     = \"mutation\"\n\tSUBSCRIPTION = \"subscription\"\n\tSCHEMA       = \"schema\"\n\tSCALAR       = \"scalar\"\n\tTYPE         = \"type\"\n\tINTERFACE    = \"interface\"\n\tUNION        = \"union\"\n\tENUM         = \"enum\"\n\tINPUT        = \"input\"\n\tEXTEND       = \"extend\"\n\tDIRECTIVE    = \"directive\"\n)\n\n// Token is a representation of a lexed Token. Value only appears for non-punctuation\n// tokens: NAME, INT, FLOAT, and STRING.\ntype Token struct {\n\tKind  TokenKind\n\tStart int\n\tEnd   int\n\tValue string\n}\n\ntype Lexer func(resetPosition int) (Token, error)\n\nfunc Lex(s *source.Source) Lexer {\n\tvar prevPosition int\n\treturn func(resetPosition int) (Token, error) {\n\t\tif resetPosition == 0 {\n\t\t\tresetPosition = prevPosition\n\t\t}\n\t\ttoken, err := readToken(s, resetPosition)\n\t\tif err != nil {\n\t\t\treturn token, err\n\t\t}\n\t\tprevPosition = token.End\n\t\treturn token, nil\n\t}\n}\n\n// Reads an alphanumeric + underscore name from the source.\n// [_A-Za-z][_0-9A-Za-z]*\n// position: Points to the byte position in the byte array\n// runePosition: Points to the rune position in the byte array\nfunc readName(source *source.Source, position, runePosition int) Token {\n\tbody := source.Body\n\tbodyLength := len(body)\n\tendByte := position + 1\n\tendRune := runePosition + 1\n\tfor {\n\t\tcode, _ := runeAt(body, endByte)\n\t\tif (endByte != bodyLength) &&\n\t\t\t(code == '_' || // _\n\t\t\t\tcode >= '0' && code <= '9' || // 0-9\n\t\t\t\tcode >= 'A' && code <= 'Z' || // A-Z\n\t\t\t\tcode >= 'a' && code <= 'z') { // a-z\n\t\t\tendByte++\n\t\t\tendRune++\n\t\t\tcontinue\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn makeToken(NAME, runePosition, endRune, string(body[position:endByte]))\n}\n\n// Reads a number token from the source file, either a float\n// or an int depending on whether a decimal point appears.\n// Int:   -?(0|[1-9][0-9]*)\n// Float: -?(0|[1-9][0-9]*)(\\.[0-9]+)?((E|e)(+|-)?[0-9]+)?\nfunc readNumber(s *source.Source, start int, firstCode rune, codeLength int) (Token, error) {\n\tcode := firstCode\n\tbody := s.Body\n\tposition := start\n\tisFloat := false\n\tif code == '-' { // -\n\t\tposition += codeLength\n\t\tcode, codeLength = runeAt(body, position)\n\t}\n\tif code == '0' { // 0\n\t\tposition += codeLength\n\t\tcode, codeLength = runeAt(body, position)\n\t\tif code >= '0' && code <= '9' {\n\t\t\tdescription := fmt.Sprintf(\"Invalid number, unexpected digit after 0: %v.\", printCharCode(code))\n\t\t\treturn Token{}, gqlerrors.NewSyntaxError(s, position, description)\n\t\t}\n\t} else {\n\t\tp, err := readDigits(s, position, code, codeLength)\n\t\tif err != nil {\n\t\t\treturn Token{}, err\n\t\t}\n\t\tposition = p\n\t\tcode, codeLength = runeAt(body, position)\n\t}\n\tif code == '.' { // .\n\t\tisFloat = true\n\t\tposition += codeLength\n\t\tcode, codeLength = runeAt(body, position)\n\t\tp, err := readDigits(s, position, code, codeLength)\n\t\tif err != nil {\n\t\t\treturn Token{}, err\n\t\t}\n\t\tposition = p\n\t\tcode, codeLength = runeAt(body, position)\n\t}\n\tif code == 'E' || code == 'e' { // E e\n\t\tisFloat = true\n\t\tposition += codeLength\n\t\tcode, codeLength = runeAt(body, position)\n\t\tif code == '+' || code == '-' { // + -\n\t\t\tposition += codeLength\n\t\t\tcode, codeLength = runeAt(body, position)\n\t\t}\n\t\tp, err := readDigits(s, position, code, codeLength)\n\t\tif err != nil {\n\t\t\treturn Token{}, err\n\t\t}\n\t\tposition = p\n\t}\n\tkind := INT\n\tif isFloat {\n\t\tkind = FLOAT\n\t}\n\n\treturn makeToken(kind, start, position, string(body[start:position])), nil\n}\n\n// Returns the new position in the source after reading digits.\nfunc readDigits(s *source.Source, start int, firstCode rune, codeLength int) (int, error) {\n\tbody := s.Body\n\tposition := start\n\tcode := firstCode\n\tif code >= '0' && code <= '9' { // 0 - 9\n\t\tfor {\n\t\t\tif code >= '0' && code <= '9' { // 0 - 9\n\t\t\t\tposition += codeLength\n\t\t\t\tcode, codeLength = runeAt(body, position)\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn position, nil\n\t}\n\tvar description string\n\tdescription = fmt.Sprintf(\"Invalid number, expected digit but got: %v.\", printCharCode(code))\n\treturn position, gqlerrors.NewSyntaxError(s, position, description)\n}\n\nfunc readString(s *source.Source, start int) (Token, error) {\n\tbody := s.Body\n\tposition := start + 1\n\trunePosition := start + 1\n\tchunkStart := position\n\tvar code rune\n\tvar n int\n\tvar valueBuffer bytes.Buffer\n\tfor {\n\t\tcode, n = runeAt(body, position)\n\t\tif position < len(body) &&\n\t\t\t// not LineTerminator\n\t\t\tcode != 0x000A && code != 0x000D &&\n\t\t\t// not Quote (\")\n\t\t\tcode != '\"' {\n\n\t\t\t// SourceCharacter\n\t\t\tif code < 0x0020 && code != 0x0009 {\n\t\t\t\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition, fmt.Sprintf(`Invalid character within String: %v.`, printCharCode(code)))\n\t\t\t}\n\t\t\tposition += n\n\t\t\trunePosition++\n\t\t\tif code == '\\\\' { // \\\n\t\t\t\tvalueBuffer.Write(body[chunkStart : position-1])\n\t\t\t\tcode, n = runeAt(body, position)\n\t\t\t\tswitch code {\n\t\t\t\tcase '\"':\n\t\t\t\t\tvalueBuffer.WriteRune('\"')\n\t\t\t\t\tbreak\n\t\t\t\tcase '/':\n\t\t\t\t\tvalueBuffer.WriteRune('/')\n\t\t\t\t\tbreak\n\t\t\t\tcase '\\\\':\n\t\t\t\t\tvalueBuffer.WriteRune('\\\\')\n\t\t\t\t\tbreak\n\t\t\t\tcase 'b':\n\t\t\t\t\tvalueBuffer.WriteRune('\\b')\n\t\t\t\t\tbreak\n\t\t\t\tcase 'f':\n\t\t\t\t\tvalueBuffer.WriteRune('\\f')\n\t\t\t\t\tbreak\n\t\t\t\tcase 'n':\n\t\t\t\t\tvalueBuffer.WriteRune('\\n')\n\t\t\t\t\tbreak\n\t\t\t\tcase 'r':\n\t\t\t\t\tvalueBuffer.WriteRune('\\r')\n\t\t\t\t\tbreak\n\t\t\t\tcase 't':\n\t\t\t\t\tvalueBuffer.WriteRune('\\t')\n\t\t\t\t\tbreak\n\t\t\t\tcase 'u':\n\t\t\t\t\t// Check if there are at least 4 bytes available\n\t\t\t\t\tif len(body) <= position+4 {\n\t\t\t\t\t\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition,\n\t\t\t\t\t\t\tfmt.Sprintf(\"Invalid character escape sequence: \"+\n\t\t\t\t\t\t\t\t\"\\\\u%v\", string(body[position+1:])))\n\t\t\t\t\t}\n\t\t\t\t\tcharCode := uniCharCode(\n\t\t\t\t\t\trune(body[position+1]),\n\t\t\t\t\t\trune(body[position+2]),\n\t\t\t\t\t\trune(body[position+3]),\n\t\t\t\t\t\trune(body[position+4]),\n\t\t\t\t\t)\n\t\t\t\t\tif charCode < 0 {\n\t\t\t\t\t\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition,\n\t\t\t\t\t\t\tfmt.Sprintf(\"Invalid character escape sequence: \"+\n\t\t\t\t\t\t\t\t\"\\\\u%v\", string(body[position+1:position+5])))\n\t\t\t\t\t}\n\t\t\t\t\tvalueBuffer.WriteRune(charCode)\n\t\t\t\t\tposition += 4\n\t\t\t\t\trunePosition += 4\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition,\n\t\t\t\t\t\tfmt.Sprintf(`Invalid character escape sequence: \\\\%c.`, code))\n\t\t\t\t}\n\t\t\t\tposition += n\n\t\t\t\trunePosition++\n\t\t\t\tchunkStart = position\n\t\t\t}\n\t\t\tcontinue\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\tif code != '\"' { // quote (\")\n\t\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition, \"Unterminated string.\")\n\t}\n\tstringContent := body[chunkStart:position]\n\tvalueBuffer.Write(stringContent)\n\tvalue := valueBuffer.String()\n\treturn makeToken(STRING, start, position+1, value), nil\n}\n\n// readBlockString reads a block string token from the source file.\n//\n// \"\"\"(\"?\"?(\\\\\"\"\"|\\\\(?!=\"\"\")|[^\"\\\\]))*\"\"\"\nfunc readBlockString(s *source.Source, start int) (Token, error) {\n\tbody := s.Body\n\tposition := start + 3\n\trunePosition := start + 3\n\tchunkStart := position\n\tvar valueBuffer bytes.Buffer\n\n\tfor {\n\t\t// Stop if we've reached the end of the buffer\n\t\tif position >= len(body) {\n\t\t\tbreak\n\t\t}\n\n\t\tcode, n := runeAt(body, position)\n\n\t\t// Closing Triple-Quote (\"\"\")\n\t\tif code == '\"' {\n\t\t\tx, _ := runeAt(body, position+1)\n\t\t\ty, _ := runeAt(body, position+2)\n\t\t\tif x == '\"' && y == '\"' {\n\t\t\t\tstringContent := body[chunkStart:position]\n\t\t\t\tvalueBuffer.Write(stringContent)\n\t\t\t\tvalue := blockStringValue(valueBuffer.String())\n\t\t\t\treturn makeToken(BLOCK_STRING, start, position+3, value), nil\n\t\t\t}\n\t\t}\n\n\t\t// SourceCharacter\n\t\tif code < 0x0020 &&\n\t\t\tcode != 0x0009 &&\n\t\t\tcode != 0x000a &&\n\t\t\tcode != 0x000d {\n\t\t\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition, fmt.Sprintf(`Invalid character within String: %v.`, printCharCode(code)))\n\t\t}\n\n\t\t// Escape Triple-Quote (\\\"\"\")\n\t\tif code == '\\\\' { // \\\n\t\t\tx, _ := runeAt(body, position+1)\n\t\t\ty, _ := runeAt(body, position+2)\n\t\t\tz, _ := runeAt(body, position+3)\n\t\t\tif x == '\"' && y == '\"' && z == '\"' {\n\t\t\t\tstringContent := append(body[chunkStart:position], []byte(`\"\"\"`)...)\n\t\t\t\tvalueBuffer.Write(stringContent)\n\t\t\t\tposition += 4     // account for `\"\"\"` characters\n\t\t\t\trunePosition += 4 // \"       \"   \"     \"\n\t\t\t\tchunkStart = position\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tposition += n\n\t\trunePosition++\n\t}\n\n\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition, \"Unterminated string.\")\n}\n\nvar splitLinesRegex = regexp.MustCompile(\"\\r\\n|[\\n\\r]\")\n\n// This implements the GraphQL spec's BlockStringValue() static algorithm.\n//\n// Produces the value of a block string from its parsed raw value, similar to\n// Coffeescript's block string, Python's docstring trim or Ruby's strip_heredoc.\n//\n// Spec: http://facebook.github.io/graphql/draft/#BlockStringValue()\n// Heavily borrows from: https://github.com/graphql/graphql-js/blob/8e0c599ceccfa8c40d6edf3b72ee2a71490b10e0/src/language/blockStringValue.js\nfunc blockStringValue(in string) string {\n\t// Expand a block string's raw value into independent lines.\n\tlines := splitLinesRegex.Split(in, -1)\n\n\t// Remove common indentation from all lines but first\n\tcommonIndent := -1\n\tfor i := 1; i < len(lines); i++ {\n\t\tline := lines[i]\n\t\tindent := leadingWhitespaceLen(line)\n\t\tif indent < len(line) && (commonIndent == -1 || indent < commonIndent) {\n\t\t\tcommonIndent = indent\n\t\t\tif commonIndent == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif commonIndent > 0 {\n\t\tfor i, line := range lines {\n\t\t\tif commonIndent > len(line) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlines[i] = line[commonIndent:]\n\t\t}\n\t}\n\n\t// Remove leading blank lines.\n\tfor len(lines) > 0 && lineIsBlank(lines[0]) {\n\t\tlines = lines[1:]\n\t}\n\n\t// Remove trailing blank lines.\n\tfor len(lines) > 0 && lineIsBlank(lines[len(lines)-1]) {\n\t\ti := len(lines) - 1\n\t\tlines = append(lines[:i], lines[i+1:]...)\n\t}\n\n\t// Return a string of the lines joined with U+000A.\n\treturn strings.Join(lines, \"\\n\")\n}\n\n// leadingWhitespaceLen returns count of whitespace characters on given line.\nfunc leadingWhitespaceLen(in string) (n int) {\n\tfor _, ch := range in {\n\t\tif ch == ' ' || ch == '\\t' {\n\t\t\tn++\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn\n}\n\n// lineIsBlank returns true when given line has no content.\nfunc lineIsBlank(in string) bool {\n\treturn leadingWhitespaceLen(in) == len(in)\n}\n\n// Converts four hexadecimal chars to the integer that the\n// string represents. For example, uniCharCode('0','0','0','f')\n// will return 15, and uniCharCode('0','0','f','f') returns 255.\n// Returns a negative number on error, if a char was invalid.\n// This is implemented by noting that char2hex() returns -1 on error,\n// which means the result of ORing the char2hex() will also be negative.\nfunc uniCharCode(a, b, c, d rune) rune {\n\treturn rune(char2hex(a)<<12 | char2hex(b)<<8 | char2hex(c)<<4 | char2hex(d))\n}\n\n// Converts a hex character to its integer value.\n// '0' becomes 0, '9' becomes 9\n// 'A' becomes 10, 'F' becomes 15\n// 'a' becomes 10, 'f' becomes 15\n// Returns -1 on error.\nfunc char2hex(a rune) int {\n\tif a >= 48 && a <= 57 { // 0-9\n\t\treturn int(a) - 48\n\t} else if a >= 65 && a <= 70 { // A-F\n\t\treturn int(a) - 55\n\t} else if a >= 97 && a <= 102 {\n\t\t// a-f\n\t\treturn int(a) - 87\n\t}\n\treturn -1\n}\n\nfunc makeToken(kind TokenKind, start int, end int, value string) Token {\n\treturn Token{Kind: kind, Start: start, End: end, Value: value}\n}\n\nfunc printCharCode(code rune) string {\n\t// NaN/undefined represents access beyond the end of the file.\n\tif code < 0 {\n\t\treturn \"<EOF>\"\n\t}\n\t// print as ASCII for printable range\n\tif code >= 0x0020 && code < 0x007F {\n\t\treturn fmt.Sprintf(`\"%c\"`, code)\n\t}\n\t// Otherwise print the escaped form. e.g. `\"\\\\u0007\"`\n\treturn fmt.Sprintf(`\"\\\\u%04X\"`, code)\n}\n\nfunc readToken(s *source.Source, fromPosition int) (Token, error) {\n\tbody := s.Body\n\tbodyLength := len(body)\n\tposition, runePosition := positionAfterWhitespace(body, fromPosition)\n\tif position >= bodyLength {\n\t\treturn makeToken(EOF, position, position, \"\"), nil\n\t}\n\tcode, codeLength := runeAt(body, position)\n\n\t// SourceCharacter\n\tif code < 0x0020 && code != 0x0009 && code != 0x000A && code != 0x000D {\n\t\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition, fmt.Sprintf(`Invalid character %v`, printCharCode(code)))\n\t}\n\n\tswitch code {\n\t// !\n\tcase '!':\n\t\treturn makeToken(BANG, position, position+1, \"\"), nil\n\t// $\n\tcase '$':\n\t\treturn makeToken(DOLLAR, position, position+1, \"\"), nil\n\t// &\n\tcase '&':\n\t\treturn makeToken(AMP, position, position+1, \"\"), nil\n\t// (\n\tcase '(':\n\t\treturn makeToken(PAREN_L, position, position+1, \"\"), nil\n\t// )\n\tcase ')':\n\t\treturn makeToken(PAREN_R, position, position+1, \"\"), nil\n\t// .\n\tcase '.':\n\t\tnext1, _ := runeAt(body, position+1)\n\t\tnext2, _ := runeAt(body, position+2)\n\t\tif next1 == '.' && next2 == '.' {\n\t\t\treturn makeToken(SPREAD, position, position+3, \"\"), nil\n\t\t}\n\t\tbreak\n\t// :\n\tcase ':':\n\t\treturn makeToken(COLON, position, position+1, \"\"), nil\n\t// =\n\tcase '=':\n\t\treturn makeToken(EQUALS, position, position+1, \"\"), nil\n\t// @\n\tcase '@':\n\t\treturn makeToken(AT, position, position+1, \"\"), nil\n\t// [\n\tcase '[':\n\t\treturn makeToken(BRACKET_L, position, position+1, \"\"), nil\n\t// ]\n\tcase ']':\n\t\treturn makeToken(BRACKET_R, position, position+1, \"\"), nil\n\t// {\n\tcase '{':\n\t\treturn makeToken(BRACE_L, position, position+1, \"\"), nil\n\t// |\n\tcase '|':\n\t\treturn makeToken(PIPE, position, position+1, \"\"), nil\n\t// }\n\tcase '}':\n\t\treturn makeToken(BRACE_R, position, position+1, \"\"), nil\n\t// A-Z\n\tcase 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',\n\t\t'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':\n\t\treturn readName(s, position, runePosition), nil\n\t// _\n\t// a-z\n\tcase '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',\n\t\t'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z':\n\t\treturn readName(s, position, runePosition), nil\n\t// -\n\t// 0-9\n\tcase '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\ttoken, err := readNumber(s, position, code, codeLength)\n\t\tif err != nil {\n\t\t\treturn token, err\n\t\t}\n\t\treturn token, nil\n\t// \"\n\tcase '\"':\n\t\tvar token Token\n\t\tvar err error\n\t\tx, _ := runeAt(body, position+1)\n\t\ty, _ := runeAt(body, position+2)\n\t\tif x == '\"' && y == '\"' {\n\t\t\ttoken, err = readBlockString(s, position)\n\t\t} else {\n\t\t\ttoken, err = readString(s, position)\n\t\t}\n\t\treturn token, err\n\t}\n\tdescription := fmt.Sprintf(\"Unexpected character %v.\", printCharCode(code))\n\treturn Token{}, gqlerrors.NewSyntaxError(s, runePosition, description)\n}\n\n// Gets the rune from the byte array at given byte position and it's width in bytes\nfunc runeAt(body []byte, position int) (code rune, charWidth int) {\n\tif len(body) <= position {\n\t\t// <EOF>\n\t\treturn -1, utf8.RuneError\n\t}\n\n\tc := body[position]\n\tif c < utf8.RuneSelf {\n\t\treturn rune(c), 1\n\t}\n\n\tr, n := utf8.DecodeRune(body[position:])\n\treturn r, n\n}\n\n// Reads from body starting at startPosition until it finds a non-whitespace\n// or commented character, then returns the position of that character for lexing.\n// lexing.\n// Returns both byte positions and rune position\nfunc positionAfterWhitespace(body []byte, startPosition int) (position int, runePosition int) {\n\tbodyLength := len(body)\n\tposition = startPosition\n\trunePosition = startPosition\n\tfor {\n\t\tif position < bodyLength {\n\t\t\tcode, n := runeAt(body, position)\n\n\t\t\t// Skip Ignored\n\t\t\tif code == 0xFEFF || // BOM\n\t\t\t\t// White Space\n\t\t\t\tcode == 0x0009 || // tab\n\t\t\t\tcode == 0x0020 || // space\n\t\t\t\t// Line Terminator\n\t\t\t\tcode == 0x000A || // new line\n\t\t\t\tcode == 0x000D || // carriage return\n\t\t\t\t// Comma\n\t\t\t\tcode == 0x002C {\n\t\t\t\tposition += n\n\t\t\t\trunePosition++\n\t\t\t} else if code == 35 { // #\n\t\t\t\tposition += n\n\t\t\t\trunePosition++\n\t\t\t\tfor {\n\t\t\t\t\tcode, n := runeAt(body, position)\n\t\t\t\t\tif position < bodyLength &&\n\t\t\t\t\t\tcode != 0 &&\n\t\t\t\t\t\t// SourceCharacter but not LineTerminator\n\t\t\t\t\t\t(code > 0x001F || code == 0x0009) && code != 0x000A && code != 0x000D {\n\t\t\t\t\t\tposition += n\n\t\t\t\t\t\trunePosition++\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcontinue\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn position, runePosition\n}\n\nfunc GetTokenDesc(token Token) string {\n\tif token.Value == \"\" {\n\t\treturn token.Kind.String()\n\t}\n\treturn fmt.Sprintf(\"%s \\\"%s\\\"\", token.Kind.String(), token.Value)\n}\n"
  },
  {
    "path": "language/lexer/lexer_test.go",
    "content": "package lexer\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\ntype Test struct {\n\tBody     string\n\tExpected interface{}\n}\n\nfunc createSource(body string) *source.Source {\n\treturn source.NewSource(&source.Source{Body: []byte(body)})\n}\n\nfunc TestLexer_GetTokenDesc(t *testing.T) {\n\texpected := `Name \"foo\"`\n\ttokenDescription := GetTokenDesc(Token{\n\t\tKind:  NAME,\n\t\tStart: 2,\n\t\tEnd:   5,\n\t\tValue: \"foo\",\n\t})\n\tif expected != tokenDescription {\n\t\tt.Errorf(\"Expected %v, got %v\", expected, tokenDescription)\n\t}\n\n\texpected = `Name`\n\ttokenDescription = GetTokenDesc(Token{\n\t\tKind:  NAME,\n\t\tStart: 0,\n\t\tEnd:   0,\n\t\tValue: \"\",\n\t})\n\tif expected != tokenDescription {\n\t\tt.Errorf(\"Expected %v, got %v\", expected, tokenDescription)\n\t}\n\n\texpected = `String \"foo\"`\n\ttokenDescription = GetTokenDesc(Token{\n\t\tKind:  STRING,\n\t\tStart: 2,\n\t\tEnd:   5,\n\t\tValue: \"foo\",\n\t})\n\tif expected != tokenDescription {\n\t\tt.Errorf(\"Expected %v, got %v\", expected, tokenDescription)\n\t}\n\n\texpected = `String`\n\ttokenDescription = GetTokenDesc(Token{\n\t\tKind:  STRING,\n\t\tStart: 0,\n\t\tEnd:   0,\n\t\tValue: \"\",\n\t})\n\tif expected != tokenDescription {\n\t\tt.Errorf(\"Expected %v, got %v\", expected, tokenDescription)\n\t}\n\n}\n\nfunc TestLexer_DisallowsUncommonControlCharacters(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"\\u0007\",\n\t\t\tExpected: `Syntax Error GraphQL (1:1) Invalid character \"\\\\u0007\"\n\n1: \\u0007\n   ^\n`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\t_, err := Lex(createSource(test.Body))(0)\n\t\tif err == nil {\n\t\t\tt.Errorf(\"unexpected nil error\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err)\n\t\t}\n\t\tif err.Error() != test.Expected {\n\t\t\tt.Errorf(\"unexpected error.\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err.Error())\n\t\t}\n\t}\n}\n\nfunc TestLexer_AcceptsBOMHeader(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"\\uFEFF foo\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  NAME,\n\t\t\t\tStart: 2,\n\t\t\t\tEnd:   5,\n\t\t\t\tValue: \"foo\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\ttoken, err := Lex(&source.Source{Body: []byte(test.Body)})(0)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif !reflect.DeepEqual(token, test.Expected) {\n\t\t\tt.Errorf(\"unexpected token, expected: %v, got: %v\", test.Expected, token)\n\t\t}\n\t}\n}\n\nfunc TestLexer_SkipsWhiteSpace(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: `\n\n    foo\n\n`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  NAME,\n\t\t\t\tStart: 6,\n\t\t\t\tEnd:   9,\n\t\t\t\tValue: \"foo\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: `\n    #comment\n    foo#comment\n`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  NAME,\n\t\t\t\tStart: 18,\n\t\t\t\tEnd:   21,\n\t\t\t\tValue: \"foo\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: `,,,foo,,,`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  NAME,\n\t\t\t\tStart: 3,\n\t\t\t\tEnd:   6,\n\t\t\t\tValue: \"foo\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: ``,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  EOF,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   0,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\ttoken, err := Lex(&source.Source{Body: []byte(test.Body)})(0)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif !reflect.DeepEqual(token, test.Expected) {\n\t\t\tt.Errorf(\"unexpected token, expected: %v, got: %v, body: %s\", test.Expected, token, test.Body)\n\t\t}\n\t}\n}\n\nfunc TestLexer_ErrorsRespectWhitespace(t *testing.T) {\n\tbody := `\n\n    ?\n\n`\n\t_, err := Lex(createSource(body))(0)\n\texpected := \"Syntax Error GraphQL (3:5) Unexpected character \\\"?\\\".\\n\\n2: \\n3:     ?\\n       ^\\n4: \\n\"\n\tif err == nil {\n\t\tt.Fatalf(\"unexpected nil error\\nexpected:\\n%v\\n\\ngot:\\n%v\", expected, err)\n\t}\n\tif err.Error() != expected {\n\t\tt.Fatalf(\"unexpected error.\\nexpected:\\n%v\\n\\ngot:\\n%v\", expected, err.Error())\n\t}\n}\n\nfunc TestLexer_LexesNames(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"simple\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  NAME,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   6,\n\t\t\t\tValue: \"simple\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"Capital\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  NAME,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   7,\n\t\t\t\tValue: \"Capital\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\ttoken, err := Lex(&source.Source{Body: []byte(test.Body)})(0)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif !reflect.DeepEqual(token, test.Expected) {\n\t\t\tt.Errorf(\"unexpected token, expected: %v, got: %v\", test.Expected, token)\n\t\t}\n\t}\n}\n\nfunc TestLexer_LexesStrings(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"\\\"simple\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   8,\n\t\t\t\tValue: \"simple\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\" white space \\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   15,\n\t\t\t\tValue: \" white space \",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"quote \\\\\\\"\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   10,\n\t\t\t\tValue: `quote \"`,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"escaped \\\\n\\\\r\\\\b\\\\t\\\\f\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   20,\n\t\t\t\tValue: \"escaped \\n\\r\\b\\t\\f\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"slashes \\\\\\\\ \\\\/\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   15,\n\t\t\t\tValue: \"slashes \\\\ /\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"unicode \\\\u1234\\\\u5678\\\\u90AB\\\\uCDEF\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   34,\n\t\t\t\tValue: \"unicode \\u1234\\u5678\\u90AB\\uCDEF\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"unicode фы世界\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   20,\n\t\t\t\tValue: \"unicode фы世界\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"фы世界\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   12,\n\t\t\t\tValue: \"фы世界\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"Has a фы世界 multi-byte character.\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   40,\n\t\t\t\tValue: \"Has a фы世界 multi-byte character.\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\ttoken, err := Lex(&source.Source{Body: []byte(test.Body)})(0)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif !reflect.DeepEqual(token, test.Expected) {\n\t\t\tt.Errorf(\"unexpected token, expected: %v, got: %v\", test.Expected, token)\n\t\t}\n\t}\n}\n\nfunc TestLexer_ReportsUsefulStringErrors(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:2) Unterminated string.\n\n1: \"\n    ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"no end quote\",\n\t\t\tExpected: `Syntax Error GraphQL (1:14) Unterminated string.\n\n1: \"no end quote\n                ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"contains unescaped \\u0007 control char\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:21) Invalid character within String: \"\\\\u0007\".\n\n1: \"contains unescaped \\u0007 control char\"\n                       ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"null-byte is not \\u0000 end of file\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:19) Invalid character within String: \"\\\\u0000\".\n\n1: \"null-byte is not \\u0000 end of file\"\n                     ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"multi\\nline\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Unterminated string.\n\n1: \"multi\n         ^\n2: line\"\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"multi\\rline\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Unterminated string.\n\n1: \"multi\n         ^\n2: line\"\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"bad \\\\z esc\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Invalid character escape sequence: \\\\z.\n\n1: \"bad \\z esc\"\n         ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"bad \\\\x esc\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Invalid character escape sequence: \\\\x.\n\n1: \"bad \\x esc\"\n         ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"bad \\\\u1 esc\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u1 es\n\n1: \"bad \\u1 esc\"\n         ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"bad \\\\u0XX1 esc\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u0XX1\n\n1: \"bad \\u0XX1 esc\"\n         ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"bad \\\\uXXXX esc\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uXXXX\n\n1: \"bad \\uXXXX esc\"\n         ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"bad \\\\uFXXX esc\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uFXXX\n\n1: \"bad \\uFXXX esc\"\n         ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"bad \\\\uXXXF esc\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Invalid character escape sequence: \\uXXXF\n\n1: \"bad \\uXXXF esc\"\n         ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"bad \\\\u123\",\n\t\t\tExpected: `Syntax Error GraphQL (1:7) Invalid character escape sequence: \\u123\n\n1: \"bad \\u123\n         ^\n`,\n\t\t},\n\t\t{\n\t\t\t// some unicode chars take more than one column of text\n\t\t\t// current implementation does not handle this\n\t\t\tBody: \"\\\"bфы世ыы𠱸d \\\\uXXXF esc\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:12) Invalid character escape sequence: \\uXXXF\n\n1: \"bфы世ыы𠱸d \\uXXXF esc\"\n              ^\n`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\t_, err := Lex(createSource(test.Body))(0)\n\t\tif err == nil {\n\t\t\tt.Errorf(\"unexpected nil error\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err)\n\t\t}\n\n\t\tif err.Error() != test.Expected {\n\t\t\tt.Errorf(\"unexpected error.\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err.Error())\n\t\t}\n\t}\n}\n\nfunc TestLexer_LexesBlockStrings(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: `\"\"\"\"\"\"`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   6,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: `\"\"\"simple\"\"\"`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   12,\n\t\t\t\tValue: \"simple\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: `\"\"\" white space \"\"\"`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   19,\n\t\t\t\tValue: \" white space \",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: `\n\t\t\t\t\"\"\"  white space \"\"\"\n\t\t\t\t\"\"\"  white space  \"\"\"\n\t\t\t\t\"\"\"  white space \"\"\"\n\t\t\t`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 5,\n\t\t\t\tEnd:   25,\n\t\t\t\tValue: \"  white space \",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: `\n\t\t\t\t\"\"\"\n\t\t\t\t\t\tmy great description\n\t\t\t\t\t\tspans multiple lines\n\n\t\t\t\t\t\twith breaks\n\t\t\t\t\"\"\"\n\t\t\t`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 5,\n\t\t\t\tEnd:   89,\n\t\t\t\tValue: \"my great description\\nspans multiple lines\\n\\nwith breaks\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: `\"\"\"contains \" quote\"\"\"`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   22,\n\t\t\t\tValue: `contains \" quote`,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: `\"\"\"contains \\\"\"\" triplequote\"\"\"`,\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   31,\n\t\t\t\tValue: `contains \"\"\" triplequote`,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"\\\"\\\"multi\\nline\\\"\\\"\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   16,\n\t\t\t\tValue: \"multi\\nline\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"\\\"\\\"multi\\rline\\r\\nnormalized\\\"\\\"\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   28,\n\t\t\t\tValue: \"multi\\nline\\nnormalized\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"\\\"\\\"unescaped \\\\n\\\\r\\\\b\\\\t\\\\f\\\\u1234\\\"\\\"\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   32,\n\t\t\t\tValue: \"unescaped \\\\n\\\\r\\\\b\\\\t\\\\f\\\\u1234\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"\\\"\\\"slashes \\\\\\\\ \\\\/\\\"\\\"\\\"\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BLOCK_STRING,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   19,\n\t\t\t\tValue: \"slashes \\\\\\\\ \\\\/\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\ttoken, err := Lex(&source.Source{Body: []byte(test.Body)})(0)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif !reflect.DeepEqual(token, test.Expected) {\n\t\t\tt.Errorf(\"unexpected token, expected: %v, got: %v\", test.Expected, token)\n\t\t}\n\t}\n}\n\nfunc TestLexer_ReportsUsefulBlockStringErrors(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: `\"\"\"`,\n\t\t\tExpected: `Syntax Error GraphQL (1:4) Unterminated string.\n\n1: \"\"\"\n      ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: `\"\"\"no end quote`,\n\t\t\tExpected: `Syntax Error GraphQL (1:16) Unterminated string.\n\n1: \"\"\"no end quote\n                  ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"\\\"\\\"contains unescaped \\u0007 control char\\\"\\\"\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:23) Invalid character within String: \"\\\\u0007\".\n\n1: \"\"\"contains unescaped \\u0007 control char\"\"\"\n                         ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\\"\\\"\\\"null-byte is not \\u0000 end of file\\\"\\\"\\\"\",\n\t\t\tExpected: `Syntax Error GraphQL (1:21) Invalid character within String: \"\\\\u0000\".\n\n1: \"\"\"null-byte is not \\u0000 end of file\"\"\"\n                       ^\n`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\t_, err := Lex(createSource(test.Body))(0)\n\t\tif err == nil {\n\t\t\tt.Errorf(\"unexpected nil error\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err)\n\t\t}\n\n\t\tif err.Error() != test.Expected {\n\t\t\tt.Errorf(\"unexpected error.\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err.Error())\n\t\t}\n\t}\n}\n\nfunc TestLexer_LexesNumbers(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  INT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"4.123\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   5,\n\t\t\t\tValue: \"4.123\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"-4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  INT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   2,\n\t\t\t\tValue: \"-4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"9\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  INT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"9\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"0\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  INT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"0\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"-4.123\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   6,\n\t\t\t\tValue: \"-4.123\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"0.123\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   5,\n\t\t\t\tValue: \"0.123\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"123e4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   5,\n\t\t\t\tValue: \"123e4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"123E4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   5,\n\t\t\t\tValue: \"123E4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"123e-4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   6,\n\t\t\t\tValue: \"123e-4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"123e+4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   6,\n\t\t\t\tValue: \"123e+4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"-1.123e4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   8,\n\t\t\t\tValue: \"-1.123e4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"-1.123E4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   8,\n\t\t\t\tValue: \"-1.123E4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"-1.123e-4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   9,\n\t\t\t\tValue: \"-1.123e-4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"-1.123e+4\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   9,\n\t\t\t\tValue: \"-1.123e+4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"-1.123e4567\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  FLOAT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   11,\n\t\t\t\tValue: \"-1.123e4567\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\ttoken, err := Lex(createSource(test.Body))(0)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v, test: %s\", err, test)\n\t\t}\n\t\tif !reflect.DeepEqual(token, test.Expected) {\n\t\t\tt.Errorf(\"unexpected token, expected: %v, got: %v, test: %v\", test.Expected, token, test)\n\t\t}\n\t}\n}\n\nfunc TestLexer_ReportsUsefulNumberErrors(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"00\",\n\t\t\tExpected: `Syntax Error GraphQL (1:2) Invalid number, unexpected digit after 0: \"0\".\n\n1: 00\n    ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"+1\",\n\t\t\tExpected: `Syntax Error GraphQL (1:1) Unexpected character \"+\".\n\n1: +1\n   ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"1.\",\n\t\t\tExpected: `Syntax Error GraphQL (1:3) Invalid number, expected digit but got: <EOF>.\n\n1: 1.\n     ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \".123\",\n\t\t\tExpected: `Syntax Error GraphQL (1:1) Unexpected character \".\".\n\n1: .123\n   ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"1.A\",\n\t\t\tExpected: `Syntax Error GraphQL (1:3) Invalid number, expected digit but got: \"A\".\n\n1: 1.A\n     ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"-A\",\n\t\t\tExpected: `Syntax Error GraphQL (1:2) Invalid number, expected digit but got: \"A\".\n\n1: -A\n    ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"1.0e\",\n\n\t\t\tExpected: `Syntax Error GraphQL (1:5) Invalid number, expected digit but got: <EOF>.\n\n1: 1.0e\n       ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"1.0eA\",\n\t\t\tExpected: `Syntax Error GraphQL (1:5) Invalid number, expected digit but got: \"A\".\n\n1: 1.0eA\n       ^\n`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\t_, err := Lex(createSource(test.Body))(0)\n\t\tif err == nil {\n\t\t\tt.Errorf(\"unexpected nil error\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err)\n\t\t}\n\t\tif err.Error() != test.Expected {\n\t\t\tt.Errorf(\"unexpected error.\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err.Error())\n\t\t}\n\t}\n}\n\nfunc TestLexer_LexesPunctuation(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"!\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BANG,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"$\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  DOLLAR,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"(\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  PAREN_L,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \")\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  PAREN_R,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"...\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  SPREAD,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   3,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \":\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  COLON,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"=\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  EQUALS,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"@\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  AT,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"[\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BRACKET_L,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"]\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BRACKET_R,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"{\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BRACE_L,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"|\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  PIPE,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tBody: \"}\",\n\t\t\tExpected: Token{\n\t\t\t\tKind:  BRACE_R,\n\t\t\t\tStart: 0,\n\t\t\t\tEnd:   1,\n\t\t\t\tValue: \"\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\ttoken, err := Lex(createSource(test.Body))(0)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error :%v, test: %v\", err, test)\n\t\t}\n\t\tif !reflect.DeepEqual(token, test.Expected) {\n\t\t\tt.Errorf(\"unexpected token, expected: %v, got: %v, test: %v\", test.Expected, token, test)\n\t\t}\n\t}\n}\n\nfunc TestLexer_ReportsUsefulUnknownCharacterError(t *testing.T) {\n\ttests := []Test{\n\t\t{\n\t\t\tBody: \"..\",\n\t\t\tExpected: `Syntax Error GraphQL (1:1) Unexpected character \".\".\n\n1: ..\n   ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"?\",\n\t\t\tExpected: `Syntax Error GraphQL (1:1) Unexpected character \"?\".\n\n1: ?\n   ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\u203B\",\n\t\t\tExpected: `Syntax Error GraphQL (1:1) Unexpected character \"\\\\u203B\".\n\n1: ※\n   ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"\\u203b\",\n\t\t\tExpected: `Syntax Error GraphQL (1:1) Unexpected character \"\\\\u203B\".\n\n1: ※\n   ^\n`,\n\t\t},\n\t\t{\n\t\t\tBody: \"ф\",\n\t\t\tExpected: `Syntax Error GraphQL (1:1) Unexpected character \"\\\\u0444\".\n\n1: ф\n   ^\n`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\t_, err := Lex(createSource(test.Body))(0)\n\t\tif err == nil {\n\t\t\tt.Errorf(\"unexpected nil error\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err)\n\t\t}\n\t\tif err.Error() != test.Expected {\n\t\t\tt.Errorf(\"unexpected error.\\nexpected:\\n%v\\n\\ngot:\\n%v\", test.Expected, err.Error())\n\t\t}\n\t}\n}\n\nfunc TestLexer_ReportsUsefulInformationForDashesInNames(t *testing.T) {\n\tq := \"a-b\"\n\tlexer := Lex(createSource(q))\n\tfirstToken, err := lexer(0)\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\tfirstTokenExpected := Token{\n\t\tKind:  NAME,\n\t\tStart: 0,\n\t\tEnd:   1,\n\t\tValue: \"a\",\n\t}\n\tif !reflect.DeepEqual(firstToken, firstTokenExpected) {\n\t\tt.Fatalf(\"unexpected token, expected: %v, got: %v\", firstTokenExpected, firstToken)\n\t}\n\terrExpected := `Syntax Error GraphQL (1:3) Invalid number, expected digit but got: \"b\".\n\n1: a-b\n     ^\n`\n\ttoken, err := lexer(0)\n\tif err == nil {\n\t\tt.Fatalf(\"unexpected nil error: %v\", err)\n\t}\n\tif err.Error() != errExpected {\n\t\tt.Fatalf(\"unexpected error, token:%v\\nexpected:\\n%v\\n\\ngot:\\n%v\", token, errExpected, err.Error())\n\t}\n}\n"
  },
  {
    "path": "language/location/location.go",
    "content": "package location\n\nimport (\n\t\"regexp\"\n\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\ntype SourceLocation struct {\n\tLine   int `json:\"line\"`\n\tColumn int `json:\"column\"`\n}\n\nfunc GetLocation(s *source.Source, position int) SourceLocation {\n\tbody := []byte{}\n\tif s != nil {\n\t\tbody = s.Body\n\t}\n\tline := 1\n\tcolumn := position + 1\n\tlineRegexp := regexp.MustCompile(\"\\r\\n|[\\n\\r]\")\n\tmatches := lineRegexp.FindAllIndex(body, -1)\n\tfor _, match := range matches {\n\t\tmatchIndex := match[0]\n\t\tif matchIndex < position {\n\t\t\tline++\n\t\t\tl := len(s.Body[match[0]:match[1]])\n\t\t\tcolumn = position + 1 - (matchIndex + l)\n\t\t\tcontinue\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn SourceLocation{Line: line, Column: column}\n}\n"
  },
  {
    "path": "language/parser/parser.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/lexer\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\ntype parseFn func(parser *Parser) (interface{}, error)\n\n// parse operation, fragment, typeSystem{schema, type..., extension, directives} definition\ntype parseDefinitionFn func(parser *Parser) (ast.Node, error)\n\nvar tokenDefinitionFn map[string]parseDefinitionFn\n\nfunc init() {\n\ttokenDefinitionFn = make(map[string]parseDefinitionFn)\n\t{\n\t\ttokenDefinitionFn[lexer.FRAGMENT] = parseFragmentDefinition\n\t\ttokenDefinitionFn[lexer.QUERY] = parseOperationDefinition\n\t\ttokenDefinitionFn[lexer.MUTATION] = parseOperationDefinition\n\t\ttokenDefinitionFn[lexer.SUBSCRIPTION] = parseOperationDefinition\n\t\ttokenDefinitionFn[lexer.SCHEMA] = parseSchemaDefinition\n\t\ttokenDefinitionFn[lexer.SCALAR] = parseScalarTypeDefinition\n\t\ttokenDefinitionFn[lexer.TYPE] = parseObjectTypeDefinition\n\t\ttokenDefinitionFn[lexer.INTERFACE] = parseInterfaceTypeDefinition\n\t\ttokenDefinitionFn[lexer.UNION] = parseUnionTypeDefinition\n\t\ttokenDefinitionFn[lexer.ENUM] = parseEnumTypeDefinition\n\t\ttokenDefinitionFn[lexer.INPUT] = parseInputObjectTypeDefinition\n\t\ttokenDefinitionFn[lexer.EXTEND] = parseTypeExtensionDefinition\n\t\ttokenDefinitionFn[lexer.DIRECTIVE] = parseDirectiveDefinition\n\t}\n}\n\ntype ParseOptions struct {\n\tNoLocation bool\n\tNoSource   bool\n}\n\ntype ParseParams struct {\n\tSource  interface{}\n\tOptions ParseOptions\n}\n\ntype Parser struct {\n\tLexToken lexer.Lexer\n\tSource   *source.Source\n\tOptions  ParseOptions\n\tPrevEnd  int\n\tToken    lexer.Token\n}\n\nfunc Parse(p ParseParams) (*ast.Document, error) {\n\tvar sourceObj *source.Source\n\tswitch src := p.Source.(type) {\n\tcase *source.Source:\n\t\tsourceObj = src\n\tdefault:\n\t\tbody, _ := p.Source.(string)\n\t\tsourceObj = source.NewSource(&source.Source{Body: []byte(body)})\n\t}\n\tparser, err := makeParser(sourceObj, p.Options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdoc, err := parseDocument(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn doc, nil\n}\n\n// ParseValue parses params and returns ast value\nfunc ParseValue(p ParseParams) (ast.Value, error) {\n\tvar value ast.Value\n\tvar sourceObj *source.Source\n\tswitch src := p.Source.(type) {\n\tcase *source.Source:\n\t\tsourceObj = src\n\tdefault:\n\t\tbody, _ := p.Source.(string)\n\t\tsourceObj = source.NewSource(&source.Source{Body: []byte(body)})\n\t}\n\tparser, err := makeParser(sourceObj, p.Options)\n\tif err != nil {\n\t\treturn value, err\n\t}\n\tvalue, err = parseValueLiteral(parser, false)\n\tif err != nil {\n\t\treturn value, err\n\t}\n\treturn value, nil\n}\n\n// Converts a name lex token into a name parse node.\nfunc parseName(parser *Parser) (*ast.Name, error) {\n\ttoken, err := expect(parser, lexer.NAME)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewName(&ast.Name{\n\t\tValue: token.Value,\n\t\tLoc:   loc(parser, token.Start),\n\t}), nil\n}\n\nfunc makeParser(s *source.Source, opts ParseOptions) (*Parser, error) {\n\tlexToken := lexer.Lex(s)\n\ttoken, err := lexToken(0)\n\tif err != nil {\n\t\treturn &Parser{}, err\n\t}\n\treturn &Parser{\n\t\tLexToken: lexToken,\n\t\tSource:   s,\n\t\tOptions:  opts,\n\t\tPrevEnd:  0,\n\t\tToken:    token,\n\t}, nil\n}\n\n/* Implements the parsing rules in the Document section. */\n\nfunc parseDocument(parser *Parser) (*ast.Document, error) {\n\tvar (\n\t\tnodes []ast.Node\n\t\tnode  ast.Node\n\t\titem  parseDefinitionFn\n\t\terr   error\n\t)\n\tstart := parser.Token.Start\n\tfor {\n\t\tif skp, err := skip(parser, lexer.EOF); err != nil {\n\t\t\treturn nil, err\n\t\t} else if skp {\n\t\t\tbreak\n\t\t}\n\t\tswitch kind := parser.Token.Kind; kind {\n\t\tcase lexer.BRACE_L:\n\t\t\titem = parseOperationDefinition\n\t\tcase lexer.NAME, lexer.STRING, lexer.BLOCK_STRING:\n\t\t\titem = parseTypeSystemDefinition\n\t\tdefault:\n\t\t\treturn nil, unexpected(parser, lexer.Token{})\n\t\t}\n\t\tif node, err = item(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnodes = append(nodes, node)\n\t}\n\treturn ast.NewDocument(&ast.Document{\n\t\tLoc:         loc(parser, start),\n\t\tDefinitions: nodes,\n\t}), nil\n}\n\n/* Implements the parsing rules in the Operations section. */\n\n/**\n * OperationDefinition :\n *  - SelectionSet\n *  - OperationType Name? VariableDefinitions? Directives? SelectionSet\n */\nfunc parseOperationDefinition(parser *Parser) (ast.Node, error) {\n\tvar (\n\t\toperation           string\n\t\tvariableDefinitions []*ast.VariableDefinition\n\t\tname                *ast.Name\n\t\tdirectives          []*ast.Directive\n\t\tselectionSet        *ast.SelectionSet\n\t\terr                 error\n\t)\n\tstart := parser.Token.Start\n\tif peek(parser, lexer.BRACE_L) {\n\t\tselectionSet, err := parseSelectionSet(parser)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn ast.NewOperationDefinition(&ast.OperationDefinition{\n\t\t\tOperation:    ast.OperationTypeQuery,\n\t\t\tDirectives:   []*ast.Directive{},\n\t\t\tSelectionSet: selectionSet,\n\t\t\tLoc:          loc(parser, start),\n\t\t}), nil\n\t}\n\tif operation, err = parseOperationType(parser); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif peek(parser, lexer.NAME) {\n\t\tif name, err = parseName(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif variableDefinitions, err = parseVariableDefinitions(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif directives, err = parseDirectives(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif selectionSet, err = parseSelectionSet(parser); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewOperationDefinition(&ast.OperationDefinition{\n\t\tOperation:           operation,\n\t\tName:                name,\n\t\tVariableDefinitions: variableDefinitions,\n\t\tDirectives:          directives,\n\t\tSelectionSet:        selectionSet,\n\t\tLoc:                 loc(parser, start),\n\t}), nil\n}\n\n/**\n * OperationType : one of query mutation subscription\n */\nfunc parseOperationType(parser *Parser) (string, error) {\n\toperationToken, err := expect(parser, lexer.NAME)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tswitch operationToken.Value {\n\tcase ast.OperationTypeQuery:\n\t\treturn operationToken.Value, nil\n\tcase ast.OperationTypeMutation:\n\t\treturn operationToken.Value, nil\n\tcase ast.OperationTypeSubscription:\n\t\treturn operationToken.Value, nil\n\tdefault:\n\t\treturn \"\", unexpected(parser, operationToken)\n\t}\n}\n\n/**\n * VariableDefinitions : ( VariableDefinition+ )\n */\nfunc parseVariableDefinitions(parser *Parser) ([]*ast.VariableDefinition, error) {\n\tvariableDefinitions := []*ast.VariableDefinition{}\n\tif !peek(parser, lexer.PAREN_L) {\n\t\treturn variableDefinitions, nil\n\t}\n\tif vdefs, err := reverse(parser,\n\t\tlexer.PAREN_L, parseVariableDefinition, lexer.PAREN_R,\n\t\ttrue,\n\t); err != nil {\n\t\treturn variableDefinitions, err\n\t} else {\n\t\tfor _, vdef := range vdefs {\n\t\t\tvariableDefinitions = append(variableDefinitions, vdef.(*ast.VariableDefinition))\n\t\t}\n\t}\n\treturn variableDefinitions, nil\n}\n\n/**\n * VariableDefinition : Variable : Type DefaultValue?\n */\nfunc parseVariableDefinition(parser *Parser) (interface{}, error) {\n\tvar (\n\t\tvariable *ast.Variable\n\t\tttype    ast.Type\n\t\terr      error\n\t)\n\tstart := parser.Token.Start\n\tif variable, err = parseVariable(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err = expect(parser, lexer.COLON); err != nil {\n\t\treturn nil, err\n\t}\n\tif ttype, err = parseType(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tvar defaultValue ast.Value\n\tif skp, err := skip(parser, lexer.EQUALS); err != nil {\n\t\treturn nil, err\n\t} else if skp {\n\t\tif defaultValue, err = parseValueLiteral(parser, true); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn ast.NewVariableDefinition(&ast.VariableDefinition{\n\t\tVariable:     variable,\n\t\tType:         ttype,\n\t\tDefaultValue: defaultValue,\n\t\tLoc:          loc(parser, start),\n\t}), nil\n}\n\n/**\n * Variable : $ Name\n */\nfunc parseVariable(parser *Parser) (*ast.Variable, error) {\n\tvar (\n\t\terr  error\n\t\tname *ast.Name\n\t)\n\tstart := parser.Token.Start\n\tif _, err = expect(parser, lexer.DOLLAR); err != nil {\n\t\treturn nil, err\n\t}\n\tif name, err = parseName(parser); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewVariable(&ast.Variable{\n\t\tName: name,\n\t\tLoc:  loc(parser, start),\n\t}), nil\n}\n\n/**\n * SelectionSet : { Selection+ }\n */\nfunc parseSelectionSet(parser *Parser) (*ast.SelectionSet, error) {\n\tstart := parser.Token.Start\n\tselections := []ast.Selection{}\n\tif iSelections, err := reverse(parser,\n\t\tlexer.BRACE_L, parseSelection, lexer.BRACE_R,\n\t\ttrue,\n\t); err != nil {\n\t\treturn nil, err\n\t} else {\n\t\tfor _, iSelection := range iSelections {\n\t\t\tselections = append(selections, iSelection.(ast.Selection))\n\t\t}\n\t}\n\n\treturn ast.NewSelectionSet(&ast.SelectionSet{\n\t\tSelections: selections,\n\t\tLoc:        loc(parser, start),\n\t}), nil\n}\n\n/**\n * Selection :\n *   - Field\n *   - FragmentSpread\n *   - InlineFragment\n */\nfunc parseSelection(parser *Parser) (interface{}, error) {\n\tif peek(parser, lexer.SPREAD) {\n\t\treturn parseFragment(parser)\n\t}\n\treturn parseField(parser)\n}\n\n/**\n * Field : Alias? Name Arguments? Directives? SelectionSet?\n *\n * Alias : Name :\n */\nfunc parseField(parser *Parser) (*ast.Field, error) {\n\tvar (\n\t\tname       *ast.Name\n\t\talias      *ast.Name\n\t\targuments  []*ast.Argument\n\t\tdirectives []*ast.Directive\n\t\terr        error\n\t)\n\tstart := parser.Token.Start\n\tif name, err = parseName(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif skp, err := skip(parser, lexer.COLON); err != nil {\n\t\treturn nil, err\n\t} else if skp {\n\t\talias = name\n\t\tif name, err = parseName(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif arguments, err = parseArguments(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif directives, err = parseDirectives(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tvar selectionSet *ast.SelectionSet\n\tif peek(parser, lexer.BRACE_L) {\n\t\tif selectionSet, err = parseSelectionSet(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn ast.NewField(&ast.Field{\n\t\tAlias:        alias,\n\t\tName:         name,\n\t\tArguments:    arguments,\n\t\tDirectives:   directives,\n\t\tSelectionSet: selectionSet,\n\t\tLoc:          loc(parser, start),\n\t}), nil\n}\n\n/**\n * Arguments : ( Argument+ )\n */\nfunc parseArguments(parser *Parser) ([]*ast.Argument, error) {\n\targuments := []*ast.Argument{}\n\tif peek(parser, lexer.PAREN_L) {\n\t\tif iArguments, err := reverse(parser,\n\t\t\tlexer.PAREN_L, parseArgument, lexer.PAREN_R,\n\t\t\ttrue,\n\t\t); err != nil {\n\t\t\treturn arguments, err\n\t\t} else {\n\t\t\tfor _, iArgument := range iArguments {\n\t\t\t\targuments = append(arguments, iArgument.(*ast.Argument))\n\t\t\t}\n\t\t}\n\t}\n\treturn arguments, nil\n}\n\n/**\n * Argument : Name : Value\n */\nfunc parseArgument(parser *Parser) (interface{}, error) {\n\tvar (\n\t\terr   error\n\t\tname  *ast.Name\n\t\tvalue ast.Value\n\t)\n\tstart := parser.Token.Start\n\tif name, err = parseName(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err = expect(parser, lexer.COLON); err != nil {\n\t\treturn nil, err\n\t}\n\tif value, err = parseValueLiteral(parser, false); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewArgument(&ast.Argument{\n\t\tName:  name,\n\t\tValue: value,\n\t\tLoc:   loc(parser, start),\n\t}), nil\n}\n\n/* Implements the parsing rules in the Fragments section. */\n\n/**\n * Corresponds to both FragmentSpread and InlineFragment in the spec.\n *\n * FragmentSpread : ... FragmentName Directives?\n *\n * InlineFragment : ... TypeCondition? Directives? SelectionSet\n */\nfunc parseFragment(parser *Parser) (interface{}, error) {\n\tvar (\n\t\terr error\n\t)\n\tstart := parser.Token.Start\n\tif _, err = expect(parser, lexer.SPREAD); err != nil {\n\t\treturn nil, err\n\t}\n\tif peek(parser, lexer.NAME) && parser.Token.Value != \"on\" {\n\t\tname, err := parseFragmentName(parser)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdirectives, err := parseDirectives(parser)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn ast.NewFragmentSpread(&ast.FragmentSpread{\n\t\t\tName:       name,\n\t\t\tDirectives: directives,\n\t\t\tLoc:        loc(parser, start),\n\t\t}), nil\n\t}\n\tvar typeCondition *ast.Named\n\tif parser.Token.Value == \"on\" {\n\t\tif err := advance(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tname, err := parseNamed(parser)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttypeCondition = name\n\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tselectionSet, err := parseSelectionSet(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewInlineFragment(&ast.InlineFragment{\n\t\tTypeCondition: typeCondition,\n\t\tDirectives:    directives,\n\t\tSelectionSet:  selectionSet,\n\t\tLoc:           loc(parser, start),\n\t}), nil\n}\n\n/**\n * FragmentDefinition :\n *   - fragment FragmentName on TypeCondition Directives? SelectionSet\n *\n * TypeCondition : NamedType\n */\nfunc parseFragmentDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\t_, err := expectKeyWord(parser, lexer.FRAGMENT)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseFragmentName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expectKeyWord(parser, \"on\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttypeCondition, err := parseNamed(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tselectionSet, err := parseSelectionSet(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewFragmentDefinition(&ast.FragmentDefinition{\n\t\tName:          name,\n\t\tTypeCondition: typeCondition,\n\t\tDirectives:    directives,\n\t\tSelectionSet:  selectionSet,\n\t\tLoc:           loc(parser, start),\n\t}), nil\n}\n\n/**\n * FragmentName : Name but not `on`\n */\nfunc parseFragmentName(parser *Parser) (*ast.Name, error) {\n\tif parser.Token.Value == \"on\" {\n\t\treturn nil, unexpected(parser, lexer.Token{})\n\t}\n\treturn parseName(parser)\n}\n\n/* Implements the parsing rules in the Values section. */\n\n/**\n * Value[Const] :\n *   - [~Const] Variable\n *   - IntValue\n *   - FloatValue\n *   - StringValue\n *   - BooleanValue\n *   - EnumValue\n *   - ListValue[?Const]\n *   - ObjectValue[?Const]\n *\n * BooleanValue : one of `true` `false`\n *\n * EnumValue : Name but not `true`, `false` or `null`\n */\nfunc parseValueLiteral(parser *Parser, isConst bool) (ast.Value, error) {\n\ttoken := parser.Token\n\tswitch token.Kind {\n\tcase lexer.BRACKET_L:\n\t\treturn parseList(parser, isConst)\n\tcase lexer.BRACE_L:\n\t\treturn parseObject(parser, isConst)\n\tcase lexer.INT:\n\t\tif err := advance(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn ast.NewIntValue(&ast.IntValue{\n\t\t\tValue: token.Value,\n\t\t\tLoc:   loc(parser, token.Start),\n\t\t}), nil\n\tcase lexer.FLOAT:\n\t\tif err := advance(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn ast.NewFloatValue(&ast.FloatValue{\n\t\t\tValue: token.Value,\n\t\t\tLoc:   loc(parser, token.Start),\n\t\t}), nil\n\tcase lexer.BLOCK_STRING, lexer.STRING:\n\t\treturn parseStringLiteral(parser)\n\tcase lexer.NAME:\n\t\tif token.Value == \"true\" || token.Value == \"false\" {\n\t\t\tif err := advance(parser); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tvalue := true\n\t\t\tif token.Value == \"false\" {\n\t\t\t\tvalue = false\n\t\t\t}\n\t\t\treturn ast.NewBooleanValue(&ast.BooleanValue{\n\t\t\t\tValue: value,\n\t\t\t\tLoc:   loc(parser, token.Start),\n\t\t\t}), nil\n\t\t} else if token.Value != \"null\" {\n\t\t\tif err := advance(parser); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn ast.NewEnumValue(&ast.EnumValue{\n\t\t\t\tValue: token.Value,\n\t\t\t\tLoc:   loc(parser, token.Start),\n\t\t\t}), nil\n\t\t}\n\tcase lexer.DOLLAR:\n\t\tif !isConst {\n\t\t\treturn parseVariable(parser)\n\t\t}\n\t}\n\n\treturn nil, unexpected(parser, lexer.Token{})\n}\n\nfunc parseConstValue(parser *Parser) (interface{}, error) {\n\tvalue, err := parseValueLiteral(parser, true)\n\tif err != nil {\n\t\treturn value, err\n\t}\n\treturn value, nil\n}\n\nfunc parseValueValue(parser *Parser) (interface{}, error) {\n\treturn parseValueLiteral(parser, false)\n}\n\n/**\n * ListValue[Const] :\n *   - [ ]\n *   - [ Value[?Const]+ ]\n */\nfunc parseList(parser *Parser, isConst bool) (*ast.ListValue, error) {\n\tstart := parser.Token.Start\n\tvar item parseFn = parseValueValue\n\tif isConst {\n\t\titem = parseConstValue\n\t}\n\tvalues := []ast.Value{}\n\tif iValues, err := reverse(parser,\n\t\tlexer.BRACKET_L, item, lexer.BRACKET_R,\n\t\tfalse,\n\t); err != nil {\n\t\treturn nil, err\n\t} else {\n\t\tfor _, iValue := range iValues {\n\t\t\tvalues = append(values, iValue.(ast.Value))\n\t\t}\n\t}\n\treturn ast.NewListValue(&ast.ListValue{\n\t\tValues: values,\n\t\tLoc:    loc(parser, start),\n\t}), nil\n}\n\n/**\n * ObjectValue[Const] :\n *   - { }\n *   - { ObjectField[?Const]+ }\n */\nfunc parseObject(parser *Parser, isConst bool) (*ast.ObjectValue, error) {\n\tstart := parser.Token.Start\n\tif _, err := expect(parser, lexer.BRACE_L); err != nil {\n\t\treturn nil, err\n\t}\n\tfields := []*ast.ObjectField{}\n\tfor {\n\t\tif skp, err := skip(parser, lexer.BRACE_R); err != nil {\n\t\t\treturn nil, err\n\t\t} else if skp {\n\t\t\tbreak\n\t\t}\n\t\tif field, err := parseObjectField(parser, isConst); err != nil {\n\t\t\treturn nil, err\n\t\t} else {\n\t\t\tfields = append(fields, field)\n\t\t}\n\t}\n\treturn ast.NewObjectValue(&ast.ObjectValue{\n\t\tFields: fields,\n\t\tLoc:    loc(parser, start),\n\t}), nil\n}\n\n/**\n * ObjectField[Const] : Name : Value[?Const]\n */\nfunc parseObjectField(parser *Parser, isConst bool) (*ast.ObjectField, error) {\n\tvar (\n\t\tname  *ast.Name\n\t\tvalue ast.Value\n\t\terr   error\n\t)\n\tstart := parser.Token.Start\n\tif name, err = parseName(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err = expect(parser, lexer.COLON); err != nil {\n\t\treturn nil, err\n\t}\n\tif value, err = parseValueLiteral(parser, isConst); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewObjectField(&ast.ObjectField{\n\t\tName:  name,\n\t\tValue: value,\n\t\tLoc:   loc(parser, start),\n\t}), nil\n}\n\n/* Implements the parsing rules in the Directives section. */\n\n/**\n * Directives : Directive+\n */\nfunc parseDirectives(parser *Parser) ([]*ast.Directive, error) {\n\tdirectives := []*ast.Directive{}\n\tfor peek(parser, lexer.AT) {\n\t\tif directive, err := parseDirective(parser); err != nil {\n\t\t\treturn directives, err\n\t\t} else {\n\t\t\tdirectives = append(directives, directive)\n\t\t}\n\t}\n\treturn directives, nil\n}\n\n/**\n * Directive : @ Name Arguments?\n */\nfunc parseDirective(parser *Parser) (*ast.Directive, error) {\n\tvar (\n\t\terr  error\n\t\tname *ast.Name\n\t\targs []*ast.Argument\n\t)\n\tstart := parser.Token.Start\n\tif _, err = expect(parser, lexer.AT); err != nil {\n\t\treturn nil, err\n\t}\n\tif name, err = parseName(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif args, err = parseArguments(parser); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewDirective(&ast.Directive{\n\t\tName:      name,\n\t\tArguments: args,\n\t\tLoc:       loc(parser, start),\n\t}), nil\n}\n\n/* Implements the parsing rules in the Types section. */\n\n/**\n * Type :\n *   - NamedType\n *   - ListType\n *   - NonNullType\n */\nfunc parseType(parser *Parser) (ttype ast.Type, err error) {\n\ttoken := parser.Token\n\t// [ String! ]!\n\tswitch token.Kind {\n\tcase lexer.BRACKET_L:\n\t\tif err = advance(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif ttype, err = parseType(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfallthrough\n\tcase lexer.BRACKET_R:\n\t\tif err = advance(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tttype = ast.NewList(&ast.List{\n\t\t\tType: ttype,\n\t\t\tLoc:  loc(parser, token.Start),\n\t\t})\n\tcase lexer.NAME:\n\t\tif ttype, err = parseNamed(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// BANG must be executed\n\tif skp, err := skip(parser, lexer.BANG); err != nil {\n\t\treturn nil, err\n\t} else if skp {\n\t\tttype = ast.NewNonNull(&ast.NonNull{\n\t\t\tType: ttype,\n\t\t\tLoc:  loc(parser, token.Start),\n\t\t})\n\t}\n\treturn ttype, nil\n}\n\n/**\n * NamedType : Name\n */\nfunc parseNamed(parser *Parser) (*ast.Named, error) {\n\tstart := parser.Token.Start\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewNamed(&ast.Named{\n\t\tName: name,\n\t\tLoc:  loc(parser, start),\n\t}), nil\n}\n\n/* Implements the parsing rules in the Type Definition section. */\n\n/**\n * TypeSystemDefinition :\n *   - SchemaDefinition\n *   - TypeDefinition\n *   - TypeExtension\n *   - DirectiveDefinition\n *\n * TypeDefinition :\n *   - ScalarTypeDefinition\n *   - ObjectTypeDefinition\n *   - InterfaceTypeDefinition\n *   - UnionTypeDefinition\n *   - EnumTypeDefinition\n *   - InputObjectTypeDefinition\n */\nfunc parseTypeSystemDefinition(parser *Parser) (ast.Node, error) {\n\tvar (\n\t\titem parseDefinitionFn\n\t\terr  error\n\t)\n\t// Many definitions begin with a description and require a lookahead.\n\tkeywordToken := parser.Token\n\tif peekDescription(parser) {\n\t\tif keywordToken, err = lookahead(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif keywordToken.Kind != lexer.NAME {\n\t\treturn nil, unexpected(parser, keywordToken)\n\t}\n\tvar ok bool\n\tif item, ok = tokenDefinitionFn[keywordToken.Value]; !ok {\n\t\treturn nil, unexpected(parser, keywordToken)\n\t}\n\treturn item(parser)\n}\n\n/**\n * SchemaDefinition : schema Directives? { OperationTypeDefinition+ }\n *\n * OperationTypeDefinition : OperationType : NamedType\n */\nfunc parseSchemaDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\t_, err := expectKeyWord(parser, \"schema\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\toperationTypesI, err := reverse(\n\t\tparser,\n\t\tlexer.BRACE_L, parseOperationTypeDefinition, lexer.BRACE_R,\n\t\ttrue,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\toperationTypes := []*ast.OperationTypeDefinition{}\n\tfor _, op := range operationTypesI {\n\t\tif op, ok := op.(*ast.OperationTypeDefinition); ok {\n\t\t\toperationTypes = append(operationTypes, op)\n\t\t}\n\t}\n\treturn ast.NewSchemaDefinition(&ast.SchemaDefinition{\n\t\tOperationTypes: operationTypes,\n\t\tDirectives:     directives,\n\t\tLoc:            loc(parser, start),\n\t}), nil\n}\n\nfunc parseOperationTypeDefinition(parser *Parser) (interface{}, error) {\n\tstart := parser.Token.Start\n\toperation, err := parseOperationType(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expect(parser, lexer.COLON)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tttype, err := parseNamed(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewOperationTypeDefinition(&ast.OperationTypeDefinition{\n\t\tOperation: operation,\n\t\tType:      ttype,\n\t\tLoc:       loc(parser, start),\n\t}), nil\n}\n\n/**\n * ScalarTypeDefinition : Description? scalar Name Directives?\n */\nfunc parseScalarTypeDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\tdescription, err := parseDescription(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expectKeyWord(parser, lexer.SCALAR)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdef := ast.NewScalarDefinition(&ast.ScalarDefinition{\n\t\tName:        name,\n\t\tDescription: description,\n\t\tDirectives:  directives,\n\t\tLoc:         loc(parser, start),\n\t})\n\treturn def, nil\n}\n\n/**\n * ObjectTypeDefinition :\n *   Description?\n *   type Name ImplementsInterfaces? Directives? { FieldDefinition+ }\n */\nfunc parseObjectTypeDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\tdescription, err := parseDescription(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expectKeyWord(parser, lexer.TYPE)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tinterfaces, err := parseImplementsInterfaces(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tiFields, err := reverse(parser,\n\t\tlexer.BRACE_L, parseFieldDefinition, lexer.BRACE_R,\n\t\tfalse,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfields := []*ast.FieldDefinition{}\n\tfor _, iField := range iFields {\n\t\tif iField != nil {\n\t\t\tfields = append(fields, iField.(*ast.FieldDefinition))\n\t\t}\n\t}\n\treturn ast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\tName:        name,\n\t\tDescription: description,\n\t\tLoc:         loc(parser, start),\n\t\tInterfaces:  interfaces,\n\t\tDirectives:  directives,\n\t\tFields:      fields,\n\t}), nil\n}\n\n/**\n * ImplementsInterfaces :\n *   - implements `&`? NamedType\n *   - ImplementsInterfaces & NamedType\n */\nfunc parseImplementsInterfaces(parser *Parser) ([]*ast.Named, error) {\n\ttypes := []*ast.Named{}\n\tif parser.Token.Value == \"implements\" {\n\t\tif err := advance(parser); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// optional leading ampersand\n\t\tskip(parser, lexer.AMP)\n\t\tfor {\n\t\t\tttype, err := parseNamed(parser)\n\t\t\tif err != nil {\n\t\t\t\treturn types, err\n\t\t\t}\n\t\t\ttypes = append(types, ttype)\n\t\t\tif skipped, err := skip(parser, lexer.AMP); !skipped {\n\t\t\t\tbreak\n\t\t\t} else if err != nil {\n\t\t\t\treturn types, err\n\t\t\t}\n\t\t}\n\t}\n\treturn types, nil\n}\n\n/**\n * FieldDefinition : Description? Name ArgumentsDefinition? : Type Directives?\n */\nfunc parseFieldDefinition(parser *Parser) (interface{}, error) {\n\tstart := parser.Token.Start\n\tdescription, err := parseDescription(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\targs, err := parseArgumentDefs(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expect(parser, lexer.COLON)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tttype, err := parseType(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewFieldDefinition(&ast.FieldDefinition{\n\t\tName:        name,\n\t\tDescription: description,\n\t\tArguments:   args,\n\t\tType:        ttype,\n\t\tDirectives:  directives,\n\t\tLoc:         loc(parser, start),\n\t}), nil\n}\n\n/**\n * ArgumentsDefinition : ( InputValueDefinition+ )\n */\nfunc parseArgumentDefs(parser *Parser) ([]*ast.InputValueDefinition, error) {\n\tinputValueDefinitions := []*ast.InputValueDefinition{}\n\n\tif !peek(parser, lexer.PAREN_L) {\n\t\treturn inputValueDefinitions, nil\n\t}\n\tiInputValueDefinitions, err := reverse(parser,\n\t\tlexer.PAREN_L, parseInputValueDef, lexer.PAREN_R,\n\t\ttrue,\n\t)\n\tif err != nil {\n\t\treturn inputValueDefinitions, err\n\t}\n\tfor _, iInputValueDefinition := range iInputValueDefinitions {\n\t\tif iInputValueDefinition != nil {\n\t\t\tinputValueDefinitions = append(inputValueDefinitions, iInputValueDefinition.(*ast.InputValueDefinition))\n\t\t}\n\t}\n\treturn inputValueDefinitions, err\n}\n\n/**\n * InputValueDefinition : Description? Name : Type DefaultValue? Directives?\n */\nfunc parseInputValueDef(parser *Parser) (interface{}, error) {\n\tvar (\n\t\tdescription *ast.StringValue\n\t\tname        *ast.Name\n\t\tttype       ast.Type\n\t\tdirectives  []*ast.Directive\n\t\terr         error\n\t)\n\tstart := parser.Token.Start\n\tif description, err = parseDescription(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif name, err = parseName(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err = expect(parser, lexer.COLON); err != nil {\n\t\treturn nil, err\n\t}\n\tif ttype, err = parseType(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tvar defaultValue ast.Value\n\tif skp, err := skip(parser, lexer.EQUALS); err != nil {\n\t\treturn nil, err\n\t} else if skp {\n\t\tval, err := parseConstValue(parser)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif val, ok := val.(ast.Value); ok {\n\t\t\tdefaultValue = val\n\t\t}\n\t}\n\tif directives, err = parseDirectives(parser); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewInputValueDefinition(&ast.InputValueDefinition{\n\t\tName:         name,\n\t\tDescription:  description,\n\t\tType:         ttype,\n\t\tDefaultValue: defaultValue,\n\t\tDirectives:   directives,\n\t\tLoc:          loc(parser, start),\n\t}), nil\n}\n\n/**\n * InterfaceTypeDefinition :\n *   Description?\n *   interface Name Directives? { FieldDefinition+ }\n */\nfunc parseInterfaceTypeDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\tdescription, err := parseDescription(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expectKeyWord(parser, lexer.INTERFACE)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tiFields, err := reverse(parser,\n\t\tlexer.BRACE_L, parseFieldDefinition, lexer.BRACE_R,\n\t\tfalse,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfields := []*ast.FieldDefinition{}\n\tfor _, iField := range iFields {\n\t\tif iField != nil {\n\t\t\tfields = append(fields, iField.(*ast.FieldDefinition))\n\t\t}\n\t}\n\treturn ast.NewInterfaceDefinition(&ast.InterfaceDefinition{\n\t\tName:        name,\n\t\tDescription: description,\n\t\tDirectives:  directives,\n\t\tLoc:         loc(parser, start),\n\t\tFields:      fields,\n\t}), nil\n}\n\n/**\n * UnionTypeDefinition : Description? union Name Directives? = UnionMembers\n */\nfunc parseUnionTypeDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\tdescription, err := parseDescription(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expectKeyWord(parser, lexer.UNION)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expect(parser, lexer.EQUALS)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttypes, err := parseUnionMembers(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewUnionDefinition(&ast.UnionDefinition{\n\t\tName:        name,\n\t\tDescription: description,\n\t\tDirectives:  directives,\n\t\tLoc:         loc(parser, start),\n\t\tTypes:       types,\n\t}), nil\n}\n\n/**\n * UnionMembers :\n *   - NamedType\n *   - UnionMembers | NamedType\n */\nfunc parseUnionMembers(parser *Parser) ([]*ast.Named, error) {\n\tmembers := []*ast.Named{}\n\tfor {\n\t\tmember, err := parseNamed(parser)\n\t\tif err != nil {\n\t\t\treturn members, err\n\t\t}\n\t\tmembers = append(members, member)\n\t\tif skp, err := skip(parser, lexer.PIPE); err != nil {\n\t\t\treturn nil, err\n\t\t} else if !skp {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn members, nil\n}\n\n/**\n * EnumTypeDefinition : Description? enum Name Directives? { EnumValueDefinition+ }\n */\nfunc parseEnumTypeDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\tdescription, err := parseDescription(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expectKeyWord(parser, lexer.ENUM)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tiEnumValueDefs, err := reverse(parser,\n\t\tlexer.BRACE_L, parseEnumValueDefinition, lexer.BRACE_R,\n\t\tfalse,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvalues := []*ast.EnumValueDefinition{}\n\tfor _, iEnumValueDef := range iEnumValueDefs {\n\t\tif iEnumValueDef != nil {\n\t\t\tvalues = append(values, iEnumValueDef.(*ast.EnumValueDefinition))\n\t\t}\n\t}\n\treturn ast.NewEnumDefinition(&ast.EnumDefinition{\n\t\tName:        name,\n\t\tDescription: description,\n\t\tDirectives:  directives,\n\t\tLoc:         loc(parser, start),\n\t\tValues:      values,\n\t}), nil\n}\n\n/**\n * EnumValueDefinition : Description? EnumValue Directives?\n *\n * EnumValue : Name\n */\nfunc parseEnumValueDefinition(parser *Parser) (interface{}, error) {\n\tstart := parser.Token.Start\n\tdescription, err := parseDescription(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewEnumValueDefinition(&ast.EnumValueDefinition{\n\t\tName:        name,\n\t\tDescription: description,\n\t\tDirectives:  directives,\n\t\tLoc:         loc(parser, start),\n\t}), nil\n}\n\n/**\n * InputObjectTypeDefinition :\n *   - Description? input Name Directives? { InputValueDefinition+ }\n */\nfunc parseInputObjectTypeDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\tdescription, err := parseDescription(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = expectKeyWord(parser, lexer.INPUT)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tname, err := parseName(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdirectives, err := parseDirectives(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tiInputValueDefinitions, err := reverse(parser,\n\t\tlexer.BRACE_L, parseInputValueDef, lexer.BRACE_R,\n\t\tfalse,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfields := []*ast.InputValueDefinition{}\n\tfor _, iInputValueDefinition := range iInputValueDefinitions {\n\t\tif iInputValueDefinition != nil {\n\t\t\tfields = append(fields, iInputValueDefinition.(*ast.InputValueDefinition))\n\t\t}\n\t}\n\treturn ast.NewInputObjectDefinition(&ast.InputObjectDefinition{\n\t\tName:        name,\n\t\tDescription: description,\n\t\tDirectives:  directives,\n\t\tLoc:         loc(parser, start),\n\t\tFields:      fields,\n\t}), nil\n}\n\n/**\n * TypeExtensionDefinition : extend ObjectTypeDefinition\n */\nfunc parseTypeExtensionDefinition(parser *Parser) (ast.Node, error) {\n\tstart := parser.Token.Start\n\t_, err := expectKeyWord(parser, lexer.EXTEND)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefinition, err := parseObjectTypeDefinition(parser)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewTypeExtensionDefinition(&ast.TypeExtensionDefinition{\n\t\tLoc:        loc(parser, start),\n\t\tDefinition: definition.(*ast.ObjectDefinition),\n\t}), nil\n}\n\n/**\n * DirectiveDefinition :\n *   - directive @ Name ArgumentsDefinition? on DirectiveLocations\n */\nfunc parseDirectiveDefinition(parser *Parser) (ast.Node, error) {\n\tvar (\n\t\terr         error\n\t\tdescription *ast.StringValue\n\t\tname        *ast.Name\n\t\targs        []*ast.InputValueDefinition\n\t\tlocations   []*ast.Name\n\t)\n\tstart := parser.Token.Start\n\tif description, err = parseDescription(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err = expectKeyWord(parser, lexer.DIRECTIVE); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err = expect(parser, lexer.AT); err != nil {\n\t\treturn nil, err\n\t}\n\tif name, err = parseName(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif args, err = parseArgumentDefs(parser); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err = expectKeyWord(parser, \"on\"); err != nil {\n\t\treturn nil, err\n\t}\n\tif locations, err = parseDirectiveLocations(parser); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ast.NewDirectiveDefinition(&ast.DirectiveDefinition{\n\t\tLoc:         loc(parser, start),\n\t\tName:        name,\n\t\tDescription: description,\n\t\tArguments:   args,\n\t\tLocations:   locations,\n\t}), nil\n}\n\n/**\n * DirectiveLocations :\n *   - Name\n *   - DirectiveLocations | Name\n */\nfunc parseDirectiveLocations(parser *Parser) ([]*ast.Name, error) {\n\tlocations := []*ast.Name{}\n\tfor {\n\t\tif name, err := parseName(parser); err != nil {\n\t\t\treturn locations, err\n\t\t} else {\n\t\t\tlocations = append(locations, name)\n\t\t}\n\n\t\tif hasPipe, err := skip(parser, lexer.PIPE); err != nil {\n\t\t\treturn locations, err\n\t\t} else if !hasPipe {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn locations, nil\n}\n\nfunc parseStringLiteral(parser *Parser) (*ast.StringValue, error) {\n\ttoken := parser.Token\n\tif err := advance(parser); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ast.NewStringValue(&ast.StringValue{\n\t\tValue: token.Value,\n\t\tLoc:   loc(parser, token.Start),\n\t}), nil\n}\n\n/**\n * Description : StringValue\n */\nfunc parseDescription(parser *Parser) (*ast.StringValue, error) {\n\tif peekDescription(parser) {\n\t\treturn parseStringLiteral(parser)\n\t}\n\treturn nil, nil\n}\n\n/* Core parsing utility functions */\n\n// Returns a location object, used to identify the place in\n// the source that created a given parsed object.\nfunc loc(parser *Parser, start int) *ast.Location {\n\tif parser.Options.NoLocation {\n\t\treturn nil\n\t}\n\tif parser.Options.NoSource {\n\t\treturn ast.NewLocation(&ast.Location{\n\t\t\tStart: start,\n\t\t\tEnd:   parser.PrevEnd,\n\t\t})\n\t}\n\treturn ast.NewLocation(&ast.Location{\n\t\tStart:  start,\n\t\tEnd:    parser.PrevEnd,\n\t\tSource: parser.Source,\n\t})\n}\n\n// Moves the internal parser object to the next lexed token.\nfunc advance(parser *Parser) error {\n\tparser.PrevEnd = parser.Token.End\n\ttoken, err := parser.LexToken(parser.PrevEnd)\n\tif err != nil {\n\t\treturn err\n\t}\n\tparser.Token = token\n\treturn nil\n}\n\n// lookahead retrieves the next token\nfunc lookahead(parser *Parser) (lexer.Token, error) {\n\treturn parser.LexToken(parser.Token.End)\n}\n\n// Determines if the next token is of a given kind\nfunc peek(parser *Parser, Kind lexer.TokenKind) bool {\n\treturn parser.Token.Kind == Kind\n}\n\n// peekDescription determines if the next token is a string value\nfunc peekDescription(parser *Parser) bool {\n\treturn peek(parser, lexer.STRING) || peek(parser, lexer.BLOCK_STRING)\n}\n\n// If the next token is of the given kind, return true after advancing\n// the parser. Otherwise, do not change the parser state and return false.\nfunc skip(parser *Parser, Kind lexer.TokenKind) (bool, error) {\n\tif parser.Token.Kind == Kind {\n\t\treturn true, advance(parser)\n\t}\n\treturn false, nil\n}\n\n// If the next token is of the given kind, return that token after advancing\n// the parser. Otherwise, do not change the parser state and return error.\nfunc expect(parser *Parser, kind lexer.TokenKind) (lexer.Token, error) {\n\ttoken := parser.Token\n\tif token.Kind == kind {\n\t\treturn token, advance(parser)\n\t}\n\tdescp := fmt.Sprintf(\"Expected %s, found %s\", kind, lexer.GetTokenDesc(token))\n\treturn token, gqlerrors.NewSyntaxError(parser.Source, token.Start, descp)\n}\n\n// If the next token is a keyword with the given value, return that token after\n// advancing the parser. Otherwise, do not change the parser state and return false.\nfunc expectKeyWord(parser *Parser, value string) (lexer.Token, error) {\n\ttoken := parser.Token\n\tif token.Kind == lexer.NAME && token.Value == value {\n\t\treturn token, advance(parser)\n\t}\n\tdescp := fmt.Sprintf(\"Expected \\\"%s\\\", found %s\", value, lexer.GetTokenDesc(token))\n\treturn token, gqlerrors.NewSyntaxError(parser.Source, token.Start, descp)\n}\n\n// Helper function for creating an error when an unexpected lexed token\n// is encountered.\nfunc unexpected(parser *Parser, atToken lexer.Token) error {\n\tvar token = atToken\n\tif (atToken == lexer.Token{}) {\n\t\ttoken = parser.Token\n\t}\n\tdescription := fmt.Sprintf(\"Unexpected %v\", lexer.GetTokenDesc(token))\n\treturn gqlerrors.NewSyntaxError(parser.Source, token.Start, description)\n}\n\nfunc unexpectedEmpty(parser *Parser, beginLoc int, openKind, closeKind lexer.TokenKind) error {\n\tdescription := fmt.Sprintf(\"Unexpected empty IN %s%s\", openKind, closeKind)\n\treturn gqlerrors.NewSyntaxError(parser.Source, beginLoc, description)\n}\n\n//  Returns list of parse nodes, determined by\n// the parseFn. This list begins with a lex token of openKind\n// and ends with a lex token of closeKind. Advances the parser\n// to the next lex token after the closing token.\n// if zinteger is true, len(nodes) > 0\nfunc reverse(parser *Parser, openKind lexer.TokenKind, parseFn parseFn, closeKind lexer.TokenKind, zinteger bool) ([]interface{}, error) {\n\ttoken, err := expect(parser, openKind)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar nodes []interface{}\n\tfor {\n\t\tif skp, err := skip(parser, closeKind); err != nil {\n\t\t\treturn nil, err\n\t\t} else if skp {\n\t\t\tbreak\n\t\t}\n\t\tnode, err := parseFn(parser)\n\t\tif err != nil {\n\t\t\treturn nodes, err\n\t\t}\n\t\tnodes = append(nodes, node)\n\t}\n\tif zinteger && len(nodes) == 0 {\n\t\treturn nodes, unexpectedEmpty(parser, token.Start, openKind, closeKind)\n\t}\n\treturn nodes, nil\n}\n"
  },
  {
    "path": "language/parser/parser_test.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/language/printer\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\nfunc TestParser_BadToken(t *testing.T) {\n\t_, err := Parse(ParseParams{\n\t\tSource: &source.Source{\n\t\t\tBody: []byte(\"query _ {\\n  me {\\n    id`\\n  }\\n}\"),\n\t\t\tName: \"GraphQL\",\n\t\t},\n\t})\n\tif err == nil {\n\t\tt.Fatal(\"expected a parse error\")\n\t}\n}\n\nfunc TestParser_AcceptsOptionToNotIncludeSource(t *testing.T) {\n\topts := ParseOptions{\n\t\tNoSource: true,\n\t}\n\tparams := ParseParams{\n\t\tSource:  \"{ field }\",\n\t\tOptions: opts,\n\t}\n\tdocument, err := Parse(params)\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\toDef := ast.OperationDefinition{\n\t\tKind: \"OperationDefinition\",\n\t\tLoc: &ast.Location{\n\t\t\tStart: 0, End: 9,\n\t\t},\n\t\tOperation:  \"query\",\n\t\tDirectives: []*ast.Directive{},\n\t\tSelectionSet: &ast.SelectionSet{\n\t\t\tKind: \"SelectionSet\",\n\t\t\tLoc: &ast.Location{\n\t\t\t\tStart: 0, End: 9,\n\t\t\t},\n\t\t\tSelections: []ast.Selection{\n\t\t\t\t&ast.Field{\n\t\t\t\t\tKind: \"Field\",\n\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\tStart: 2, End: 7,\n\t\t\t\t\t},\n\t\t\t\t\tName: &ast.Name{\n\t\t\t\t\t\tKind: \"Name\",\n\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\tStart: 2, End: 7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"field\",\n\t\t\t\t\t},\n\t\t\t\t\tArguments:  []*ast.Argument{},\n\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\texpectedDocument := ast.NewDocument(&ast.Document{\n\t\tLoc: &ast.Location{\n\t\t\tStart: 0, End: 9,\n\t\t},\n\t\tDefinitions: []ast.Node{&oDef},\n\t})\n\tif !reflect.DeepEqual(document, expectedDocument) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expectedDocument, document)\n\t}\n}\n\nfunc TestParser_ParseProvidesUsefulErrors(t *testing.T) {\n\topts := ParseOptions{\n\t\tNoSource: true,\n\t}\n\tparams := ParseParams{\n\t\tSource:  \"{\",\n\t\tOptions: opts,\n\t}\n\t_, err := Parse(params)\n\n\texpectedError := &gqlerrors.Error{\n\t\tMessage: `Syntax Error GraphQL (1:2) Expected Name, found EOF\n\n1: {\n    ^\n`,\n\t\tPositions: []int{1},\n\t\tLocations: []location.SourceLocation{{Line: 1, Column: 2}},\n\t}\n\tcheckError(t, err, expectedError)\n\n\ttestErrorMessagesTable := []errorMessageTest{\n\t\t{\n\t\t\t`{ ...MissingOn }\nfragment MissingOn Type\n`,\n\t\t\t`Syntax Error GraphQL (2:20) Expected \"on\", found Name \"Type\"`,\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t`{ field: {} }`,\n\t\t\t`Syntax Error GraphQL (1:10) Expected Name, found {`,\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t`notanoperation Foo { field }`,\n\t\t\t`Syntax Error GraphQL (1:1) Unexpected Name \"notanoperation\"`,\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"...\",\n\t\t\t`Syntax Error GraphQL (1:1) Unexpected ...`,\n\t\t\tfalse,\n\t\t},\n\t}\n\tfor _, test := range testErrorMessagesTable {\n\t\tif test.skipped != false {\n\t\t\tt.Skipf(\"Skipped test: %v\", test.source)\n\t\t}\n\t\t_, err := Parse(ParseParams{Source: test.source})\n\t\tcheckErrorMessage(t, err, test.expectedMessage)\n\t}\n\n}\n\nfunc TestParser_ParseProvidesUsefulErrorsWhenUsingSource(t *testing.T) {\n\ttest := errorMessageTest{\n\t\tsource.NewSource(&source.Source{\n\t\t\tBody: []byte(\"query\"),\n\t\t\tName: \"MyQuery.graphql\",\n\t\t}),\n\t\t`Syntax Error MyQuery.graphql (1:6) Expected {, found EOF`,\n\t\tfalse,\n\t}\n\ttestErrorMessage(t, test)\n}\n\nfunc TestParser_ParsesVariableInlineValues(t *testing.T) {\n\tsource := `{ field(complex: { a: { b: [ $var ] } }) }`\n\t// should not return error\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_ParsesConstantDefaultValues(t *testing.T) {\n\ttest := errorMessageTest{\n\t\t`query Foo($x: Complex = { a: { b: [ $var ] } }) { field }`,\n\t\t`Syntax Error GraphQL (1:37) Unexpected $`,\n\t\tfalse,\n\t}\n\ttestErrorMessage(t, test)\n}\n\nfunc TestParser_DoesNotAcceptFragmentsNameOn(t *testing.T) {\n\ttest := errorMessageTest{\n\t\t`fragment on on on { on }`,\n\t\t`Syntax Error GraphQL (1:10) Unexpected Name \"on\"`,\n\t\tfalse,\n\t}\n\ttestErrorMessage(t, test)\n}\n\nfunc TestParser_DoesNotAcceptFragmentsSpreadOfOn(t *testing.T) {\n\ttest := errorMessageTest{\n\t\t`{ ...on }'`,\n\t\t`Syntax Error GraphQL (1:9) Expected Name, found }`,\n\t\tfalse,\n\t}\n\ttestErrorMessage(t, test)\n}\n\nfunc TestParser_DoesNotAllowNullAsValue(t *testing.T) {\n\ttest := errorMessageTest{\n\t\t`{ fieldWithNullableStringInput(input: null) }'`,\n\t\t`Syntax Error GraphQL (1:39) Unexpected Name \"null\"`,\n\t\tfalse,\n\t}\n\ttestErrorMessage(t, test)\n}\n\nfunc TestParser_ParsesMultiByteCharacters_Unicode(t *testing.T) {\n\n\tdoc := `\n        # This comment has a \\u0A0A multi-byte character.\n        { field(arg: \"Has a \\u0A0A multi-byte character.\") }\n\t`\n\tastDoc := parse(t, doc)\n\n\texpectedASTDoc := ast.NewDocument(&ast.Document{\n\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\tStart: 67,\n\t\t\tEnd:   121,\n\t\t}),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewOperationDefinition(&ast.OperationDefinition{\n\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\tStart: 67,\n\t\t\t\t\tEnd:   119,\n\t\t\t\t}),\n\t\t\t\tOperation: \"query\",\n\t\t\t\tSelectionSet: ast.NewSelectionSet(&ast.SelectionSet{\n\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\tStart: 67,\n\t\t\t\t\t\tEnd:   119,\n\t\t\t\t\t}),\n\t\t\t\t\tSelections: []ast.Selection{\n\t\t\t\t\t\tast.NewField(&ast.Field{\n\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\tStart: 67,\n\t\t\t\t\t\t\t\tEnd:   117,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\t\tStart: 69,\n\t\t\t\t\t\t\t\t\tEnd:   74,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tValue: \"field\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tArguments: []*ast.Argument{\n\t\t\t\t\t\t\t\tast.NewArgument(&ast.Argument{\n\t\t\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\t\t\tStart: 75,\n\t\t\t\t\t\t\t\t\t\tEnd:   116,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\n\t\t\t\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\t\t\t\tStart: 75,\n\t\t\t\t\t\t\t\t\t\t\tEnd:   78,\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\tValue: \"arg\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\tValue: ast.NewStringValue(&ast.StringValue{\n\n\t\t\t\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\t\t\t\tStart: 80,\n\t\t\t\t\t\t\t\t\t\t\tEnd:   116,\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\tValue: \"Has a \\u0A0A multi-byte character.\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t}),\n\t\t},\n\t})\n\n\tastDocQuery := printer.Print(astDoc)\n\texpectedASTDocQuery := printer.Print(expectedASTDoc)\n\n\tif !reflect.DeepEqual(astDocQuery, expectedASTDocQuery) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", astDocQuery, expectedASTDocQuery)\n\t}\n}\n\nfunc TestParser_ParsesMultiByteCharacters_UnicodeText(t *testing.T) {\n\n\tdoc := `\n        # This comment has a фы世界 multi-byte character.\n        { field(arg: \"Has a фы世界 multi-byte character.\") }\n\t`\n\tastDoc := parse(t, doc)\n\n\texpectedASTDoc := ast.NewDocument(&ast.Document{\n\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\tStart: 67,\n\t\t\tEnd:   121,\n\t\t}),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewOperationDefinition(&ast.OperationDefinition{\n\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\tStart: 67,\n\t\t\t\t\tEnd:   119,\n\t\t\t\t}),\n\t\t\t\tOperation: \"query\",\n\t\t\t\tSelectionSet: ast.NewSelectionSet(&ast.SelectionSet{\n\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\tStart: 67,\n\t\t\t\t\t\tEnd:   119,\n\t\t\t\t\t}),\n\t\t\t\t\tSelections: []ast.Selection{\n\t\t\t\t\t\tast.NewField(&ast.Field{\n\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\tStart: 67,\n\t\t\t\t\t\t\t\tEnd:   117,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\t\tStart: 69,\n\t\t\t\t\t\t\t\t\tEnd:   74,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tValue: \"field\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tArguments: []*ast.Argument{\n\t\t\t\t\t\t\t\tast.NewArgument(&ast.Argument{\n\t\t\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\t\t\tStart: 75,\n\t\t\t\t\t\t\t\t\t\tEnd:   116,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\n\t\t\t\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\t\t\t\tStart: 75,\n\t\t\t\t\t\t\t\t\t\t\tEnd:   78,\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\tValue: \"arg\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\tValue: ast.NewStringValue(&ast.StringValue{\n\n\t\t\t\t\t\t\t\t\t\tLoc: ast.NewLocation(&ast.Location{\n\t\t\t\t\t\t\t\t\t\t\tStart: 80,\n\t\t\t\t\t\t\t\t\t\t\tEnd:   116,\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\tValue: \"Has a фы世界 multi-byte character.\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t}),\n\t\t},\n\t})\n\n\tastDocQuery := printer.Print(astDoc)\n\texpectedASTDocQuery := printer.Print(expectedASTDoc)\n\n\tif !reflect.DeepEqual(astDocQuery, expectedASTDocQuery) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", astDocQuery, expectedASTDocQuery)\n\t}\n}\n\nfunc TestParser_ParsesKitchenSink(t *testing.T) {\n\tb, err := ioutil.ReadFile(\"../../kitchen-sink.graphql\")\n\tif err != nil {\n\t\tt.Fatalf(\"unable to load kitchen-sink.graphql\")\n\t}\n\tsource := string(b)\n\t_, err = Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_AllowsNonKeywordsAnywhereNameIsAllowed(t *testing.T) {\n\tnonKeywords := []string{\n\t\t\"on\",\n\t\t\"fragment\",\n\t\t\"query\",\n\t\t\"mutation\",\n\t\t\"subscription\",\n\t\t\"true\",\n\t\t\"false\",\n\t}\n\tfor _, keyword := range nonKeywords {\n\t\tfragmentName := keyword\n\t\t// You can't define or reference a fragment named `on`.\n\t\tif keyword == \"on\" {\n\t\t\tfragmentName = \"a\"\n\t\t}\n\t\tsource := fmt.Sprintf(`query %v {\n\t\t\t... %v\n\t\t\t... on %v { field }\n\t\t}\n\t\tfragment %v on Type {\n\t\t%v(%v: $%v) @%v(%v: $%v)\n\t\t}\n\t\t`, keyword, fragmentName, keyword, fragmentName, keyword, keyword, keyword, keyword, keyword, keyword)\n\t\t_, err := Parse(ParseParams{Source: source})\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t}\n}\n\nfunc TestParser_ParsesExperimentalSubscriptionFeature(t *testing.T) {\n\tsource := `\n      subscription Foo {\n        subscriptionField\n      }\n    `\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_ParsesAnonymousMutationOperations(t *testing.T) {\n\tsource := `\n      mutation {\n        mutationField\n      }\n    `\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_ParsesAnonymousSubscriptionOperations(t *testing.T) {\n\tsource := `\n      subscription {\n        subscriptionField\n      }\n    `\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_ParsesNamedMutationOperations(t *testing.T) {\n\tsource := `\n      mutation Foo {\n        mutationField\n      }\n    `\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_ParsesNamedSubscriptionOperations(t *testing.T) {\n\tsource := `\n      subscription Foo {\n        subscriptionField\n      }\n    `\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_ParsesFieldDefinitionWithDescription(t *testing.T) {\n\tsource := `\n\t\ttype Foo implements Bar {\n\t\t\t\"\"\"\n\t\t\tfoo is quite the field.\n\t\t\t\"\"\"\n\t\t\tfoo: String!\n\t\t}\n\t`\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_ParsesInputValueDefinitionWithDescription(t *testing.T) {\n\tsource := `\n\t\ttype Foo implements Bar {\n\t\t\tfoo(\n\t\t\t\t\"\"\"\n\t\t\t\tinput value comment\n\t\t\t\t\"\"\"\n\t\t\t\tbar: String!\n\t\t\t): String!\n\t\t}\n\t`\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_ParsesEnumValueDefinitionWithDescription(t *testing.T) {\n\tsource := `\n\t\tenum Site {\n\t\t\t\"description 1\"\n\t\t\tDESKTOP\n\t\t\t\"\"\"\n\t\t\tdescription 2\n\t\t\t\"\"\"\n\t\t\tMOBILE\n\t\t}\n\t`\n\t_, err := Parse(ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestParser_DefinitionsWithDescriptions(t *testing.T) {\n\ttestCases := []struct {\n\t\tname            string\n\t\tsource          string\n\t\texpectedComment string\n\t}{\n\t\t{\n\t\t\tname: \"directives\",\n\t\t\tsource: `\n\t\t\t\t\"cool skip\"\n\t\t\t\tdirective @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\t\t\t`,\n\t\t\texpectedComment: \"cool skip\",\n\t\t},\n\t\t{\n\t\t\tname: \"input\",\n\t\t\tsource: `\n\t\t\t\t\"\"\"\n\t\t\t\tInputType is indeed a type\n\t\t\t\t\"\"\"\n\t\t\t\tinput InputType {\n\t\t\t\t\tkey: String!\n\t\t\t\t\tanswer: Int = 42\n\t\t\t\t}\n\t\t\t`,\n\t\t\texpectedComment: \"InputType is indeed a type\",\n\t\t},\n\t\t{\n\t\t\tname: \"enum\",\n\t\t\tsource: `\n\t\t\t\t\"\"\"\n\t\t\t\tdescription 2\n\t\t\t\t\"\"\"\n\t\t\t\tenum Site {\n\t\t\t\t\tDESKTOP\n\t\t\t\t\tMOBILE\n\t\t\t\t}\n\t\t\t`,\n\t\t\texpectedComment: \"description 2\",\n\t\t},\n\t\t{\n\t\t\tname: \"union\",\n\t\t\tsource: `\n\t\t\t\t\"\"\"\n\t\t\t\tCruft ...\n\t\t\t\t\"\"\"\n\t\t\t\tunion Cruft = Foo | Bar\n\t\t\t`,\n\t\t\texpectedComment: \"Cruft ...\",\n\t\t},\n\t\t{\n\t\t\tname: \"interface\",\n\t\t\tsource: `\n\t\t\t\t\"\"\"\n\t\t\t\tBar is a symptom of the communist agenda\n\t\t\t\t\"\"\"\n\t\t\t\tinterface  Bar {\n\t\t\t\t\tfoo: String!\n\t\t\t\t}\n\t\t\t`,\n\t\t\texpectedComment: \"Bar is a symptom of the communist agenda\",\n\t\t},\n\t\t{\n\t\t\tname: \"object\",\n\t\t\tsource: `\n\t\t\t\t\"\"\"\n\t\t\t\t★ Foo ★\n\t\t\t\t\"\"\"\n\t\t\t\ttype Foo implements Bar {\n\t\t\t\t\tfoo: String!\n\t\t\t\t}\n\t\t\t`,\n\t\t\texpectedComment: \"★ Foo ★\",\n\t\t},\n\t\t{\n\t\t\tname: \"scalar\",\n\t\t\tsource: `\n\t\t\t\t\"\"\"\n\t\t\t\tReturns RFC666; includes timezone offset.\n\t\t\t\t\"\"\"\n\t\t\t\tscalar TimeWithZone\n\t\t\t`,\n\t\t\texpectedComment: \"Returns RFC666; includes timezone offset.\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(fmt.Sprintf(\"%s may have comments\", tc.name), func(t *testing.T) {\n\t\t\tdoc, err := Parse(ParseParams{Source: tc.source})\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif doc == nil {\n\t\t\t\tt.Fatal(\"no document was returned\")\n\t\t\t}\n\t\t\tfor _, def := range doc.Definitions {\n\t\t\t\tfmt.Printf(\"%#v\\n\", def)\n\t\t\t}\n\t\t\tif node, ok := doc.Definitions[0].(ast.DescribableNode); !ok {\n\t\t\t\tt.Fatalf(\"unexpected node received %#v\", doc.Definitions[0])\n\t\t\t} else if node.GetDescription().Value != tc.expectedComment {\n\t\t\t\tt.Fatalf(\n\t\t\t\t\t\"parsed description '%s' does not match '%s'\",\n\t\t\t\t\tnode.GetDescription().Value,\n\t\t\t\t\ttc.expectedComment,\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestParser_ParseCreatesAst(t *testing.T) {\n\tbody := `{\n  node(id: 4) {\n    id,\n    name\n  }\n}\n`\n\tsource := source.NewSource(&source.Source{\n\t\tBody: []byte(body),\n\t})\n\tdocument, err := Parse(\n\t\tParseParams{\n\t\t\tSource: source,\n\t\t\tOptions: ParseOptions{\n\t\t\t\tNoSource: true,\n\t\t\t},\n\t\t},\n\t)\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\n\toDef := ast.OperationDefinition{\n\t\tKind: \"OperationDefinition\",\n\t\tLoc: &ast.Location{\n\t\t\tStart: 0, End: 40,\n\t\t},\n\t\tOperation:  \"query\",\n\t\tDirectives: []*ast.Directive{},\n\t\tSelectionSet: &ast.SelectionSet{\n\t\t\tKind: \"SelectionSet\",\n\t\t\tLoc: &ast.Location{\n\t\t\t\tStart: 0, End: 40,\n\t\t\t},\n\t\t\tSelections: []ast.Selection{\n\t\t\t\t&ast.Field{\n\t\t\t\t\tKind: \"Field\",\n\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\tStart: 4, End: 38,\n\t\t\t\t\t},\n\t\t\t\t\tName: &ast.Name{\n\t\t\t\t\t\tKind: \"Name\",\n\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\tStart: 4, End: 8,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"node\",\n\t\t\t\t\t},\n\t\t\t\t\tArguments: []*ast.Argument{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tKind: \"Argument\",\n\t\t\t\t\t\t\tName: &ast.Name{\n\t\t\t\t\t\t\t\tKind: \"Name\",\n\t\t\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\t\t\tStart: 9, End: 11,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"id\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tValue: &ast.IntValue{\n\t\t\t\t\t\t\t\tKind: \"IntValue\",\n\t\t\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\t\t\tStart: 13, End: 14,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"4\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\t\tStart: 9, End: 14,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\tSelectionSet: &ast.SelectionSet{\n\t\t\t\t\t\tKind: \"SelectionSet\",\n\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\tStart: 16, End: 38,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSelections: []ast.Selection{\n\t\t\t\t\t\t\t&ast.Field{\n\t\t\t\t\t\t\t\tKind: \"Field\",\n\t\t\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\t\t\tStart: 22, End: 24,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tName: &ast.Name{\n\t\t\t\t\t\t\t\t\tKind: \"Name\",\n\t\t\t\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\t\t\t\tStart: 22, End: 24,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tValue: \"id\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tArguments:    []*ast.Argument{},\n\t\t\t\t\t\t\t\tDirectives:   []*ast.Directive{},\n\t\t\t\t\t\t\t\tSelectionSet: nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&ast.Field{\n\t\t\t\t\t\t\t\tKind: \"Field\",\n\t\t\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\t\t\tStart: 30, End: 34,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tName: &ast.Name{\n\t\t\t\t\t\t\t\t\tKind: \"Name\",\n\t\t\t\t\t\t\t\t\tLoc: &ast.Location{\n\t\t\t\t\t\t\t\t\t\tStart: 30, End: 34,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tArguments:    []*ast.Argument{},\n\t\t\t\t\t\t\t\tDirectives:   []*ast.Directive{},\n\t\t\t\t\t\t\t\tSelectionSet: nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\texpectedDocument := ast.NewDocument(&ast.Document{\n\t\tLoc: &ast.Location{\n\t\t\tStart: 0, End: 41,\n\t\t},\n\t\tDefinitions: []ast.Node{&oDef},\n\t})\n\tif !reflect.DeepEqual(document, expectedDocument) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expectedDocument, document.Definitions)\n\t}\n\n}\n\nfunc TestParser_DoesNotAcceptStringAsDefinition(t *testing.T) {\n\ttest := errorMessageTest{\n\t\t`String`,\n\t\t`Syntax Error GraphQL (1:1) Unexpected Name \"String\"`,\n\t\tfalse,\n\t}\n\ttestErrorMessage(t, test)\n}\n\ntype errorMessageTest struct {\n\tsource          interface{}\n\texpectedMessage string\n\tskipped         bool\n}\n\nfunc testErrorMessage(t *testing.T, test errorMessageTest) {\n\tif test.skipped != false {\n\t\tt.Skipf(\"Skipped test: %v\", test.source)\n\t}\n\t_, err := Parse(ParseParams{Source: test.source})\n\tcheckErrorMessage(t, err, test.expectedMessage)\n}\n\nfunc checkError(t *testing.T, err error, expectedError *gqlerrors.Error) {\n\tif expectedError == nil {\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\treturn // ok\n\t}\n\t// else expectedError != nil\n\tif err == nil {\n\t\tt.Fatalf(\"unexpected nil error\\nexpected:\\n%v\\n\\ngot:\\n%v\", expectedError, err)\n\t}\n\tif err.Error() != expectedError.Message {\n\t\tt.Fatalf(\"unexpected error.\\nexpected:\\n%v\\n\\ngot:\\n%v\", expectedError, err.Error())\n\t}\n\tgErr := toError(err)\n\tif gErr == nil {\n\t\tt.Fatalf(\"unexpected nil Error\")\n\t}\n\tif len(expectedError.Positions) > 0 && !reflect.DeepEqual(gErr.Positions, expectedError.Positions) {\n\t\tt.Fatalf(\"unexpected Error.Positions.\\nexpected:\\n%v\\n\\ngot:\\n%v\", expectedError.Positions, gErr.Positions)\n\t}\n\tif len(expectedError.Locations) > 0 && !reflect.DeepEqual(gErr.Locations, expectedError.Locations) {\n\t\tt.Fatalf(\"unexpected Error.Locations.\\nexpected:\\n%v\\n\\ngot:\\n%v\", expectedError.Locations, gErr.Locations)\n\t}\n}\n\nfunc checkErrorMessage(t *testing.T, err error, expectedMessage string) {\n\tif err == nil {\n\t\tt.Fatalf(\"unexpected nil error\\nexpected:\\n%v\\n\\ngot:\\n%v\", expectedMessage, err)\n\t}\n\tif err.Error() != expectedMessage {\n\t\t// only check first line of error message\n\t\tlines := strings.Split(err.Error(), \"\\n\")\n\t\tif lines[0] != expectedMessage {\n\t\t\tt.Fatalf(\"unexpected error.\\nexpected:\\n%v\\n\\ngot:\\n%v\", expectedMessage, lines[0])\n\t\t}\n\t}\n}\n\nfunc toError(err error) *gqlerrors.Error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\tswitch err := err.(type) {\n\tcase *gqlerrors.Error:\n\t\treturn err\n\tdefault:\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "language/parser/schema_parser_test.go",
    "content": "package parser\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\nfunc parse(t *testing.T, query string) *ast.Document {\n\tastDoc, err := Parse(ParseParams{\n\t\tSource: query,\n\t\tOptions: ParseOptions{\n\t\t\tNoLocation: false,\n\t\t\tNoSource:   true,\n\t\t},\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Parse failed: %v\", err)\n\t}\n\treturn astDoc\n}\n\nfunc testLoc(start int, end int) *ast.Location {\n\treturn &ast.Location{\n\t\tStart: start, End: end,\n\t}\n}\n\nfunc TestSchemaParser_SimpleType(t *testing.T) {\n\n\tbody := `\ntype Hello {\n  world: String\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 31),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(1, 31),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(6, 11),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{},\n\t\t\t\tFields: []*ast.FieldDefinition{\n\t\t\t\t\tast.NewFieldDefinition(&ast.FieldDefinition{\n\t\t\t\t\t\tLoc: testLoc(16, 29),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\tLoc:   testLoc(16, 21),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tArguments:  []*ast.InputValueDefinition{},\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\tLoc: testLoc(23, 29),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\tLoc:   testLoc(23, 29),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleExtension(t *testing.T) {\n\n\tbody := `\nextend type Hello {\n  world: String\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 38),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewTypeExtensionDefinition(&ast.TypeExtensionDefinition{\n\t\t\t\tLoc: testLoc(1, 38),\n\t\t\t\tDefinition: ast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\t\tLoc: testLoc(8, 38),\n\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\t\tLoc:   testLoc(13, 18),\n\t\t\t\t\t}),\n\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\tInterfaces: []*ast.Named{},\n\t\t\t\t\tFields: []*ast.FieldDefinition{\n\t\t\t\t\t\tast.NewFieldDefinition(&ast.FieldDefinition{\n\t\t\t\t\t\t\tLoc: testLoc(23, 36),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\t\tLoc:   testLoc(23, 28),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\t\tArguments:  []*ast.InputValueDefinition{},\n\t\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\t\tLoc: testLoc(30, 36),\n\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\t\tLoc:   testLoc(30, 36),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleNonNullType(t *testing.T) {\n\n\tbody := `\ntype Hello {\n  world: String!\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 32),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(1, 32),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(6, 11),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{},\n\t\t\t\tFields: []*ast.FieldDefinition{\n\t\t\t\t\tast.NewFieldDefinition(&ast.FieldDefinition{\n\t\t\t\t\t\tLoc: testLoc(16, 30),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\tLoc:   testLoc(16, 21),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tArguments:  []*ast.InputValueDefinition{},\n\t\t\t\t\t\tType: ast.NewNonNull(&ast.NonNull{\n\t\t\t\t\t\t\tKind: \"NonNullType\",\n\t\t\t\t\t\t\tLoc:  testLoc(23, 30),\n\t\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\t\tLoc: testLoc(23, 29),\n\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\t\tLoc:   testLoc(23, 29),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleTypeInheritingInterface(t *testing.T) {\n\tbody := `type Hello implements World { }`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(0, 31),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(0, 31),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(5, 10),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{\n\t\t\t\t\tast.NewNamed(&ast.Named{\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"World\",\n\t\t\t\t\t\t\tLoc:   testLoc(22, 27),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tLoc: testLoc(22, 27),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tFields: []*ast.FieldDefinition{},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleTypeInheritingMultipleInterfaces(t *testing.T) {\n\tbody := `type Hello implements Wo & rld { }`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(0, 34),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(0, 34),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(5, 10),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{\n\t\t\t\t\tast.NewNamed(&ast.Named{\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"Wo\",\n\t\t\t\t\t\t\tLoc:   testLoc(22, 24),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tLoc: testLoc(22, 24),\n\t\t\t\t\t}),\n\t\t\t\t\tast.NewNamed(&ast.Named{\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"rld\",\n\t\t\t\t\t\t\tLoc:   testLoc(27, 30),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tLoc: testLoc(27, 30),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tFields: []*ast.FieldDefinition{},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleTypeInheritingMultipleInterfacesWithLeadingAmpersand(t *testing.T) {\n\tbody := `type Hello implements & Wo & rld { }`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(0, 36),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(0, 36),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(5, 10),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{\n\t\t\t\t\tast.NewNamed(&ast.Named{\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"Wo\",\n\t\t\t\t\t\t\tLoc:   testLoc(24, 26),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tLoc: testLoc(24, 26),\n\t\t\t\t\t}),\n\t\t\t\t\tast.NewNamed(&ast.Named{\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"rld\",\n\t\t\t\t\t\t\tLoc:   testLoc(29, 32),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tLoc: testLoc(29, 32),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tFields: []*ast.FieldDefinition{},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SingleValueEnum(t *testing.T) {\n\tbody := `enum Hello { WORLD }`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(0, 20),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewEnumDefinition(&ast.EnumDefinition{\n\t\t\t\tLoc: testLoc(0, 20),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(5, 10),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tValues: []*ast.EnumValueDefinition{\n\t\t\t\t\tast.NewEnumValueDefinition(&ast.EnumValueDefinition{\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"WORLD\",\n\t\t\t\t\t\t\tLoc:   testLoc(13, 18),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tLoc:        testLoc(13, 18),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_DoubleValueEnum(t *testing.T) {\n\tbody := `enum Hello { WO, RLD }`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(0, 22),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewEnumDefinition(&ast.EnumDefinition{\n\t\t\t\tLoc: testLoc(0, 22),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(5, 10),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tValues: []*ast.EnumValueDefinition{\n\t\t\t\t\tast.NewEnumValueDefinition(&ast.EnumValueDefinition{\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"WO\",\n\t\t\t\t\t\t\tLoc:   testLoc(13, 15),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tLoc:        testLoc(13, 15),\n\t\t\t\t\t}),\n\t\t\t\t\tast.NewEnumValueDefinition(&ast.EnumValueDefinition{\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"RLD\",\n\t\t\t\t\t\t\tLoc:   testLoc(17, 20),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tLoc:        testLoc(17, 20),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleInterface(t *testing.T) {\n\tbody := `\ninterface Hello {\n  world: String\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 36),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewInterfaceDefinition(&ast.InterfaceDefinition{\n\t\t\t\tLoc: testLoc(1, 36),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(11, 16),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tFields: []*ast.FieldDefinition{\n\t\t\t\t\tast.NewFieldDefinition(&ast.FieldDefinition{\n\t\t\t\t\t\tLoc: testLoc(21, 34),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\tLoc:   testLoc(21, 26),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tArguments:  []*ast.InputValueDefinition{},\n\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\tLoc: testLoc(28, 34),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\tLoc:   testLoc(28, 34),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleFieldWithArg(t *testing.T) {\n\tbody := `\ntype Hello {\n  world(flag: Boolean): String\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 46),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(1, 46),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(6, 11),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{},\n\t\t\t\tFields: []*ast.FieldDefinition{\n\t\t\t\t\tast.NewFieldDefinition(&ast.FieldDefinition{\n\t\t\t\t\t\tLoc: testLoc(16, 44),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\tLoc:   testLoc(16, 21),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tArguments: []*ast.InputValueDefinition{\n\t\t\t\t\t\t\tast.NewInputValueDefinition(&ast.InputValueDefinition{\n\t\t\t\t\t\t\t\tLoc: testLoc(22, 35),\n\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\tValue: \"flag\",\n\t\t\t\t\t\t\t\t\tLoc:   testLoc(22, 26),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\t\t\tLoc: testLoc(28, 35),\n\t\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\t\tValue: \"Boolean\",\n\t\t\t\t\t\t\t\t\t\tLoc:   testLoc(28, 35),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tDefaultValue: nil,\n\t\t\t\t\t\t\t\tDirectives:   []*ast.Directive{},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\tLoc: testLoc(38, 44),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\tLoc:   testLoc(38, 44),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleFieldWithArgWithDefaultValue(t *testing.T) {\n\tbody := `\ntype Hello {\n  world(flag: Boolean = true): String\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 53),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(1, 53),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(6, 11),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{},\n\t\t\t\tFields: []*ast.FieldDefinition{\n\t\t\t\t\tast.NewFieldDefinition(&ast.FieldDefinition{\n\t\t\t\t\t\tLoc: testLoc(16, 51),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\tLoc:   testLoc(16, 21),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tArguments: []*ast.InputValueDefinition{\n\t\t\t\t\t\t\tast.NewInputValueDefinition(&ast.InputValueDefinition{\n\t\t\t\t\t\t\t\tLoc: testLoc(22, 42),\n\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\tValue: \"flag\",\n\t\t\t\t\t\t\t\t\tLoc:   testLoc(22, 26),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\t\t\tLoc: testLoc(28, 35),\n\t\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\t\tValue: \"Boolean\",\n\t\t\t\t\t\t\t\t\t\tLoc:   testLoc(28, 35),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tDefaultValue: ast.NewBooleanValue(&ast.BooleanValue{\n\t\t\t\t\t\t\t\t\tValue: true,\n\t\t\t\t\t\t\t\t\tLoc:   testLoc(38, 42),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\tLoc: testLoc(45, 51),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\tLoc:   testLoc(45, 51),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleFieldWithListArg(t *testing.T) {\n\tbody := `\ntype Hello {\n  world(things: [String]): String\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 49),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(1, 49),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(6, 11),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{},\n\t\t\t\tFields: []*ast.FieldDefinition{\n\t\t\t\t\tast.NewFieldDefinition(&ast.FieldDefinition{\n\t\t\t\t\t\tLoc: testLoc(16, 47),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\tLoc:   testLoc(16, 21),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tArguments: []*ast.InputValueDefinition{\n\t\t\t\t\t\t\tast.NewInputValueDefinition(&ast.InputValueDefinition{\n\t\t\t\t\t\t\t\tLoc: testLoc(22, 38),\n\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\tValue: \"things\",\n\t\t\t\t\t\t\t\t\tLoc:   testLoc(22, 28),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tType: ast.NewList(&ast.List{\n\t\t\t\t\t\t\t\t\tLoc: testLoc(30, 38),\n\t\t\t\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\t\t\t\tLoc: testLoc(31, 37),\n\t\t\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\t\t\t\tLoc:   testLoc(31, 37),\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tDefaultValue: nil,\n\t\t\t\t\t\t\t\tDirectives:   []*ast.Directive{},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\tLoc: testLoc(41, 47),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\tLoc:   testLoc(41, 47),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleFieldWithTwoArg(t *testing.T) {\n\tbody := `\ntype Hello {\n  world(argOne: Boolean, argTwo: Int): String\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 61),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewObjectDefinition(&ast.ObjectDefinition{\n\t\t\t\tLoc: testLoc(1, 61),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(6, 11),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tInterfaces: []*ast.Named{},\n\t\t\t\tFields: []*ast.FieldDefinition{\n\t\t\t\t\tast.NewFieldDefinition(&ast.FieldDefinition{\n\t\t\t\t\t\tLoc: testLoc(16, 59),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\tLoc:   testLoc(16, 21),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\t\t\tArguments: []*ast.InputValueDefinition{\n\t\t\t\t\t\t\tast.NewInputValueDefinition(&ast.InputValueDefinition{\n\t\t\t\t\t\t\t\tLoc: testLoc(22, 37),\n\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\tValue: \"argOne\",\n\t\t\t\t\t\t\t\t\tLoc:   testLoc(22, 28),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\t\t\tLoc: testLoc(30, 37),\n\t\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\t\tValue: \"Boolean\",\n\t\t\t\t\t\t\t\t\t\tLoc:   testLoc(30, 37),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tDefaultValue: nil,\n\t\t\t\t\t\t\t\tDirectives:   []*ast.Directive{},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tast.NewInputValueDefinition(&ast.InputValueDefinition{\n\t\t\t\t\t\t\t\tLoc: testLoc(39, 50),\n\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\tValue: \"argTwo\",\n\t\t\t\t\t\t\t\t\tLoc:   testLoc(39, 45),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\t\t\tLoc: testLoc(47, 50),\n\t\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\t\tValue: \"Int\",\n\t\t\t\t\t\t\t\t\t\tLoc:   testLoc(47, 50),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tDefaultValue: nil,\n\t\t\t\t\t\t\t\tDirectives:   []*ast.Directive{},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\tLoc: testLoc(53, 59),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\tLoc:   testLoc(53, 59),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleUnion(t *testing.T) {\n\tbody := `union Hello = World`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(0, 19),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewUnionDefinition(&ast.UnionDefinition{\n\t\t\t\tLoc: testLoc(0, 19),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(6, 11),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tTypes: []*ast.Named{\n\t\t\t\t\tast.NewNamed(&ast.Named{\n\t\t\t\t\t\tLoc: testLoc(14, 19),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"World\",\n\t\t\t\t\t\t\tLoc:   testLoc(14, 19),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_UnionWithTwoTypes(t *testing.T) {\n\tbody := `union Hello = Wo | Rld`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(0, 22),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewUnionDefinition(&ast.UnionDefinition{\n\t\t\t\tLoc: testLoc(0, 22),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(6, 11),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tTypes: []*ast.Named{\n\t\t\t\t\tast.NewNamed(&ast.Named{\n\t\t\t\t\t\tLoc: testLoc(14, 16),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"Wo\",\n\t\t\t\t\t\t\tLoc:   testLoc(14, 16),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t\tast.NewNamed(&ast.Named{\n\t\t\t\t\t\tLoc: testLoc(19, 22),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"Rld\",\n\t\t\t\t\t\t\tLoc:   testLoc(19, 22),\n\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_Scalar(t *testing.T) {\n\tbody := `scalar Hello`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(0, 12),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewScalarDefinition(&ast.ScalarDefinition{\n\t\t\t\tLoc: testLoc(0, 12),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(7, 12),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleInputObject(t *testing.T) {\n\tbody := `\ninput Hello {\n  world: String\n}`\n\tastDoc := parse(t, body)\n\texpected := ast.NewDocument(&ast.Document{\n\t\tLoc: testLoc(1, 32),\n\t\tDefinitions: []ast.Node{\n\t\t\tast.NewInputObjectDefinition(&ast.InputObjectDefinition{\n\t\t\t\tLoc: testLoc(1, 32),\n\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\tValue: \"Hello\",\n\t\t\t\t\tLoc:   testLoc(7, 12),\n\t\t\t\t}),\n\t\t\t\tDirectives: []*ast.Directive{},\n\t\t\t\tFields: []*ast.InputValueDefinition{\n\t\t\t\t\tast.NewInputValueDefinition(&ast.InputValueDefinition{\n\t\t\t\t\t\tLoc: testLoc(17, 30),\n\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\tValue: \"world\",\n\t\t\t\t\t\t\tLoc:   testLoc(17, 22),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tType: ast.NewNamed(&ast.Named{\n\t\t\t\t\t\t\tLoc: testLoc(24, 30),\n\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\tValue: \"String\",\n\t\t\t\t\t\t\t\tLoc:   testLoc(24, 30),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tDefaultValue: nil,\n\t\t\t\t\t\tDirectives:   []*ast.Directive{},\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t})\n\tif !reflect.DeepEqual(astDoc, expected) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expected, astDoc)\n\t}\n}\n\nfunc TestSchemaParser_SimpleInputObjectWithArgsShouldFail(t *testing.T) {\n\tbody := `\ninput Hello {\n  world(foo: Int): String\n}`\n\n\t_, err := Parse(ParseParams{\n\t\tSource: body,\n\t\tOptions: ParseOptions{\n\t\t\tNoLocation: false,\n\t\t\tNoSource:   true,\n\t\t},\n\t})\n\n\texpectedError := &gqlerrors.Error{\n\t\tMessage: `Syntax Error GraphQL (3:8) Expected :, found (\n\n2: input Hello {\n3:   world(foo: Int): String\n          ^\n4: }\n`,\n\t\tStack: `Syntax Error GraphQL (3:8) Expected :, found (\n\n2: input Hello {\n3:   world(foo: Int): String\n          ^\n4: }\n`,\n\t\tNodes: []ast.Node{},\n\t\tSource: &source.Source{\n\t\t\tBody: []byte(`\ninput Hello {\n  world(foo: Int): String\n}`),\n\t\t\tName: \"GraphQL\",\n\t\t},\n\t\tPositions: []int{22},\n\t\tLocations: []location.SourceLocation{\n\t\t\t{Line: 3, Column: 8},\n\t\t},\n\t}\n\tif err == nil {\n\t\tt.Fatalf(\"expected error, expected: %v, got: %v\", expectedError, nil)\n\t}\n\tif !reflect.DeepEqual(expectedError, err) {\n\t\tt.Fatalf(\"unexpected document, expected: %v, got: %v\", expectedError, err)\n\t}\n}\n"
  },
  {
    "path": "language/printer/printer.go",
    "content": "package printer\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"reflect\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/visitor\"\n)\n\nfunc getMapValue(m map[string]interface{}, key string) interface{} {\n\ttokens := strings.Split(key, \".\")\n\tvalMap := m\n\tfor _, token := range tokens {\n\t\tv, ok := valMap[token]\n\t\tif !ok {\n\t\t\treturn nil\n\t\t}\n\t\tswitch v := v.(type) {\n\t\tcase []interface{}:\n\t\t\treturn v\n\t\tcase map[string]interface{}:\n\t\t\tvalMap = v\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn v\n\t\t}\n\t}\n\treturn valMap\n}\nfunc getMapSliceValue(m map[string]interface{}, key string) []interface{} {\n\ttokens := strings.Split(key, \".\")\n\tvalMap := m\n\tfor _, token := range tokens {\n\t\tv, ok := valMap[token]\n\t\tif !ok {\n\t\t\treturn []interface{}{}\n\t\t}\n\t\tswitch v := v.(type) {\n\t\tcase []interface{}:\n\t\t\treturn v\n\t\tdefault:\n\t\t\treturn []interface{}{}\n\t\t}\n\t}\n\treturn []interface{}{}\n}\nfunc getMapValueString(m map[string]interface{}, key string) string {\n\ttokens := strings.Split(key, \".\")\n\tvalMap := m\n\tfor _, token := range tokens {\n\t\tv, ok := valMap[token]\n\t\tif !ok {\n\t\t\treturn \"\"\n\t\t}\n\t\tif v == nil {\n\t\t\treturn \"\"\n\t\t}\n\t\tswitch v := v.(type) {\n\t\tcase map[string]interface{}:\n\t\t\tvalMap = v\n\t\t\tcontinue\n\t\tcase string:\n\t\t\treturn v\n\t\tdefault:\n\t\t\treturn fmt.Sprintf(\"%v\", v)\n\t\t}\n\t}\n\treturn \"\"\n}\nfunc getDescription(raw interface{}) string {\n\tvar desc string\n\n\tswitch node := raw.(type) {\n\tcase ast.DescribableNode:\n\t\tif sval := node.GetDescription(); sval != nil {\n\t\t\tdesc = sval.Value\n\t\t}\n\tcase map[string]interface{}:\n\t\tdesc = getMapValueString(node, \"Description.Value\")\n\t}\n\tif desc != \"\" {\n\t\tsep := \"\"\n\t\tif strings.ContainsRune(desc, '\\n') {\n\t\t\tsep = \"\\n\"\n\t\t}\n\t\tdesc = join([]string{`\"\"\"`, desc, `\"\"\"`}, sep)\n\t}\n\treturn desc\n}\n\nfunc toSliceString(slice interface{}) []string {\n\tif slice == nil {\n\t\treturn []string{}\n\t}\n\tres := []string{}\n\tswitch reflect.TypeOf(slice).Kind() {\n\tcase reflect.Slice:\n\t\ts := reflect.ValueOf(slice)\n\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\telem := s.Index(i)\n\t\t\telemInterface := elem.Interface()\n\t\t\tif elem, ok := elemInterface.(string); ok {\n\t\t\t\tres = append(res, elem)\n\t\t\t}\n\t\t}\n\t\treturn res\n\tdefault:\n\t\treturn res\n\t}\n}\n\nfunc join(str []string, sep string) string {\n\tss := []string{}\n\t// filter out empty strings\n\tfor _, s := range str {\n\t\tif s == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tss = append(ss, s)\n\t}\n\treturn strings.Join(ss, sep)\n}\n\nfunc wrap(start, maybeString, end string) string {\n\tif maybeString == \"\" {\n\t\treturn maybeString\n\t}\n\treturn start + maybeString + end\n}\n\n// Given array, print each item on its own line, wrapped in an indented \"{ }\" block.\nfunc block(maybeArray interface{}) string {\n\ts := toSliceString(maybeArray)\n\tif len(s) == 0 {\n\t\treturn \"{}\"\n\t}\n\treturn indent(\"{\\n\"+join(s, \"\\n\")) + \"\\n}\"\n}\n\nfunc indent(maybeString interface{}) string {\n\tif maybeString == nil {\n\t\treturn \"\"\n\t}\n\tswitch str := maybeString.(type) {\n\tcase string:\n\t\treturn strings.Replace(str, \"\\n\", \"\\n  \", -1)\n\t}\n\treturn \"\"\n}\n\nvar printDocASTReducer = map[string]visitor.VisitFunc{\n\t\"Name\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.Name:\n\t\t\treturn visitor.ActionUpdate, node.Value\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, getMapValue(node, \"Value\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"Variable\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.Variable:\n\t\t\treturn visitor.ActionUpdate, fmt.Sprintf(\"$%v\", node.Name)\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, \"$\" + getMapValueString(node, \"Name\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\n\t// Document\n\t\"Document\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.Document:\n\t\t\tdefinitions := toSliceString(node.Definitions)\n\t\t\treturn visitor.ActionUpdate, join(definitions, \"\\n\\n\") + \"\\n\"\n\t\tcase map[string]interface{}:\n\t\t\tdefinitions := toSliceString(getMapValue(node, \"Definitions\"))\n\t\t\treturn visitor.ActionUpdate, join(definitions, \"\\n\\n\") + \"\\n\"\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"OperationDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.OperationDefinition:\n\t\t\top := string(node.Operation)\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\n\t\t\tvarDefs := wrap(\"(\", join(toSliceString(node.VariableDefinitions), \", \"), \")\")\n\t\t\tdirectives := join(toSliceString(node.Directives), \" \")\n\t\t\tselectionSet := fmt.Sprintf(\"%v\", node.SelectionSet)\n\t\t\t// Anonymous queries with no directives or variable definitions can use\n\t\t\t// the query short form.\n\t\t\tstr := \"\"\n\t\t\tif name == \"\" && directives == \"\" && varDefs == \"\" && op == ast.OperationTypeQuery {\n\t\t\t\tstr = selectionSet\n\t\t\t} else {\n\t\t\t\tstr = join([]string{\n\t\t\t\t\top,\n\t\t\t\t\tjoin([]string{name, varDefs}, \"\"),\n\t\t\t\t\tdirectives,\n\t\t\t\t\tselectionSet,\n\t\t\t\t}, \" \")\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\n\t\t\top := getMapValueString(node, \"Operation\")\n\t\t\tname := getMapValueString(node, \"Name\")\n\n\t\t\tvarDefs := wrap(\"(\", join(toSliceString(getMapValue(node, \"VariableDefinitions\")), \", \"), \")\")\n\t\t\tdirectives := join(toSliceString(getMapValue(node, \"Directives\")), \" \")\n\t\t\tselectionSet := getMapValueString(node, \"SelectionSet\")\n\t\t\tstr := \"\"\n\t\t\tif name == \"\" && directives == \"\" && varDefs == \"\" && op == ast.OperationTypeQuery {\n\t\t\t\tstr = selectionSet\n\t\t\t} else {\n\t\t\t\tstr = join([]string{\n\t\t\t\t\top,\n\t\t\t\t\tjoin([]string{name, varDefs}, \"\"),\n\t\t\t\t\tdirectives,\n\t\t\t\t\tselectionSet,\n\t\t\t\t}, \" \")\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"VariableDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.VariableDefinition:\n\t\t\tvariable := fmt.Sprintf(\"%v\", node.Variable)\n\t\t\tttype := fmt.Sprintf(\"%v\", node.Type)\n\t\t\tdefaultValue := fmt.Sprintf(\"%v\", node.DefaultValue)\n\n\t\t\treturn visitor.ActionUpdate, variable + \": \" + ttype + wrap(\" = \", defaultValue, \"\")\n\t\tcase map[string]interface{}:\n\n\t\t\tvariable := getMapValueString(node, \"Variable\")\n\t\t\tttype := getMapValueString(node, \"Type\")\n\t\t\tdefaultValue := getMapValueString(node, \"DefaultValue\")\n\n\t\t\treturn visitor.ActionUpdate, variable + \": \" + ttype + wrap(\" = \", defaultValue, \"\")\n\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"SelectionSet\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.SelectionSet:\n\t\t\tstr := block(node.Selections)\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tselections := getMapValue(node, \"Selections\")\n\t\t\tstr := block(selections)\n\t\t\treturn visitor.ActionUpdate, str\n\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"Field\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.Argument:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tvalue := fmt.Sprintf(\"%v\", node.Value)\n\t\t\treturn visitor.ActionUpdate, name + \": \" + value\n\t\tcase map[string]interface{}:\n\n\t\t\talias := getMapValueString(node, \"Alias\")\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\targs := toSliceString(getMapValue(node, \"Arguments\"))\n\t\t\tdirectives := toSliceString(getMapValue(node, \"Directives\"))\n\t\t\tselectionSet := getMapValueString(node, \"SelectionSet\")\n\n\t\t\tstr := join(\n\t\t\t\t[]string{\n\t\t\t\t\twrap(\"\", alias, \": \") + name + wrap(\"(\", join(args, \", \"), \")\"),\n\t\t\t\t\tjoin(directives, \" \"),\n\t\t\t\t\tselectionSet,\n\t\t\t\t},\n\t\t\t\t\" \",\n\t\t\t)\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"Argument\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.FragmentSpread:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tdirectives := toSliceString(node.Directives)\n\t\t\treturn visitor.ActionUpdate, \"...\" + name + wrap(\" \", join(directives, \" \"), \"\")\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tvalue := getMapValueString(node, \"Value\")\n\t\t\treturn visitor.ActionUpdate, name + \": \" + value\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\n\t// Fragments\n\t\"FragmentSpread\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.InlineFragment:\n\t\t\ttypeCondition := fmt.Sprintf(\"%v\", node.TypeCondition)\n\t\t\tdirectives := toSliceString(node.Directives)\n\t\t\tselectionSet := fmt.Sprintf(\"%v\", node.SelectionSet)\n\t\t\treturn visitor.ActionUpdate, \"... on \" + typeCondition + \" \" + wrap(\"\", join(directives, \" \"), \" \") + selectionSet\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tdirectives := toSliceString(getMapValue(node, \"Directives\"))\n\t\t\treturn visitor.ActionUpdate, \"...\" + name + wrap(\" \", join(directives, \" \"), \"\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"InlineFragment\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase map[string]interface{}:\n\t\t\ttypeCondition := getMapValueString(node, \"TypeCondition\")\n\t\t\tdirectives := toSliceString(getMapValue(node, \"Directives\"))\n\t\t\tselectionSet := getMapValueString(node, \"SelectionSet\")\n\t\t\treturn visitor.ActionUpdate,\n\t\t\t\tjoin([]string{\n\t\t\t\t\t\"...\",\n\t\t\t\t\twrap(\"on \", typeCondition, \"\"),\n\t\t\t\t\tjoin(directives, \" \"),\n\t\t\t\t\tselectionSet,\n\t\t\t\t}, \" \")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"FragmentDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.FragmentDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\ttypeCondition := fmt.Sprintf(\"%v\", node.TypeCondition)\n\t\t\tdirectives := toSliceString(node.Directives)\n\t\t\tselectionSet := fmt.Sprintf(\"%v\", node.SelectionSet)\n\t\t\treturn visitor.ActionUpdate, \"fragment \" + name + \" on \" + typeCondition + \" \" + wrap(\"\", join(directives, \" \"), \" \") + selectionSet\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\ttypeCondition := getMapValueString(node, \"TypeCondition\")\n\t\t\tdirectives := toSliceString(getMapValue(node, \"Directives\"))\n\t\t\tselectionSet := getMapValueString(node, \"SelectionSet\")\n\t\t\treturn visitor.ActionUpdate, \"fragment \" + name + \" on \" + typeCondition + \" \" + wrap(\"\", join(directives, \" \"), \" \") + selectionSet\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\n\t// Value\n\t\"IntValue\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.IntValue:\n\t\t\treturn visitor.ActionUpdate, fmt.Sprintf(\"%v\", node.Value)\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, getMapValueString(node, \"Value\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"FloatValue\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.FloatValue:\n\t\t\treturn visitor.ActionUpdate, fmt.Sprintf(\"%v\", node.Value)\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, getMapValueString(node, \"Value\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"StringValue\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.StringValue:\n\t\t\treturn visitor.ActionUpdate, strconv.Quote(node.Value)\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, `\"` + getMapValueString(node, \"Value\") + `\"`\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"BooleanValue\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.BooleanValue:\n\t\t\treturn visitor.ActionUpdate, fmt.Sprintf(\"%v\", node.Value)\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, getMapValueString(node, \"Value\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"EnumValue\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.EnumValue:\n\t\t\treturn visitor.ActionUpdate, fmt.Sprintf(\"%v\", node.Value)\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, getMapValueString(node, \"Value\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"ListValue\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.ListValue:\n\t\t\treturn visitor.ActionUpdate, \"[\" + join(toSliceString(node.Values), \", \") + \"]\"\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, \"[\" + join(toSliceString(getMapValue(node, \"Values\")), \", \") + \"]\"\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"ObjectValue\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.ObjectValue:\n\t\t\treturn visitor.ActionUpdate, \"{\" + join(toSliceString(node.Fields), \", \") + \"}\"\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, \"{\" + join(toSliceString(getMapValue(node, \"Fields\")), \", \") + \"}\"\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"ObjectField\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.ObjectField:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tvalue := fmt.Sprintf(\"%v\", node.Value)\n\t\t\treturn visitor.ActionUpdate, name + \": \" + value\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tvalue := getMapValueString(node, \"Value\")\n\t\t\treturn visitor.ActionUpdate, name + \": \" + value\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\n\t// Directive\n\t\"Directive\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.Directive:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\targs := toSliceString(node.Arguments)\n\t\t\treturn visitor.ActionUpdate, \"@\" + name + wrap(\"(\", join(args, \", \"), \")\")\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\targs := toSliceString(getMapValue(node, \"Arguments\"))\n\t\t\treturn visitor.ActionUpdate, \"@\" + name + wrap(\"(\", join(args, \", \"), \")\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\n\t// Type\n\t\"Named\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.Named:\n\t\t\treturn visitor.ActionUpdate, fmt.Sprintf(\"%v\", node.Name)\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, getMapValueString(node, \"Name\")\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"List\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.List:\n\t\t\treturn visitor.ActionUpdate, \"[\" + fmt.Sprintf(\"%v\", node.Type) + \"]\"\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, \"[\" + getMapValueString(node, \"Type\") + \"]\"\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"NonNull\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.NonNull:\n\t\t\treturn visitor.ActionUpdate, fmt.Sprintf(\"%v\", node.Type) + \"!\"\n\t\tcase map[string]interface{}:\n\t\t\treturn visitor.ActionUpdate, getMapValueString(node, \"Type\") + \"!\"\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\n\t// Type System Definitions\n\t\"SchemaDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.SchemaDefinition:\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"schema\",\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(node.OperationTypes),\n\t\t\t}, \" \")\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\toperationTypes := toSliceString(getMapValue(node, \"OperationTypes\"))\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"schema\",\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(operationTypes),\n\t\t\t}, \" \")\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"OperationTypeDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.OperationTypeDefinition:\n\t\t\tstr := fmt.Sprintf(\"%v: %v\", node.Operation, node.Type)\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\toperation := getMapValueString(node, \"Operation\")\n\t\t\tttype := getMapValueString(node, \"Type\")\n\t\t\tstr := fmt.Sprintf(\"%v: %v\", operation, ttype)\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"ScalarDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.ScalarDefinition:\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"scalar\",\n\t\t\t\tfmt.Sprintf(\"%v\", node.Name),\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"scalar\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"ObjectDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.ObjectDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tinterfaces := toSliceString(node.Interfaces)\n\t\t\tfields := node.Fields\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"type\",\n\t\t\t\tname,\n\t\t\t\twrap(\"implements \", join(interfaces, \" & \"), \"\"),\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(fields),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tinterfaces := toSliceString(getMapValue(node, \"Interfaces\"))\n\t\t\tfields := getMapValue(node, \"Fields\")\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"type\",\n\t\t\t\tname,\n\t\t\t\twrap(\"implements \", join(interfaces, \" & \"), \"\"),\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(fields),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"FieldDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.FieldDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tttype := fmt.Sprintf(\"%v\", node.Type)\n\t\t\targs := toSliceString(node.Arguments)\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\thasArgDesc := false\n\t\t\tfor _, arg := range node.Arguments {\n\t\t\t\tif arg.Description != nil && arg.Description.Value != \"\" {\n\t\t\t\t\thasArgDesc = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar argsStr string\n\t\t\tif hasArgDesc {\n\t\t\t\targsStr = wrap(\"(\", indent(\"\\n\"+join(args, \"\\n\")), \"\\n)\")\n\t\t\t} else {\n\t\t\t\targsStr = wrap(\"(\", join(args, \", \"), \")\")\n\t\t\t}\n\t\t\tstr := name + argsStr + \": \" + ttype + wrap(\" \", join(directives, \" \"), \"\")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"\\n%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tttype := getMapValueString(node, \"Type\")\n\t\t\targs := toSliceString(getMapValue(node, \"Arguments\"))\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\thasArgDesc := false\n\t\t\tfor _, arg := range args {\n\t\t\t\tif strings.HasPrefix(strings.TrimSpace(arg), `\"\"\"`) {\n\t\t\t\t\thasArgDesc = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar argsStr string\n\t\t\tif hasArgDesc {\n\t\t\t\targsStr = wrap(\"(\", indent(\"\\n\"+join(args, \"\\n\")), \"\\n)\")\n\t\t\t} else {\n\t\t\t\targsStr = wrap(\"(\", join(args, \", \"), \")\")\n\t\t\t}\n\t\t\tstr := name + argsStr + \": \" + ttype + wrap(\" \", join(directives, \" \"), \"\")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"\\n%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"InputValueDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.InputValueDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tttype := fmt.Sprintf(\"%v\", node.Type)\n\t\t\tdefaultValue := fmt.Sprintf(\"%v\", node.DefaultValue)\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\tname + \": \" + ttype,\n\t\t\t\twrap(\"= \", defaultValue, \"\"),\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"\\n%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tttype := getMapValueString(node, \"Type\")\n\t\t\tdefaultValue := getMapValueString(node, \"DefaultValue\")\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\tname + \": \" + ttype,\n\t\t\t\twrap(\"= \", defaultValue, \"\"),\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"\\n%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"InterfaceDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.InterfaceDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tfields := node.Fields\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"interface\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(fields),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tfields := getMapValue(node, \"Fields\")\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"interface\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(fields),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"UnionDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.UnionDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\ttypes := toSliceString(node.Types)\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"union\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\t\"= \" + join(types, \" | \"),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\ttypes := toSliceString(getMapValue(node, \"Types\"))\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"union\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\t\"= \" + join(types, \" | \"),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"EnumDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.EnumDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tvalues := node.Values\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"enum\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(values),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tvalues := getMapValue(node, \"Values\")\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"enum\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(values),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"EnumValueDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.EnumValueDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"\\n%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"\\n%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"InputObjectDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.InputObjectDefinition:\n\t\t\tname := fmt.Sprintf(\"%v\", node.Name)\n\t\t\tfields := node.Fields\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range node.Directives {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive.Name))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"input\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(fields),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tfields := getMapValue(node, \"Fields\")\n\t\t\tdirectives := []string{}\n\t\t\tfor _, directive := range getMapSliceValue(node, \"Directives\") {\n\t\t\t\tdirectives = append(directives, fmt.Sprintf(\"%v\", directive))\n\t\t\t}\n\t\t\tstr := join([]string{\n\t\t\t\t\"input\",\n\t\t\t\tname,\n\t\t\t\tjoin(directives, \" \"),\n\t\t\t\tblock(fields),\n\t\t\t}, \" \")\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"TypeExtensionDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.TypeExtensionDefinition:\n\t\t\tdefinition := fmt.Sprintf(\"%v\", node.Definition)\n\t\t\tstr := \"extend \" + definition\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tdefinition := getMapValueString(node, \"Definition\")\n\t\t\tstr := \"extend \" + definition\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n\t\"DirectiveDefinition\": func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\tswitch node := p.Node.(type) {\n\t\tcase *ast.DirectiveDefinition:\n\t\t\targs := toSliceString(node.Arguments)\n\t\t\thasArgDesc := false\n\t\t\tfor _, arg := range node.Arguments {\n\t\t\t\tif arg.Description != nil && arg.Description.Value != \"\" {\n\t\t\t\t\thasArgDesc = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar argsStr string\n\t\t\tif hasArgDesc {\n\t\t\t\targsStr = wrap(\"(\", indent(\"\\n\"+join(args, \"\\n\")), \"\\n)\")\n\t\t\t} else {\n\t\t\t\targsStr = wrap(\"(\", join(args, \", \"), \")\")\n\t\t\t}\n\t\t\tstr := fmt.Sprintf(\"directive @%v%v on %v\", node.Name, argsStr, join(toSliceString(node.Locations), \" | \"))\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\tcase map[string]interface{}:\n\t\t\tname := getMapValueString(node, \"Name\")\n\t\t\tlocations := toSliceString(getMapValue(node, \"Locations\"))\n\t\t\targs := toSliceString(getMapValue(node, \"Arguments\"))\n\t\t\thasArgDesc := false\n\t\t\tfor _, arg := range args {\n\t\t\t\tif strings.HasPrefix(strings.TrimSpace(arg), `\"\"\"`) {\n\t\t\t\t\thasArgDesc = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar argsStr string\n\t\t\tif hasArgDesc {\n\t\t\t\targsStr = wrap(\"(\", indent(\"\\n\"+join(args, \"\\n\")), \"\\n)\")\n\t\t\t} else {\n\t\t\t\targsStr = wrap(\"(\", join(args, \", \"), \")\")\n\t\t\t}\n\t\t\tstr := fmt.Sprintf(\"directive @%v%v on %v\", name, argsStr, join(locations, \" | \"))\n\t\t\tif desc := getDescription(node); desc != \"\" {\n\t\t\t\tstr = fmt.Sprintf(\"%s\\n%s\", desc, str)\n\t\t\t}\n\t\t\treturn visitor.ActionUpdate, str\n\t\t}\n\t\treturn visitor.ActionNoChange, nil\n\t},\n}\n\nfunc Print(astNode ast.Node) (printed interface{}) {\n\tdefer func() interface{} {\n\t\tif r := recover(); r != nil {\n\t\t\treturn fmt.Sprintf(\"%v\", astNode)\n\t\t}\n\t\treturn printed\n\t}()\n\tprinted = visitor.Visit(astNode, &visitor.VisitorOptions{\n\t\tLeaveKindMap: printDocASTReducer,\n\t}, nil)\n\treturn printed\n}\n"
  },
  {
    "path": "language/printer/printer_test.go",
    "content": "package printer_test\n\nimport (\n\t\"io/ioutil\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/parser\"\n\t\"github.com/graphql-go/graphql/language/printer\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc parse(t *testing.T, query string) *ast.Document {\n\tastDoc, err := parser.Parse(parser.ParseParams{\n\t\tSource: query,\n\t\tOptions: parser.ParseOptions{\n\t\t\tNoLocation: true,\n\t\t},\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Parse failed: %v\", err)\n\t}\n\treturn astDoc\n}\n\nfunc TestPrinter_DoesNotAlterAST(t *testing.T) {\n\tb, err := ioutil.ReadFile(\"../../kitchen-sink.graphql\")\n\tif err != nil {\n\t\tt.Fatalf(\"unable to load kitchen-sink.graphql\")\n\t}\n\n\tquery := string(b)\n\tastDoc := parse(t, query)\n\n\tastDocBefore := testutil.ASTToJSON(t, astDoc)\n\n\t_ = printer.Print(astDoc)\n\n\tastDocAfter := testutil.ASTToJSON(t, astDoc)\n\n\t_ = testutil.ASTToJSON(t, astDoc)\n\n\tif !reflect.DeepEqual(astDocAfter, astDocBefore) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(astDocBefore, astDocAfter))\n\t}\n}\n\nfunc TestPrinter_PrintsMinimalAST(t *testing.T) {\n\tastDoc := ast.NewField(&ast.Field{\n\t\tName: ast.NewName(&ast.Name{\n\t\t\tValue: \"foo\",\n\t\t}),\n\t})\n\tresults := printer.Print(astDoc)\n\texpected := \"foo\"\n\tif !reflect.DeepEqual(results, expected) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n}\n\n// TestPrinter_ProducesHelpfulErrorMessages\n// Skipped, can't figure out how to pass in an invalid astDoc, which is already strongly-typed\n\nfunc TestPrinter_CorrectlyPrintsNonQueryOperationsWithoutName(t *testing.T) {\n\n\t// Test #1\n\tqueryAstShorthanded := `query { id, name }`\n\texpected := `{\n  id\n  name\n}\n`\n\tastDoc := parse(t, queryAstShorthanded)\n\tresults := printer.Print(astDoc)\n\n\tif !reflect.DeepEqual(expected, results) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n\n\t// Test #2\n\tmutationAst := `mutation { id, name }`\n\texpected = `mutation {\n  id\n  name\n}\n`\n\tastDoc = parse(t, mutationAst)\n\tresults = printer.Print(astDoc)\n\n\tif !reflect.DeepEqual(expected, results) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n\n\t// Test #3\n\tqueryAstWithArtifacts := `query ($foo: TestType) @testDirective { id, name }`\n\texpected = `query ($foo: TestType) @testDirective {\n  id\n  name\n}\n`\n\tastDoc = parse(t, queryAstWithArtifacts)\n\tresults = printer.Print(astDoc)\n\n\tif !reflect.DeepEqual(expected, results) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n\n\t// Test #4\n\tmutationAstWithArtifacts := `mutation ($foo: TestType) @testDirective { id, name }`\n\texpected = `mutation ($foo: TestType) @testDirective {\n  id\n  name\n}\n`\n\tastDoc = parse(t, mutationAstWithArtifacts)\n\tresults = printer.Print(astDoc)\n\n\tif !reflect.DeepEqual(expected, results) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n}\n\nfunc TestPrinter_PrintsKitchenSink(t *testing.T) {\n\tb, err := ioutil.ReadFile(\"../../kitchen-sink.graphql\")\n\tif err != nil {\n\t\tt.Fatalf(\"unable to load kitchen-sink.graphql\")\n\t}\n\n\tquery := string(b)\n\tastDoc := parse(t, query)\n\texpected := `query namedQuery($foo: ComplexFooType, $bar: Bar = DefaultBarValue) {\n  customUser: user(id: [987, 654]) {\n    id\n    ... on User @defer {\n      field2 {\n        id\n        alias: field1(first: 10, after: $foo) @include(if: $foo) {\n          id\n          ...frag\n        }\n      }\n    }\n    ... @skip(unless: $foo) {\n      id\n    }\n    ... {\n      id\n    }\n  }\n}\n\nmutation favPost {\n  fav(post: 123) @defer {\n    post {\n      id\n    }\n  }\n}\n\nsubscription PostFavSubscription($input: StoryLikeSubscribeInput) {\n  postFavSubscribe(input: $input) {\n    post {\n      favers {\n        count\n      }\n      favSentence {\n        text\n      }\n    }\n  }\n}\n\nfragment frag on Follower {\n  foo(size: $size, bar: $b, obj: {key: \"value\"})\n}\n\n{\n  unnamed(truthyVal: true, falseyVal: false)\n  query\n}\n`\n\tresults := printer.Print(astDoc)\n\n\tif !reflect.DeepEqual(expected, results) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n}\n\nfunc TestPrinter_CorrectlyPrintsStringArgumentsWithProperQuoting(t *testing.T) {\n\tqueryAst := `query { foo(jsonStr: \"{\\\"foo\\\": \\\"bar\\\"}\") }`\n\texpected := `{\n  foo(jsonStr: \"{\\\"foo\\\": \\\"bar\\\"}\")\n}\n`\n\tastDoc := parse(t, queryAst)\n\tresults := printer.Print(astDoc)\n\n\tif !reflect.DeepEqual(expected, results) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n}\n\nfunc BenchmarkPrint(b *testing.B) {\n\tq, err := ioutil.ReadFile(\"../../kitchen-sink.graphql\")\n\tif err != nil {\n\t\tb.Fatalf(\"unable to load kitchen-sink.graphql\")\n\t}\n\n\tquery := string(q)\n\n\tastDoc, err := parser.Parse(parser.ParseParams{\n\t\tSource: query,\n\t\tOptions: parser.ParseOptions{\n\t\t\tNoLocation: true,\n\t\t},\n\t})\n\tif err != nil {\n\t\tb.Fatalf(\"Parse failed: %v\", err)\n\t}\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = printer.Print(astDoc)\n\t}\n}\n"
  },
  {
    "path": "language/printer/schema_printer_test.go",
    "content": "package printer_test\n\nimport (\n\t\"io/ioutil\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/printer\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestSchemaPrinter_PrintsMinimalAST(t *testing.T) {\n\tastDoc := ast.NewScalarDefinition(&ast.ScalarDefinition{\n\t\tName: ast.NewName(&ast.Name{\n\t\t\tValue: \"foo\",\n\t\t}),\n\t})\n\tresults := printer.Print(astDoc)\n\texpected := \"scalar foo\"\n\tif !reflect.DeepEqual(results, expected) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n}\n\nfunc TestSchemaPrinter_DoesNotAlterAST(t *testing.T) {\n\tb, err := ioutil.ReadFile(\"../../schema-kitchen-sink.graphql\")\n\tif err != nil {\n\t\tt.Fatalf(\"unable to load schema-kitchen-sink.graphql\")\n\t}\n\n\tquery := string(b)\n\tastDoc := parse(t, query)\n\n\tastDocBefore := testutil.ASTToJSON(t, astDoc)\n\n\t_ = printer.Print(astDoc)\n\n\tastDocAfter := testutil.ASTToJSON(t, astDoc)\n\n\t_ = testutil.ASTToJSON(t, astDoc)\n\n\tif !reflect.DeepEqual(astDocAfter, astDocBefore) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(astDocAfter, astDocBefore))\n\t}\n}\n\nfunc TestSchemaPrinter_PrintsKitchenSink(t *testing.T) {\n\tb, err := ioutil.ReadFile(\"../../schema-kitchen-sink.graphql\")\n\tif err != nil {\n\t\tt.Fatalf(\"unable to load schema-kitchen-sink.graphql\")\n\t}\n\n\tquery := string(b)\n\tastDoc := parse(t, query)\n\texpected := `schema {\n  query: QueryType\n  mutation: MutationType\n}\n\ntype Foo implements Bar & Baz {\n  one: Type\n  two(argument: InputType!): Type\n  three(argument: InputType, other: String): Int\n  four(argument: String = \"string\"): String\n  five(argument: [String] = [\"string\", \"string\"]): String\n  six(argument: InputType = {key: \"value\"}): Type\n}\n\ntype AnnotatedObject @onObject(arg: \"value\") {\n  annotatedField(arg: Type = \"default\" @onArg): Type @onField\n}\n\ninterface Bar {\n  one: Type\n  four(argument: String = \"string\"): String\n}\n\ninterface AnnotatedInterface @onInterface {\n  annotatedField(arg: Type @onArg): Type @onField\n}\n\nunion Feed = Story | Article | Advert\n\nunion AnnotatedUnion @onUnion = A | B\n\nscalar CustomScalar\n\nscalar AnnotatedScalar @onScalar\n\nenum Site {\n  DESKTOP\n  MOBILE\n}\n\nenum AnnotatedEnum @onEnum {\n  ANNOTATED_VALUE @onEnumValue\n  OTHER_VALUE\n}\n\ninput InputType {\n  key: String!\n  answer: Int = 42\n}\n\ninput AnnotatedInput @onInputObjectType {\n  annotatedField: Type @onField\n}\n\nextend type Foo {\n  seven(argument: [String]): Type\n}\n\nextend type Foo @onType {}\n\ntype NoFields {}\n\ndirective @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\ndirective @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n`\n\tresults := printer.Print(astDoc)\n\tif !reflect.DeepEqual(expected, results) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n}\n\nfunc TestSchemaPrinter_PrintsAllDescriptions(t *testing.T) {\n\tb, err := ioutil.ReadFile(\"../../schema-all-descriptions.graphql\")\n\tif err != nil {\n\t\tt.Fatalf(\"unable to load schema-all-descriptions.graphql\")\n\t}\n\n\tquery := string(b)\n\tastDoc := parse(t, query)\n\texpected := `\"\"\"single line scalar description\"\"\"\nscalar ScalarSingleLine\n\n\"\"\"\nmulti line\n\nscalar description\n\"\"\"\nscalar ScalarMultiLine\n\n\"\"\"single line object description\"\"\"\ntype ObjectSingleLine {\n  no_description: ID\n  \n  \"\"\"single line field description\"\"\"\n  single_line(a: ID, b: ID, c: ID, d: ID): ID\n  \n  \"\"\"\n  multi line\n  \n  field description\n  \"\"\"\n  multi_line(\n    a: ID\n    \n    \"\"\"single line argument description\"\"\"\n    b: ID\n    \n    \"\"\"\n    multi line\n    \n    field description\n    \"\"\"\n    c: ID\n    d: ID\n  ): ID\n}\n\n\"\"\"\nmulti line\n\nobject description\n\"\"\"\ntype ObjectMultiLine {\n  foo: ID\n}\n\n\"\"\"single line interface description\"\"\"\ninterface InterfaceSingleLine {\n  no_description: ID\n  \n  \"\"\"single line field description\"\"\"\n  single_line(a: ID, b: ID, c: ID, d: ID): ID\n  \n  \"\"\"\n  multi line\n  \n  field description\n  \"\"\"\n  multi_line(\n    a: ID\n    \n    \"\"\"single line argument description\"\"\"\n    b: ID\n    \n    \"\"\"\n    multi line\n    \n    argument description\n    \"\"\"\n    c: ID\n    d: ID\n  ): ID\n}\n\n\"\"\"\nmulti line\n\ninterface description\n\"\"\"\ninterface InterfaceMultiLine {\n  foo: ID\n}\n\n\"\"\"single line union description\"\"\"\nunion UnionSingleLine = String | Int | Float | ID\n\n\"\"\"\nmulti line\n\nunion description\n\"\"\"\nunion UnionSingleLine = String | Int | Float | ID\n\n\"\"\"single line enum description\"\"\"\nenum EnumSingleLine {\n  no_description\n  \n  \"\"\"single line enum description\"\"\"\n  single_line\n  \n  \"\"\"\n  multi line\n  \n  enum description\n  \"\"\"\n  multi_line\n  again_no_description\n}\n\n\"\"\"\nmulti line\n\nenum description\n\"\"\"\nenum EnumMultiLine {\n  foo\n}\n\n\"\"\"single line input description\"\"\"\ninput InputSingleLine {\n  a: ID\n  \n  \"\"\"single line argument description\"\"\"\n  b: ID\n  \n  \"\"\"\n  multi line\n  \n  argument description\n  \"\"\"\n  c: ID\n  d: ID\n}\n\n\"\"\"\nmulti line\n\ninput description\n\"\"\"\ninput InputMultiLine {\n  foo: ID\n}\n\n\"\"\"single line directive description\"\"\"\ndirective @DirectiveSingleLine(\n  a: ID\n  \n  \"\"\"single line argument description\"\"\"\n  b: ID\n  \n  \"\"\"\n  multi line\n  \n  argument description\n  \"\"\"\n  c: ID\n  d: ID\n) on SCALAR\n\n\"\"\"\nmulti line\n\ndirective description\n\"\"\"\ndirective @DirectiveMultiLine on SCALAR\n`\n\tresults := printer.Print(astDoc)\n\tif !reflect.DeepEqual(expected, results) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, results))\n\t}\n}\n"
  },
  {
    "path": "language/source/source.go",
    "content": "package source\n\nconst (\n\tname = \"GraphQL\"\n)\n\ntype Source struct {\n\tBody []byte\n\tName string\n}\n\nfunc NewSource(s *Source) *Source {\n\tif s == nil {\n\t\ts = &Source{Name: name}\n\t}\n\tif s.Name == \"\" {\n\t\ts.Name = name\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "language/typeInfo/type_info.go",
    "content": "package typeInfo\n\nimport (\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\n// TypeInfoI defines the interface for TypeInfo Implementation\ntype TypeInfoI interface {\n\tEnter(node ast.Node)\n\tLeave(node ast.Node)\n}\n"
  },
  {
    "path": "language/visitor/visitor.go",
    "content": "package visitor\n\nimport (\n\t\"fmt\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/typeInfo\"\n\t\"reflect\"\n)\n\nconst (\n\tActionNoChange = \"\"\n\tActionBreak    = \"BREAK\"\n\tActionSkip     = \"SKIP\"\n\tActionUpdate   = \"UPDATE\"\n)\n\ntype KeyMap map[string][]string\n\n// note that the keys are in Capital letters, equivalent to the ast.Node field Names\nvar QueryDocumentKeys = KeyMap{\n\t\"Name\":     []string{},\n\t\"Document\": []string{\"Definitions\"},\n\t\"OperationDefinition\": []string{\n\t\t\"Name\",\n\t\t\"VariableDefinitions\",\n\t\t\"Directives\",\n\t\t\"SelectionSet\",\n\t},\n\t\"VariableDefinition\": []string{\n\t\t\"Variable\",\n\t\t\"Type\",\n\t\t\"DefaultValue\",\n\t},\n\t\"Variable\":     []string{\"Name\"},\n\t\"SelectionSet\": []string{\"Selections\"},\n\t\"Field\": []string{\n\t\t\"Alias\",\n\t\t\"Name\",\n\t\t\"Arguments\",\n\t\t\"Directives\",\n\t\t\"SelectionSet\",\n\t},\n\t\"Argument\": []string{\n\t\t\"Name\",\n\t\t\"Value\",\n\t},\n\n\t\"FragmentSpread\": []string{\n\t\t\"Name\",\n\t\t\"Directives\",\n\t},\n\t\"InlineFragment\": []string{\n\t\t\"TypeCondition\",\n\t\t\"Directives\",\n\t\t\"SelectionSet\",\n\t},\n\t\"FragmentDefinition\": []string{\n\t\t\"Name\",\n\t\t\"TypeCondition\",\n\t\t\"Directives\",\n\t\t\"SelectionSet\",\n\t},\n\n\t\"IntValue\":     []string{},\n\t\"FloatValue\":   []string{},\n\t\"StringValue\":  []string{},\n\t\"BooleanValue\": []string{},\n\t\"EnumValue\":    []string{},\n\t\"ListValue\":    []string{\"Values\"},\n\t\"ObjectValue\":  []string{\"Fields\"},\n\t\"ObjectField\": []string{\n\t\t\"Name\",\n\t\t\"Value\",\n\t},\n\n\t\"Directive\": []string{\n\t\t\"Name\",\n\t\t\"Arguments\",\n\t},\n\n\t\"Named\":   []string{\"Name\"},\n\t\"List\":    []string{\"Type\"},\n\t\"NonNull\": []string{\"Type\"},\n\n\t\"SchemaDefinition\": []string{\n\t\t\"Directives\",\n\t\t\"OperationTypes\",\n\t},\n\t\"OperationTypeDefinition\": []string{\"Type\"},\n\n\t\"ScalarDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Directives\",\n\t},\n\t\"ObjectDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Interfaces\",\n\t\t\"Directives\",\n\t\t\"Fields\",\n\t},\n\t\"FieldDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Arguments\",\n\t\t\"Type\",\n\t\t\"Directives\",\n\t},\n\t\"InputValueDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Type\",\n\t\t\"DefaultValue\",\n\t\t\"Directives\",\n\t},\n\t\"InterfaceDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Directives\",\n\t\t\"Fields\",\n\t},\n\t\"UnionDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Directives\",\n\t\t\"Types\",\n\t},\n\t\"EnumDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Directives\",\n\t\t\"Values\",\n\t},\n\t\"EnumValueDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Directives\",\n\t},\n\t\"InputObjectDefinition\": []string{\n\t\t\"Name\",\n\t\t\"Directives\",\n\t\t\"Fields\",\n\t},\n\n\t\"TypeExtensionDefinition\": []string{\"Definition\"},\n\n\t\"DirectiveDefinition\": []string{\"Name\", \"Arguments\", \"Locations\"},\n}\n\ntype stack struct {\n\tIndex   int\n\tKeys    []interface{}\n\tEdits   []*edit\n\tinSlice bool\n\tPrev    *stack\n}\ntype edit struct {\n\tKey   interface{}\n\tValue interface{}\n}\n\ntype VisitFuncParams struct {\n\tNode      interface{}\n\tKey       interface{}\n\tParent    ast.Node\n\tPath      []interface{}\n\tAncestors []ast.Node\n}\n\ntype VisitFunc func(p VisitFuncParams) (string, interface{})\n\ntype NamedVisitFuncs struct {\n\tKind  VisitFunc // 1) Named visitors triggered when entering a node a specific kind.\n\tLeave VisitFunc // 2) Named visitors that trigger upon entering and leaving a node of\n\tEnter VisitFunc // 2) Named visitors that trigger upon entering and leaving a node of\n}\n\ntype VisitorOptions struct {\n\tKindFuncMap map[string]NamedVisitFuncs\n\tEnter       VisitFunc // 3) Generic visitors that trigger upon entering and leaving any node.\n\tLeave       VisitFunc // 3) Generic visitors that trigger upon entering and leaving any node.\n\n\tEnterKindMap map[string]VisitFunc // 4) Parallel visitors for entering and leaving nodes of a specific kind\n\tLeaveKindMap map[string]VisitFunc // 4) Parallel visitors for entering and leaving nodes of a specific kind\n}\n\nfunc Visit(root ast.Node, visitorOpts *VisitorOptions, keyMap KeyMap) interface{} {\n\tvisitorKeys := keyMap\n\tif visitorKeys == nil {\n\t\tvisitorKeys = QueryDocumentKeys\n\t}\n\n\tvar (\n\t\tresult         interface{}\n\t\tnewRoot        ast.Node = root\n\t\tsstack         *stack\n\t\tparent         interface{}\n\t\tparentSlice    []interface{}\n\t\tinSlice        = false\n\t\tprevInSlice    = false\n\t\tkeys           = []interface{}{root}\n\t\tindex          = -1\n\t\tedits          = []*edit{} // key-value\n\t\tpath           = []interface{}{}\n\t\tancestors      = []interface{}{}\n\t\tancestorsSlice = [][]interface{}{}\n\t)\n\t// these algorithm must be simple!!!\n\t// abstract algorithm\nLoop:\n\tfor {\n\t\tindex++\n\n\t\tisLeaving := (len(keys) == index)\n\t\tvar (\n\t\t\tkey       interface{} // string for structs or int for slices\n\t\t\tnode      interface{} // ast.Node or can be anything\n\t\t\tnodeSlice []interface{}\n\t\t)\n\t\tisEdited := (isLeaving && len(edits) != 0)\n\n\t\tif isLeaving {\n\t\t\tkey, path = pop(path)\n\n\t\t\tnode = parent\n\t\t\tparent, ancestors = pop(ancestors)\n\t\t\tnodeSlice = parentSlice\n\t\t\tparentSlice, ancestorsSlice = popNodeSlice(ancestorsSlice)\n\n\t\t\tif isEdited {\n\t\t\t\tprevInSlice = inSlice\n\t\t\t\teditOffset := 0\n\t\t\t\tfor _, edit := range edits {\n\t\t\t\t\tif inSlice {\n\t\t\t\t\t\tif isNilNode(edit.Value) {\n\t\t\t\t\t\t\tnodeSlice = removeNodeByIndex(nodeSlice, edit.Key.(int)-editOffset)\n\t\t\t\t\t\t\teditOffset++\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnodeSlice[edit.Key.(int)-editOffset] = edit.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar isConvertMap bool\n\t\t\t\t\t\t// check if edit.Value implements ast.Node or []ast.Node.\n\t\t\t\t\t\tif !isSlice(edit.Value) {\n\t\t\t\t\t\t\tif !isStructNode(edit.Value) {\n\t\t\t\t\t\t\t\tisConvertMap = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// check if edit.value slice is ast.nodes\n\t\t\t\t\t\t\tev := reflect.ValueOf(edit.Value)\n\t\t\t\t\t\t\tfor i := 0; i < ev.Len(); i++ {\n\t\t\t\t\t\t\t\tif !isStructNode(ev.Index(i).Interface()) {\n\t\t\t\t\t\t\t\t\tisConvertMap = true\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif !isConvertMap {\n\t\t\t\t\t\t\tnode = updateNodeField(node, edit.Key.(string), edit.Value)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// non-node needs convert to map\n\t\t\t\t\t\t\tif todoNode, err := convertMap(node); err != nil {\n\t\t\t\t\t\t\t\tpanic(err)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttodoNode[edit.Key.(string)] = edit.Value\n\t\t\t\t\t\t\t\tnode = todoNode\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tindex, keys, edits, inSlice, sstack = sstack.Index, sstack.Keys, sstack.Edits, sstack.inSlice, sstack.Prev\n\t\t} else {\n\t\t\t// get key & value\n\t\t\tif inSlice {\n\t\t\t\tkey = index\n\t\t\t} else if !isNilNode(parent) {\n\t\t\t\tkey = getFieldValue(keys, index)\n\t\t\t}\n\t\t\t// get node\n\t\t\tvar tmp interface{}\n\t\t\tif !isNilNode(parent) {\n\t\t\t\ttmp = parent\n\t\t\t} else if len(parentSlice) != 0 {\n\t\t\t\ttmp = parentSlice\n\t\t\t} else {\n\t\t\t\tnode, nodeSlice = newRoot, []interface{}{}\n\t\t\t}\n\t\t\tif tmp != nil {\n\t\t\t\tfieldValue := getFieldValue(tmp, key)\n\t\t\t\tswitch {\n\t\t\t\tcase isNode(fieldValue):\n\t\t\t\t\tnode = fieldValue.(ast.Node)\n\t\t\t\tcase isSlice(fieldValue):\n\t\t\t\t\tnodeSlice = toSliceInterfaces(fieldValue)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif isNilNode(node) && len(nodeSlice) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !inSlice {\n\t\t\t\tif !isNilNode(parent) {\n\t\t\t\t\tpath = append(path, key)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif len(parentSlice) != 0 {\n\t\t\t\t\tpath = append(path, key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// get result from visitFn for a node if set\n\t\tvar result interface{}\n\t\tresultIsUndefined := true\n\t\tif !isNilNode(node) {\n\t\t\t// Note that since user can potentially return a non-ast.Node from visit functions.\n\t\t\t// if not exist map type for node, nodes implement ast.Node\n\t\t\tparentConcrete, _ := parent.(ast.Node)\n\t\t\tancestorsConcrete := []ast.Node{}\n\t\t\tfor _, ancestor := range ancestors {\n\t\t\t\tif ancestorConcrete, ok := ancestor.(ast.Node); ok {\n\t\t\t\t\tancestorsConcrete = append(ancestorsConcrete, ancestorConcrete)\n\t\t\t\t} else {\n\t\t\t\t\tancestorsConcrete = append(ancestorsConcrete, nil) // map for nil\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar kind string\n\t\t\tswitch tmp := node.(type) {\n\t\t\tcase map[string]interface{}:\n\t\t\t\tkind = tmp[\"Kind\"].(string)\n\t\t\tcase ast.Node:\n\t\t\t\tkind = tmp.GetKind()\n\t\t\t}\n\n\t\t\tvisitFn := GetVisitFn(visitorOpts, kind, isLeaving)\n\t\t\tif visitFn != nil {\n\t\t\t\tp := VisitFuncParams{\n\t\t\t\t\tNode:      node,\n\t\t\t\t\tKey:       key,\n\t\t\t\t\tParent:    parentConcrete,\n\t\t\t\t\tPath:      path,\n\t\t\t\t\tAncestors: ancestorsConcrete,\n\t\t\t\t}\n\t\t\t\tvar action string\n\t\t\t\tswitch action, result = visitFn(p); action {\n\t\t\t\tcase ActionBreak:\n\t\t\t\t\tbreak Loop\n\t\t\t\tcase ActionSkip:\n\t\t\t\t\tif !isLeaving {\n\t\t\t\t\t\t_, path = pop(path)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\tcase ActionUpdate:\n\t\t\t\t\tresultIsUndefined = false\n\t\t\t\t\tedits = append(edits, &edit{\n\t\t\t\t\t\tKey:   key,\n\t\t\t\t\t\tValue: result,\n\t\t\t\t\t})\n\t\t\t\t\tif !isLeaving {\n\t\t\t\t\t\tif isNode(result) {\n\t\t\t\t\t\t\tnode = result\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t_, path = pop(path)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// collect back edits on the way out\n\t\tif resultIsUndefined && isEdited {\n\t\t\tif !prevInSlice {\n\t\t\t\tedits = append(edits, &edit{\n\t\t\t\t\tKey:   key,\n\t\t\t\t\tValue: node,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tedits = append(edits, &edit{\n\t\t\t\t\tKey:   key,\n\t\t\t\t\tValue: nodeSlice,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tif !isLeaving {\n\t\t\t// add to stack\n\t\t\tprevStack := sstack\n\t\t\tsstack = &stack{\n\t\t\t\tinSlice: inSlice,\n\t\t\t\tIndex:   index,\n\t\t\t\tKeys:    keys,\n\t\t\t\tEdits:   edits,\n\t\t\t\tPrev:    prevStack,\n\t\t\t}\n\n\t\t\t// replace keys\n\t\t\tkeys, index, edits = []interface{}{}, -1, []*edit{}\n\t\t\tif len(nodeSlice) > 0 {\n\t\t\t\tinSlice = true\n\t\t\t\tkeys = append(keys, nodeSlice...)\n\t\t\t} else {\n\t\t\t\tinSlice = false\n\t\t\t\tif !isNilNode(node) {\n\t\t\t\t\tkind := node.(ast.Node).GetKind()\n\t\t\t\t\tfor _, m := range visitorKeys[kind] {\n\t\t\t\t\t\tkeys = append(keys, m)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tancestors = append(ancestors, parent)\n\t\t\tparent = node\n\t\t\tancestorsSlice = append(ancestorsSlice, parentSlice)\n\t\t\tparentSlice = nodeSlice\n\t\t}\n\n\t\t// loop guard\n\t\tif sstack == nil {\n\t\t\tbreak Loop\n\t\t}\n\t}\n\tif len(edits) != 0 {\n\t\tresult = edits[len(edits)-1].Value\n\t}\n\treturn result\n}\n\nfunc pop(a []interface{}) (interface{}, []interface{}) {\n\tif len(a) == 0 {\n\t\treturn nil, nil\n\t}\n\treturn a[len(a)-1], a[:len(a)-1]\n}\n\nfunc popNodeSlice(a [][]interface{}) ([]interface{}, [][]interface{}) {\n\tif len(a) == 0 {\n\t\treturn nil, nil\n\t}\n\treturn a[len(a)-1], a[:len(a)-1]\n}\n\nfunc removeNodeByIndex(a []interface{}, pos int) []interface{} {\n\tif pos < 0 || pos >= len(a) {\n\t\treturn a\n\t}\n\treturn append(a[:pos], a[pos+1:]...)\n}\n\nfunc convertMap(src interface{}) (dest map[string]interface{}, err error) {\n\tif src == nil {\n\t\treturn\n\t}\n\n\t// return if src is already a map\n\tdest, ok := src.(map[string]interface{})\n\tif ok {\n\t\treturn\n\t}\n\n\toutputMap := make(map[string]interface{})\n\tval := reflect.ValueOf(src)\n\n\t// Dereference pointer if necessary\n\tif val.Kind() == reflect.Ptr {\n\t\tif val.IsNil() {\n\t\t\treturn nil, fmt.Errorf(\"input is a nil pointer\")\n\t\t}\n\t\tval = val.Elem()\n\t}\n\n\tif val.Kind() != reflect.Struct {\n\t\treturn nil, fmt.Errorf(\"input is not a struct or pointer to struct\")\n\t}\n\n\ttyp := val.Type()\n\tfor i := 0; i < val.NumField(); i++ {\n\t\tfield := val.Field(i)\n\t\tfieldName := typ.Field(i).Name\n\n\t\tswitch field.Kind() {\n\t\tcase reflect.Ptr:\n\t\t\tif field.IsNil() {\n\t\t\t\toutputMap[fieldName] = nil\n\t\t\t} else {\n\t\t\t\tnestedMap, err := convertMap(field.Interface())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\toutputMap[fieldName] = nestedMap\n\t\t\t}\n\t\tcase reflect.Struct:\n\t\t\tnestedMap, err := convertMap(field.Interface())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\toutputMap[fieldName] = nestedMap\n\t\tcase reflect.Interface:\n\t\t\tif field.IsNil() {\n\t\t\t\toutputMap[fieldName] = nil\n\t\t\t} else {\n\t\t\t\tconcreteValue := field.Elem()\n\t\t\t\toutputMap[fieldName], _ = convertMap(concreteValue.Interface())\n\t\t\t}\n\t\tdefault:\n\t\t\toutputMap[fieldName] = field.Interface()\n\t\t}\n\t}\n\n\treturn outputMap, nil\n}\n\n// get value by key from struct | slice | map | wrap(prev)\n// when obj type is struct, the key's type must be string\n// ... slice, ... int\n// ... map, ... any type. But the type satisfies map's key definition(feature: compare...)\nfunc getFieldValue(obj interface{}, key interface{}) interface{} {\n\tvar value reflect.Value\n\tval := reflect.ValueOf(obj)\n\tif val.Kind() == reflect.Ptr {\n\t\tval = val.Elem()\n\t}\n\tswitch val.Kind() {\n\tcase reflect.Struct:\n\t\tvalue = val.FieldByName(key.(string))\n\tcase reflect.Map:\n\t\tvalue = val.MapIndex(reflect.ValueOf(key))\n\tcase reflect.Slice:\n\t\tif index, ok := key.(int); !ok {\n\t\t\treturn nil\n\t\t} else if index >= 0 || val.Len() > index {\n\t\t\tvalue = val.Index(index)\n\t\t}\n\t}\n\tif !value.IsValid() {\n\t\treturn nil\n\t}\n\treturn value.Interface()\n}\n\n// currently only supports update struct field value\nfunc updateNodeField(src interface{}, targetName string, target interface{}) interface{} {\n\tvar isPtr bool\n\tsrcVal := reflect.ValueOf(src)\n\t// verify condition\n\tif srcVal.Kind() == reflect.Ptr {\n\t\tisPtr = true\n\t\tsrcVal = srcVal.Elem()\n\t}\n\ttargetVal := reflect.ValueOf(target)\n\tif srcVal.Kind() != reflect.Struct {\n\t\treturn src\n\t}\n\tsrcFieldValue := srcVal.FieldByName(targetName)\n\tif !srcFieldValue.IsValid() || srcFieldValue.Kind() != targetVal.Kind() {\n\t\treturn src\n\t}\n\n\tif srcFieldValue.CanSet() {\n\t\tif srcFieldValue.Kind() == reflect.Slice {\n\t\t\titems := reflect.MakeSlice(srcFieldValue.Type(), targetVal.Len(), targetVal.Len())\n\t\t\tfor index := 0; index < items.Len(); index++ {\n\t\t\t\ttmp := targetVal.Index(index).Interface()\n\t\t\t\titems.Index(index).Set(reflect.ValueOf(tmp))\n\t\t\t}\n\t\t\tsrcFieldValue.Set(items)\n\t\t} else {\n\t\t\tsrcFieldValue.Set(targetVal)\n\t\t}\n\t}\n\tif isPtr {\n\t\treturn srcVal.Addr().Interface()\n\t}\n\treturn srcVal.Interface()\n}\n\nfunc toSliceInterfaces(src interface{}) []interface{} {\n\tvar list []interface{}\n\tvalue := reflect.ValueOf(src)\n\tif value.Kind() == reflect.Ptr {\n\t\tvalue = value.Elem()\n\t}\n\tif value.Kind() != reflect.Slice {\n\t\treturn nil\n\t}\n\tfor index := 0; index < value.Len(); index++ {\n\t\tlist = append(list, value.Index(index).Interface())\n\t}\n\treturn list\n}\n\nfunc isSlice(value interface{}) bool {\n\tif value == nil {\n\t\treturn false\n\t}\n\ttyp := reflect.TypeOf(value)\n\tif typ.Kind() == reflect.Slice {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isStructNode(node interface{}) bool {\n\tif node == nil {\n\t\treturn false\n\t}\n\tvalue := reflect.ValueOf(node)\n\tif value.Kind() == reflect.Ptr {\n\t\tvalue = value.Elem()\n\t}\n\tif value.Kind() == reflect.Struct {\n\t\t_, ok := node.(ast.Node)\n\t\treturn ok\n\t}\n\treturn false\n}\n\n// notice: type: Named, List or NonNull maybe map type\n// and it can't be asserted to ast.Node\nfunc isNode(node interface{}) bool {\n\tif node == nil {\n\t\treturn false\n\t}\n\tval := reflect.ValueOf(node)\n\tif !val.IsValid() {\n\t\treturn false\n\t}\n\tswitch val.Kind() {\n\tcase reflect.Map:\n\t\treturn true\n\tcase reflect.Ptr:\n\t\tval = val.Elem()\n\t}\n\t_, ok := node.(ast.Node)\n\treturn ok\n}\n\nfunc isNilNode(node interface{}) bool {\n\tif node == nil {\n\t\treturn true\n\t}\n\tval := reflect.ValueOf(node)\n\tif !val.IsValid() {\n\t\treturn true\n\t}\n\tswitch val.Kind() {\n\tcase reflect.Ptr, reflect.Map, reflect.Slice:\n\t\treturn val.IsNil()\n\tcase reflect.Bool:\n\t\treturn node.(bool)\n\t}\n\treturn false\n}\n\n// VisitInParallel Creates a new visitor instance which delegates to many visitors to run in\n// parallel. Each visitor will be visited for each node before moving on.\n//\n// If a prior visitor edits a node, no following visitors will see that node.\nfunc VisitInParallel(visitorOptsSlice ...*VisitorOptions) *VisitorOptions {\n\tskipping := map[int]interface{}{}\n\n\treturn &VisitorOptions{\n\t\tEnter: func(p VisitFuncParams) (string, interface{}) {\n\t\t\tfor i, visitorOpts := range visitorOptsSlice {\n\t\t\t\tif _, ok := skipping[i]; !ok {\n\t\t\t\t\tnode, ok := p.Node.(ast.Node)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tkind := node.GetKind()\n\t\t\t\t\tfn := GetVisitFn(visitorOpts, kind, false)\n\t\t\t\t\tif fn != nil {\n\t\t\t\t\t\taction, result := fn(p)\n\t\t\t\t\t\tif action == ActionSkip {\n\t\t\t\t\t\t\tskipping[i] = node\n\t\t\t\t\t\t} else if action == ActionBreak {\n\t\t\t\t\t\t\tskipping[i] = ActionBreak\n\t\t\t\t\t\t} else if action == ActionUpdate {\n\t\t\t\t\t\t\treturn ActionUpdate, result\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p VisitFuncParams) (string, interface{}) {\n\t\t\tfor i, visitorOpts := range visitorOptsSlice {\n\t\t\t\tskippedNode, ok := skipping[i]\n\t\t\t\tif !ok {\n\t\t\t\t\tif node, ok := p.Node.(ast.Node); ok {\n\t\t\t\t\t\tkind := node.GetKind()\n\t\t\t\t\t\tfn := GetVisitFn(visitorOpts, kind, true)\n\t\t\t\t\t\tif fn != nil {\n\t\t\t\t\t\t\taction, result := fn(p)\n\t\t\t\t\t\t\tif action == ActionBreak {\n\t\t\t\t\t\t\t\tskipping[i] = ActionBreak\n\t\t\t\t\t\t\t} else if action == ActionUpdate {\n\t\t\t\t\t\t\t\treturn ActionUpdate, result\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if skippedNode == p.Node {\n\t\t\t\t\tdelete(skipping, i)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ActionNoChange, nil\n\t\t},\n\t}\n}\n\n// VisitWithTypeInfo Creates a new visitor instance which maintains a provided TypeInfo instance\n// along with visiting visitor.\nfunc VisitWithTypeInfo(ttypeInfo typeInfo.TypeInfoI, visitorOpts *VisitorOptions) *VisitorOptions {\n\treturn &VisitorOptions{\n\t\tEnter: func(p VisitFuncParams) (string, interface{}) {\n\t\t\tif node, ok := p.Node.(ast.Node); ok {\n\t\t\t\tttypeInfo.Enter(node)\n\t\t\t\tfn := GetVisitFn(visitorOpts, node.GetKind(), false)\n\t\t\t\tif fn != nil {\n\t\t\t\t\taction, result := fn(p)\n\t\t\t\t\tif action == ActionUpdate {\n\t\t\t\t\t\tttypeInfo.Leave(node)\n\t\t\t\t\t\tif isNode(result) {\n\t\t\t\t\t\t\tif result, ok := result.(ast.Node); ok {\n\t\t\t\t\t\t\t\tttypeInfo.Enter(result)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn action, result\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p VisitFuncParams) (string, interface{}) {\n\t\t\taction := ActionNoChange\n\t\t\tvar result interface{}\n\t\t\tif node, ok := p.Node.(ast.Node); ok {\n\t\t\t\tfn := GetVisitFn(visitorOpts, node.GetKind(), true)\n\t\t\t\tif fn != nil {\n\t\t\t\t\taction, result = fn(p)\n\t\t\t\t}\n\t\t\t\tttypeInfo.Leave(node)\n\t\t\t}\n\t\t\treturn action, result\n\t\t},\n\t}\n}\n\n// GetVisitFn Given a visitor instance, if it is leaving or not, and a node kind, return\n// the function the visitor runtime should call.\n// priority [high->low] in VisitorOptions:\n// KindFuncMap{Kind> {Leave, Enter}} > {Leave, Enter} > {EnterKindMap, LeaveKindMap}\nfunc GetVisitFn(visitorOpts *VisitorOptions, kind string, isLeaving bool) VisitFunc {\n\tif visitorOpts == nil {\n\t\treturn nil\n\t}\n\tif kindVisitor, ok := visitorOpts.KindFuncMap[kind]; ok {\n\t\tif !isLeaving && kindVisitor.Kind != nil {\n\t\t\t// { Kind() {} }\n\t\t\treturn kindVisitor.Kind\n\t\t} else if isLeaving {\n\t\t\t// { Kind: { leave() {} } }\n\t\t\treturn kindVisitor.Leave\n\t\t} else {\n\t\t\t// { Kind: { enter() {} } }\n\t\t\treturn kindVisitor.Enter\n\t\t}\n\t}\n\tif isLeaving {\n\t\t// { leave() {} }\n\t\tif genericVisitor := visitorOpts.Leave; genericVisitor != nil {\n\t\t\treturn genericVisitor\n\t\t}\n\t\tif specificKindVisitor, ok := visitorOpts.LeaveKindMap[kind]; ok {\n\t\t\t// { leave: { Kind() {} } }\n\t\t\treturn specificKindVisitor\n\t\t}\n\n\t} else {\n\t\t// { enter() {} }\n\t\tif genericVisitor := visitorOpts.Enter; genericVisitor != nil {\n\t\t\treturn genericVisitor\n\t\t}\n\t\tif specificKindVisitor, ok := visitorOpts.EnterKindMap[kind]; ok {\n\t\t\t// { enter: { Kind() {} } }\n\t\t\treturn specificKindVisitor\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "language/visitor/visitor_test.go",
    "content": "package visitor_test\n\nimport (\n\t\"io/ioutil\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"fmt\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/kinds\"\n\t\"github.com/graphql-go/graphql/language/parser\"\n\t\"github.com/graphql-go/graphql/language/printer\"\n\t\"github.com/graphql-go/graphql/language/visitor\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc parse(t *testing.T, query string) *ast.Document {\n\tastDoc, err := parser.Parse(parser.ParseParams{\n\t\tSource: query,\n\t\tOptions: parser.ParseOptions{\n\t\t\tNoLocation: true,\n\t\t},\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Parse failed: %v\", err)\n\t}\n\treturn astDoc\n}\n\nfunc TestVisitor_AllowsEditingANodeBothOnEnterAndOnLeave(t *testing.T) {\n\n\tquery := `{ a, b, c { a, b, c } }`\n\tastDoc := parse(t, query)\n\n\tvar selectionSet *ast.SelectionSet\n\n\texpectedQuery := `{ a, b, c { a, b, c } }`\n\texpectedAST := parse(t, expectedQuery)\n\n\tvisited := map[string]bool{\n\t\t\"didEnter\": false,\n\t\t\"didLeave\": false,\n\t}\n\n\texpectedVisited := map[string]bool{\n\t\t\"didEnter\": true,\n\t\t\"didLeave\": true,\n\t}\n\n\tv := &visitor.VisitorOptions{\n\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.OperationDefinition); ok {\n\t\t\t\t\t\tselectionSet = node.SelectionSet\n\t\t\t\t\t\tvisited[\"didEnter\"] = true\n\t\t\t\t\t\treturn visitor.ActionUpdate, ast.NewOperationDefinition(&ast.OperationDefinition{\n\t\t\t\t\t\t\tLoc:                 node.Loc,\n\t\t\t\t\t\t\tOperation:           node.Operation,\n\t\t\t\t\t\t\tName:                node.Name,\n\t\t\t\t\t\t\tVariableDefinitions: node.VariableDefinitions,\n\t\t\t\t\t\t\tDirectives:          node.Directives,\n\t\t\t\t\t\t\tSelectionSet: ast.NewSelectionSet(&ast.SelectionSet{\n\t\t\t\t\t\t\t\tSelections: []ast.Selection{},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.OperationDefinition); ok {\n\t\t\t\t\t\tvisited[\"didLeave\"] = true\n\t\t\t\t\t\treturn visitor.ActionUpdate, ast.NewOperationDefinition(&ast.OperationDefinition{\n\t\t\t\t\t\t\tLoc:                 node.Loc,\n\t\t\t\t\t\t\tOperation:           node.Operation,\n\t\t\t\t\t\t\tName:                node.Name,\n\t\t\t\t\t\t\tVariableDefinitions: node.VariableDefinitions,\n\t\t\t\t\t\t\tDirectives:          node.Directives,\n\t\t\t\t\t\t\tSelectionSet:        selectionSet,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\teditedAst := visitor.Visit(astDoc, v, nil)\n\tif !reflect.DeepEqual(expectedAST, editedAst) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedAST, editedAst))\n\t}\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n\n}\nfunc TestVisitor_AllowsEditingTheRootNodeOnEnterAndOnLeave(t *testing.T) {\n\n\tquery := `{ a, b, c { a, b, c } }`\n\tastDoc := parse(t, query)\n\n\tdefinitions := astDoc.Definitions\n\n\texpectedQuery := `{ a, b, c { a, b, c } }`\n\texpectedAST := parse(t, expectedQuery)\n\n\tvisited := map[string]bool{\n\t\t\"didEnter\": false,\n\t\t\"didLeave\": false,\n\t}\n\n\texpectedVisited := map[string]bool{\n\t\t\"didEnter\": true,\n\t\t\"didLeave\": true,\n\t}\n\n\tv := &visitor.VisitorOptions{\n\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Document: {\n\t\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.Document); ok {\n\t\t\t\t\t\tvisited[\"didEnter\"] = true\n\t\t\t\t\t\treturn visitor.ActionUpdate, ast.NewDocument(&ast.Document{\n\t\t\t\t\t\t\tLoc:         node.Loc,\n\t\t\t\t\t\t\tDefinitions: []ast.Node{},\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.Document); ok {\n\t\t\t\t\t\tvisited[\"didLeave\"] = true\n\t\t\t\t\t\treturn visitor.ActionUpdate, ast.NewDocument(&ast.Document{\n\t\t\t\t\t\t\tLoc:         node.Loc,\n\t\t\t\t\t\t\tDefinitions: definitions,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\teditedAst := visitor.Visit(astDoc, v, nil)\n\tif !reflect.DeepEqual(expectedAST, editedAst) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedAST, editedAst))\n\t}\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\nfunc TestVisitor_AllowsForEditingOnEnter(t *testing.T) {\n\n\tquery := `{ a, b, c { a, b, c } }`\n\tastDoc := parse(t, query)\n\n\texpectedQuery := `{ a,    c { a,    c } }`\n\texpectedAST := parse(t, expectedQuery)\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Field:\n\t\t\t\tif node.Name != nil && node.Name.Value == \"b\" {\n\t\t\t\t\treturn visitor.ActionUpdate, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\teditedAst := visitor.Visit(astDoc, v, nil)\n\tif !reflect.DeepEqual(expectedAST, editedAst) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedAST, editedAst))\n\t}\n\n}\nfunc TestVisitor_AllowsForEditingOnLeave(t *testing.T) {\n\n\tquery := `{ a, b, c { a, b, c } }`\n\tastDoc := parse(t, query)\n\n\texpectedQuery := `{ a,    c { a,    c } }`\n\texpectedAST := parse(t, expectedQuery)\n\tv := &visitor.VisitorOptions{\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Field:\n\t\t\t\tif node.Name != nil && node.Name.Value == \"b\" {\n\t\t\t\t\treturn visitor.ActionUpdate, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\teditedAst := visitor.Visit(astDoc, v, nil)\n\tif !reflect.DeepEqual(expectedAST, editedAst) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedAST, editedAst))\n\t}\n}\n\nfunc TestVisitor_VisitsEditedNode(t *testing.T) {\n\n\tquery := `{ a { x } }`\n\tastDoc := parse(t, query)\n\n\taddedField := &ast.Field{\n\t\tKind: \"Field\",\n\t\tName: &ast.Name{\n\t\t\tKind:  \"Name\",\n\t\t\tValue: \"__typename\",\n\t\t},\n\t}\n\n\tdidVisitAddedField := false\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Field:\n\t\t\t\tif node.Name != nil && node.Name.Value == \"a\" {\n\t\t\t\t\ts := node.SelectionSet.Selections\n\t\t\t\t\ts = append(s, addedField)\n\t\t\t\t\tss := node.SelectionSet\n\t\t\t\t\tss.Selections = s\n\t\t\t\t\treturn visitor.ActionUpdate, ast.NewField(&ast.Field{\n\t\t\t\t\t\tKind:         \"Field\",\n\t\t\t\t\t\tSelectionSet: ss,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif reflect.DeepEqual(node, addedField) {\n\t\t\t\t\tdidVisitAddedField = true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, v, nil)\n\tif didVisitAddedField == false {\n\t\tt.Fatalf(\"Unexpected result, expected didVisitAddedField == true\")\n\t}\n}\nfunc TestVisitor_AllowsSkippingASubTree(t *testing.T) {\n\n\tquery := `{ a, b { x }, c }`\n\tastDoc := parse(t, query)\n\n\tvisited := []interface{}{}\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"leave\", \"Document\", nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\tcase *ast.Field:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, nil})\n\t\t\t\tif node.Name != nil && node.Name.Value == \"b\" {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, v, nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_AllowsEarlyExitWhileVisiting(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\tquery := `{ a, b { x }, c }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"b\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"x\"},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\t\tif node.Value == \"x\" {\n\t\t\t\t\treturn visitor.ActionBreak, nil\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, v, nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_AllowsEarlyExitWhileLeaving(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\tquery := `{ a, b { x }, c }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"b\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"x\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"x\"},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value})\n\t\t\t\tif node.Value == \"x\" {\n\t\t\t\t\treturn visitor.ActionBreak, nil\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, v, nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_AllowsANamedFunctionsVisitorAPI(t *testing.T) {\n\n\tquery := `{ a, b { x }, c }`\n\tastDoc := parse(t, query)\n\n\tvisited := []interface{}{}\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"x\"},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\t\"Name\": {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tswitch node := p.Node.(type) {\n\t\t\t\t\tcase *ast.Name:\n\t\t\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"SelectionSet\": {\n\t\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tswitch node := p.Node.(type) {\n\t\t\t\t\tcase *ast.SelectionSet:\n\t\t\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, nil})\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tswitch node := p.Node.(type) {\n\t\t\t\t\tcase *ast.SelectionSet:\n\t\t\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, nil})\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, v, nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\nfunc TestVisitor_VisitsKitchenSink(t *testing.T) {\n\tb, err := ioutil.ReadFile(\"../../kitchen-sink.graphql\")\n\tif err != nil {\n\t\tt.Fatalf(\"unable to load kitchen-sink.graphql\")\n\t}\n\n\tquery := string(b)\n\tastDoc := parse(t, query)\n\n\tvisited := []interface{}{}\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil, nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"OperationDefinition\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"OperationDefinition\"},\n\t\t[]interface{}{\"enter\", \"VariableDefinition\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Variable\", \"Variable\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Variable\", \"Variable\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Named\", \"Type\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Named\", \"Type\", \"VariableDefinition\"},\n\t\t[]interface{}{\"leave\", \"VariableDefinition\", 0, nil},\n\t\t[]interface{}{\"enter\", \"VariableDefinition\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Variable\", \"Variable\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Variable\", \"Variable\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Named\", \"Type\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Named\", \"Type\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"EnumValue\", \"DefaultValue\", \"VariableDefinition\"},\n\t\t[]interface{}{\"leave\", \"EnumValue\", \"DefaultValue\", \"VariableDefinition\"},\n\t\t[]interface{}{\"leave\", \"VariableDefinition\", 1, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"OperationDefinition\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Alias\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Alias\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"ListValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"IntValue\", 0, nil},\n\t\t[]interface{}{\"leave\", \"IntValue\", 0, nil},\n\t\t[]interface{}{\"enter\", \"IntValue\", 1, nil},\n\t\t[]interface{}{\"leave\", \"IntValue\", 1, nil},\n\t\t[]interface{}{\"leave\", \"ListValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"InlineFragment\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Named\", \"TypeCondition\", \"InlineFragment\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Named\", \"TypeCondition\", \"InlineFragment\"},\n\t\t[]interface{}{\"enter\", \"Directive\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Directive\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Directive\"},\n\t\t[]interface{}{\"leave\", \"Directive\", 0, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"InlineFragment\"},\n\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Field\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Alias\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Alias\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"IntValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"IntValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Argument\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Directive\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Directive\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Directive\"},\n\t\t[]interface{}{\"enter\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"leave\", \"Directive\", 0, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"FragmentSpread\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"FragmentSpread\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"FragmentSpread\"},\n\t\t[]interface{}{\"leave\", \"FragmentSpread\", 1, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 1, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"InlineFragment\"},\n\t\t[]interface{}{\"leave\", \"InlineFragment\", 1, nil},\n\t\t[]interface{}{\"enter\", \"InlineFragment\", 2, nil},\n\t\t[]interface{}{\"enter\", \"Directive\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Directive\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Directive\"},\n\t\t[]interface{}{\"enter\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\n\t\t[]interface{}{\"leave\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"leave\", \"Directive\", 0, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"InlineFragment\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"InlineFragment\"},\n\t\t[]interface{}{\"leave\", \"InlineFragment\", 2, nil},\n\t\t[]interface{}{\"enter\", \"InlineFragment\", 3, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"InlineFragment\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"InlineFragment\"},\n\t\t[]interface{}{\"leave\", \"InlineFragment\", 3, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"OperationDefinition\"},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", 0, nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"OperationDefinition\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"OperationDefinition\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"OperationDefinition\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"IntValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"IntValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Directive\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Directive\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Directive\"},\n\t\t[]interface{}{\"leave\", \"Directive\", 0, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"OperationDefinition\"},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", 1, nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", 2, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"OperationDefinition\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"OperationDefinition\"},\n\t\t[]interface{}{\"enter\", \"VariableDefinition\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Variable\", \"Variable\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\n\t\t[]interface{}{\"leave\", \"Variable\", \"Variable\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Named\", \"Type\", \"VariableDefinition\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Named\", \"Type\", \"VariableDefinition\"},\n\t\t[]interface{}{\"leave\", \"VariableDefinition\", 0, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"OperationDefinition\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Field\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 1, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"OperationDefinition\"},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", 2, nil},\n\t\t[]interface{}{\"enter\", \"FragmentDefinition\", 3, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"FragmentDefinition\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"FragmentDefinition\"},\n\t\t[]interface{}{\"enter\", \"Named\", \"TypeCondition\", \"FragmentDefinition\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Named\"},\n\t\t[]interface{}{\"leave\", \"Named\", \"TypeCondition\", \"FragmentDefinition\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"FragmentDefinition\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\n\t\t[]interface{}{\"enter\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Argument\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Variable\"},\n\t\t[]interface{}{\"leave\", \"Variable\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Argument\", 2, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"ObjectValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"ObjectField\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"ObjectField\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"ObjectField\"},\n\t\t[]interface{}{\"enter\", \"StringValue\", \"Value\", \"ObjectField\"},\n\t\t[]interface{}{\"leave\", \"StringValue\", \"Value\", \"ObjectField\"},\n\t\t[]interface{}{\"leave\", \"ObjectField\", 0, nil},\n\t\t[]interface{}{\"leave\", \"ObjectValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 2, nil},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"FragmentDefinition\"},\n\t\t[]interface{}{\"leave\", \"FragmentDefinition\", 3, nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", 4, nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", \"SelectionSet\", \"OperationDefinition\"},\n\t\t[]interface{}{\"enter\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"enter\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"BooleanValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"BooleanValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Argument\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Argument\"},\n\t\t[]interface{}{\"enter\", \"BooleanValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"BooleanValue\", \"Value\", \"Argument\"},\n\t\t[]interface{}{\"leave\", \"Argument\", 1, nil},\n\t\t[]interface{}{\"leave\", \"Field\", 0, nil},\n\t\t[]interface{}{\"enter\", \"Field\", 1, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"Name\", \"Field\"},\n\t\t[]interface{}{\"leave\", \"Field\", 1, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", \"SelectionSet\", \"OperationDefinition\"},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", 4, nil},\n\t\t[]interface{}{\"leave\", \"Document\", nil, nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase ast.Node:\n\t\t\t\tif p.Parent != nil {\n\t\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), p.Key, p.Parent.GetKind()})\n\t\t\t\t} else {\n\t\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), p.Key, nil})\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase ast.Node:\n\t\t\t\tif p.Parent != nil {\n\t\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), p.Key, p.Parent.GetKind()})\n\t\t\t\t} else {\n\t\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), p.Key, nil})\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, v, nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_VisitInParallel_AllowsSkippingASubTree(t *testing.T) {\n\n\t// Note: nearly identical to the above test of the same test but\n\t// using visitInParallel.\n\n\tquery := `{ a, b { x }, c }`\n\tastDoc := parse(t, query)\n\n\tvisited := []interface{}{}\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"leave\", \"Document\", nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\tcase *ast.Field:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, nil})\n\t\t\t\tif node.Name != nil && node.Name.Value == \"b\" {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, visitor.VisitInParallel(v), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_VisitInParallel_AllowsSkippingDifferentSubTrees(t *testing.T) {\n\n\tquery := `{ a { x }, b { y} }`\n\tastDoc := parse(t, query)\n\n\tvisited := []interface{}{}\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"no-a\", \"enter\", \"Document\", nil},\n\t\t[]interface{}{\"no-b\", \"enter\", \"Document\", nil},\n\t\t[]interface{}{\"no-a\", \"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"no-b\", \"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"no-a\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"no-b\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"no-a\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"no-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"no-b\", \"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"no-b\", \"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"no-b\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"no-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"no-b\", \"enter\", \"Name\", \"x\"},\n\t\t[]interface{}{\"no-b\", \"leave\", \"Name\", \"x\"},\n\t\t[]interface{}{\"no-b\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"no-b\", \"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"no-b\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"no-a\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"no-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"no-a\", \"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"no-a\", \"leave\", \"Name\", \"b\"},\n\t\t[]interface{}{\"no-a\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"no-a\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"no-a\", \"enter\", \"Name\", \"y\"},\n\t\t[]interface{}{\"no-a\", \"leave\", \"Name\", \"y\"},\n\t\t[]interface{}{\"no-a\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"no-a\", \"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"no-a\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"no-a\", \"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"no-b\", \"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"no-a\", \"leave\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"no-b\", \"leave\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"no-a\", \"leave\", \"Document\", nil},\n\t\t[]interface{}{\"no-b\", \"leave\", \"Document\", nil},\n\t}\n\n\tv := []*visitor.VisitorOptions{\n\t\t{\n\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\tswitch node := p.Node.(type) {\n\t\t\t\tcase *ast.Name:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-a\", \"enter\", node.Kind, node.Value})\n\t\t\t\tcase *ast.Field:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-a\", \"enter\", node.Kind, nil})\n\t\t\t\t\tif node.Name != nil && node.Name.Value == \"a\" {\n\t\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t\t}\n\t\t\t\tcase ast.Node:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-a\", \"enter\", node.GetKind(), nil})\n\t\t\t\tdefault:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-a\", \"enter\", nil, nil})\n\t\t\t\t}\n\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t},\n\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\tswitch node := p.Node.(type) {\n\t\t\t\tcase *ast.Name:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-a\", \"leave\", node.Kind, node.Value})\n\t\t\t\tcase ast.Node:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-a\", \"leave\", node.GetKind(), nil})\n\t\t\t\tdefault:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-a\", \"leave\", nil, nil})\n\t\t\t\t}\n\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\tswitch node := p.Node.(type) {\n\t\t\t\tcase *ast.Name:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-b\", \"enter\", node.Kind, node.Value})\n\t\t\t\tcase *ast.Field:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-b\", \"enter\", node.Kind, nil})\n\t\t\t\t\tif node.Name != nil && node.Name.Value == \"b\" {\n\t\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t\t}\n\t\t\t\tcase ast.Node:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-b\", \"enter\", node.GetKind(), nil})\n\t\t\t\tdefault:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-b\", \"enter\", nil, nil})\n\t\t\t\t}\n\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t},\n\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\tswitch node := p.Node.(type) {\n\t\t\t\tcase *ast.Name:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-b\", \"leave\", node.Kind, node.Value})\n\t\t\t\tcase ast.Node:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-b\", \"leave\", node.GetKind(), nil})\n\t\t\t\tdefault:\n\t\t\t\t\tvisited = append(visited, []interface{}{\"no-b\", \"leave\", nil, nil})\n\t\t\t\t}\n\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t},\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, visitor.VisitInParallel(v...), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_VisitInParallel_AllowsEarlyExitWhileVisiting(t *testing.T) {\n\n\t// Note: nearly identical to the above test of the same test but\n\t// using visitInParallel.\n\n\tvisited := []interface{}{}\n\n\tquery := `{ a, b { x }, c }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"b\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"x\"},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\t\tif node.Value == \"x\" {\n\t\t\t\t\treturn visitor.ActionBreak, nil\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, visitor.VisitInParallel(v), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_VisitInParallel_AllowsEarlyExitFromDifferentPoints(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\tquery := `{ a { y }, b { x } }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"break-a\", \"enter\", \"Document\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Document\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"break-b\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Name\", \"y\"},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Name\", \"y\"},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Name\", \"b\"},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"enter\", node.Kind, node.Value})\n\t\t\t\tif node != nil && node.Value == \"a\" {\n\t\t\t\t\treturn visitor.ActionBreak, nil\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\tv2 := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"enter\", node.Kind, node.Value})\n\t\t\t\tif node != nil && node.Value == \"b\" {\n\t\t\t\t\treturn visitor.ActionBreak, nil\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, visitor.VisitInParallel(v, v2), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_VisitInParallel_AllowsEarlyExitWhileLeaving(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\tquery := `{ a, b { x }, c }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"b\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"x\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"x\"},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value})\n\t\t\t\tif node.Value == \"x\" {\n\t\t\t\t\treturn visitor.ActionBreak, nil\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, visitor.VisitInParallel(v), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_VisitInParallel_AllowsEarlyExitFromLeavingDifferentPoints(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\tquery := `{ a { y }, b { x } }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"break-a\", \"enter\", \"Document\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Document\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"break-a\", \"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"break-a\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-a\", \"enter\", \"Name\", \"y\"},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Name\", \"y\"},\n\t\t[]interface{}{\"break-a\", \"leave\", \"Name\", \"y\"},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Name\", \"y\"},\n\t\t[]interface{}{\"break-a\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"break-a\", \"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-b\", \"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-a\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Name\", \"b\"},\n\t\t[]interface{}{\"break-b\", \"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"enter\", \"Name\", \"x\"},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Name\", \"x\"},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Field\", nil},\n\t\t[]interface{}{\"break-b\", \"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"break-b\", \"leave\", \"Field\", nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"enter\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Field:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"leave\", node.GetKind(), nil})\n\t\t\t\tif node.Name != nil && node.Name.Value == \"a\" {\n\t\t\t\t\treturn visitor.ActionBreak, nil\n\t\t\t\t}\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-a\", \"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\tv2 := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"enter\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Field:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"leave\", node.GetKind(), nil})\n\t\t\t\tif node.Name != nil && node.Name.Value == \"b\" {\n\t\t\t\t\treturn visitor.ActionBreak, nil\n\t\t\t\t}\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"break-b\", \"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, visitor.VisitInParallel(v, v2), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_VisitInParallel_AllowsForEditingOnEnter(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\tquery := `{ a, b, c { a, b, c } }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"c\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"leave\", \"Document\", nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Field:\n\t\t\t\tif node != nil && node.Name != nil && node.Name.Value == \"b\" {\n\t\t\t\t\treturn visitor.ActionUpdate, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\tv2 := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, visitor.VisitInParallel(v, v2), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n}\n\nfunc TestVisitor_VisitInParallel_AllowsForEditingOnLeave(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\tquery := `{ a, b, c { a, b, c } }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"b\"},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"c\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"a\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"b\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"b\"},\n\t\t[]interface{}{\"enter\", \"Field\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"c\"},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", nil},\n\t\t[]interface{}{\"leave\", \"Document\", nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Field:\n\t\t\t\tif node != nil && node.Name != nil && node.Name.Value == \"b\" {\n\t\t\t\t\treturn visitor.ActionUpdate, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\tv2 := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\teditedAST := visitor.Visit(astDoc, visitor.VisitInParallel(v, v2), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n\n\texpectedEditedAST := parse(t, `{ a,    c { a,    c } }`)\n\tif !reflect.DeepEqual(editedAST, expectedEditedAST) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedEditedAST, editedAST))\n\t}\n}\n\nfunc TestVisitor_VisitWithTypeInfo_MaintainsTypeInfoDuringVisit(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\ttypeInfo := graphql.NewTypeInfo(&graphql.TypeInfoConfig{\n\t\tSchema: testutil.TestSchema,\n\t})\n\n\tquery := `{ human(id: 4) { name, pets { name }, unknown } }`\n\tastDoc := parse(t, query)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil, nil, nil, nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil, nil, \"QueryRoot\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil, \"QueryRoot\", \"QueryRoot\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"QueryRoot\", \"Human\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"human\", \"QueryRoot\", \"Human\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"human\", \"QueryRoot\", \"Human\", nil},\n\t\t[]interface{}{\"enter\", \"Argument\", nil, \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"id\", \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"id\", \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"enter\", \"IntValue\", nil, \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"leave\", \"IntValue\", nil, \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"leave\", \"Argument\", nil, \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil, \"Human\", \"Human\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"Human\", \"String\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"name\", \"Human\", \"String\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"name\", \"Human\", \"String\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"Human\", \"String\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"Human\", \"[Pet]\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"pets\", \"Human\", \"[Pet]\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"pets\", \"Human\", \"[Pet]\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil, \"Pet\", \"[Pet]\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"Pet\", \"String\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"name\", \"Pet\", \"String\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"name\", \"Pet\", \"String\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"Pet\", \"String\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil, \"Pet\", \"[Pet]\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"Human\", \"[Pet]\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"Human\", nil, nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"unknown\", \"Human\", nil, nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"unknown\", \"Human\", nil, nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"Human\", nil, nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil, \"Human\", \"Human\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"QueryRoot\", \"Human\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil, \"QueryRoot\", \"QueryRoot\", nil},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", nil, nil, \"QueryRoot\", nil},\n\t\t[]interface{}{\"leave\", \"Document\", nil, nil, nil, nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tvar parentType interface{}\n\t\t\tvar ttype interface{}\n\t\t\tvar inputType interface{}\n\n\t\t\tif typeInfo.ParentType() != nil {\n\t\t\t\tparentType = fmt.Sprintf(\"%v\", typeInfo.ParentType())\n\t\t\t}\n\t\t\tif typeInfo.Type() != nil {\n\t\t\t\tttype = fmt.Sprintf(\"%v\", typeInfo.Type())\n\t\t\t}\n\t\t\tif typeInfo.InputType() != nil {\n\t\t\t\tinputType = fmt.Sprintf(\"%v\", typeInfo.InputType())\n\t\t\t}\n\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value, parentType, ttype, inputType})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil, parentType, ttype, inputType})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil, parentType, ttype, inputType})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tvar parentType interface{}\n\t\t\tvar ttype interface{}\n\t\t\tvar inputType interface{}\n\n\t\t\tif typeInfo.ParentType() != nil {\n\t\t\t\tparentType = fmt.Sprintf(\"%v\", typeInfo.ParentType())\n\t\t\t}\n\t\t\tif typeInfo.Type() != nil {\n\t\t\t\tttype = fmt.Sprintf(\"%v\", typeInfo.Type())\n\t\t\t}\n\t\t\tif typeInfo.InputType() != nil {\n\t\t\t\tinputType = fmt.Sprintf(\"%v\", typeInfo.InputType())\n\t\t\t}\n\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value, parentType, ttype, inputType})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil, parentType, ttype, inputType})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil, parentType, ttype, inputType})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\t_ = visitor.Visit(astDoc, visitor.VisitWithTypeInfo(typeInfo, v), nil)\n\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n\n}\n\nfunc TestVisitor_VisitWithTypeInfo_MaintainsTypeInfoDuringEdit(t *testing.T) {\n\n\tvisited := []interface{}{}\n\n\ttypeInfo := graphql.NewTypeInfo(&graphql.TypeInfoConfig{\n\t\tSchema: testutil.TestSchema,\n\t})\n\n\tastDoc := parse(t, `{ human(id: 4) { name, pets }, alien }`)\n\n\texpectedVisited := []interface{}{\n\t\t[]interface{}{\"enter\", \"Document\", nil, nil, nil, nil},\n\t\t[]interface{}{\"enter\", \"OperationDefinition\", nil, nil, \"QueryRoot\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil, \"QueryRoot\", \"QueryRoot\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"QueryRoot\", \"Human\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"human\", \"QueryRoot\", \"Human\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"human\", \"QueryRoot\", \"Human\", nil},\n\t\t[]interface{}{\"enter\", \"Argument\", nil, \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"enter\", \"Name\", \"id\", \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"leave\", \"Name\", \"id\", \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"enter\", \"IntValue\", nil, \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"leave\", \"IntValue\", nil, \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"leave\", \"Argument\", nil, \"QueryRoot\", \"Human\", \"ID\"},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil, \"Human\", \"Human\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"Human\", \"String\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"name\", \"Human\", \"String\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"name\", \"Human\", \"String\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"Human\", \"String\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"Human\", \"[Pet]\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"pets\", \"Human\", \"[Pet]\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"pets\", \"Human\", \"[Pet]\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil, \"Pet\", \"[Pet]\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"Pet\", \"String!\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"__typename\", \"Pet\", \"String!\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"__typename\", \"Pet\", \"String!\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"Pet\", \"String!\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil, \"Pet\", \"[Pet]\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"Human\", \"[Pet]\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil, \"Human\", \"Human\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"QueryRoot\", \"Human\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"QueryRoot\", \"Alien\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"alien\", \"QueryRoot\", \"Alien\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"alien\", \"QueryRoot\", \"Alien\", nil},\n\t\t[]interface{}{\"enter\", \"SelectionSet\", nil, \"Alien\", \"Alien\", nil},\n\t\t[]interface{}{\"enter\", \"Field\", nil, \"Alien\", \"String!\", nil},\n\t\t[]interface{}{\"enter\", \"Name\", \"__typename\", \"Alien\", \"String!\", nil},\n\t\t[]interface{}{\"leave\", \"Name\", \"__typename\", \"Alien\", \"String!\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"Alien\", \"String!\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil, \"Alien\", \"Alien\", nil},\n\t\t[]interface{}{\"leave\", \"Field\", nil, \"QueryRoot\", \"Alien\", nil},\n\t\t[]interface{}{\"leave\", \"SelectionSet\", nil, \"QueryRoot\", \"QueryRoot\", nil},\n\t\t[]interface{}{\"leave\", \"OperationDefinition\", nil, nil, \"QueryRoot\", nil},\n\t\t[]interface{}{\"leave\", \"Document\", nil, nil, nil, nil},\n\t}\n\n\tv := &visitor.VisitorOptions{\n\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tvar parentType interface{}\n\t\t\tvar ttype interface{}\n\t\t\tvar inputType interface{}\n\n\t\t\tif typeInfo.ParentType() != nil {\n\t\t\t\tparentType = fmt.Sprintf(\"%v\", typeInfo.ParentType())\n\t\t\t}\n\t\t\tif typeInfo.Type() != nil {\n\t\t\t\tttype = fmt.Sprintf(\"%v\", typeInfo.Type())\n\t\t\t}\n\t\t\tif typeInfo.InputType() != nil {\n\t\t\t\tinputType = fmt.Sprintf(\"%v\", typeInfo.InputType())\n\t\t\t}\n\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.Kind, node.Value, parentType, ttype, inputType})\n\t\t\tcase *ast.Field:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil, parentType, ttype, inputType})\n\n\t\t\t\t// Make a query valid by adding missing selection sets.\n\t\t\t\tif node.SelectionSet == nil && graphql.IsCompositeType(graphql.GetNamed(typeInfo.Type())) {\n\t\t\t\t\treturn visitor.ActionUpdate, ast.NewField(&ast.Field{\n\t\t\t\t\t\tAlias:      node.Alias,\n\t\t\t\t\t\tName:       node.Name,\n\t\t\t\t\t\tArguments:  node.Arguments,\n\t\t\t\t\t\tDirectives: node.Directives,\n\t\t\t\t\t\tSelectionSet: ast.NewSelectionSet(&ast.SelectionSet{\n\t\t\t\t\t\t\tSelections: []ast.Selection{\n\t\t\t\t\t\t\t\tast.NewField(&ast.Field{\n\t\t\t\t\t\t\t\t\tName: ast.NewName(&ast.Name{\n\t\t\t\t\t\t\t\t\t\tValue: \"__typename\",\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", node.GetKind(), nil, parentType, ttype, inputType})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"enter\", nil, nil, parentType, ttype, inputType})\n\t\t\t}\n\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\tvar parentType interface{}\n\t\t\tvar ttype interface{}\n\t\t\tvar inputType interface{}\n\n\t\t\tif typeInfo.ParentType() != nil {\n\t\t\t\tparentType = fmt.Sprintf(\"%v\", typeInfo.ParentType())\n\t\t\t}\n\t\t\tif typeInfo.Type() != nil {\n\t\t\t\tttype = fmt.Sprintf(\"%v\", typeInfo.Type())\n\t\t\t}\n\t\t\tif typeInfo.InputType() != nil {\n\t\t\t\tinputType = fmt.Sprintf(\"%v\", typeInfo.InputType())\n\t\t\t}\n\n\t\t\tswitch node := p.Node.(type) {\n\t\t\tcase *ast.Name:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.Kind, node.Value, parentType, ttype, inputType})\n\t\t\tcase ast.Node:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", node.GetKind(), nil, parentType, ttype, inputType})\n\t\t\tdefault:\n\t\t\t\tvisited = append(visited, []interface{}{\"leave\", nil, nil, parentType, ttype, inputType})\n\t\t\t}\n\t\t\treturn visitor.ActionNoChange, nil\n\t\t},\n\t}\n\n\teditedAST := visitor.Visit(astDoc, visitor.VisitWithTypeInfo(typeInfo, v), nil)\n\n\teditedASTQuery := printer.Print(editedAST.(ast.Node))\n\texpectedEditedASTQuery := printer.Print(parse(t, `{ human(id: 4) { name, pets { __typename } }, alien { __typename } }`))\n\n\tif !reflect.DeepEqual(editedASTQuery, expectedEditedASTQuery) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedEditedASTQuery, editedASTQuery))\n\t}\n\tif !reflect.DeepEqual(visited, expectedVisited) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedVisited, visited))\n\t}\n\n}\n"
  },
  {
    "path": "lists_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc checkList(t *testing.T, testType graphql.Type, testData interface{}, expected *graphql.Result) {\n\t// TODO: uncomment t.Helper when support for go1.8 is dropped.\n\t//t.Helper()\n\tdata := map[string]interface{}{\n\t\t\"test\": testData,\n\t}\n\n\tdataType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"DataType\",\n\t\tFields: graphql.Fields{\n\t\t\t\"test\": &graphql.Field{\n\t\t\t\tType: testType,\n\t\t\t},\n\t\t},\n\t})\n\tdataType.AddFieldConfig(\"nest\", &graphql.Field{\n\t\tType: dataType,\n\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\treturn data, nil\n\t\t},\n\t})\n\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: dataType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Error in schema %v\", err.Error())\n\t}\n\n\t// parse query\n\tast := testutil.TestParse(t, `{ nest { test } }`)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: schema,\n\t\tAST:    ast,\n\t\tRoot:   data,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n\n}\n\n// Describe [T] Array<T>\nfunc TestLists_ListOfNullableObjects_ContainsValues(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\tdata := []interface{}{\n\t\t1, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_ListOfNullableObjects_ContainsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\tdata := []interface{}{\n\t\t1, nil, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, nil, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_ListOfNullableObjects_ReturnsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": nil,\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, nil, expected)\n}\n\n// Describe [T] Func()Array<T> // equivalent to Promise<Array<T>>\nfunc TestLists_ListOfNullableFunc_ContainsValues(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn []interface{}{\n\t\t\t1, 2,\n\t\t}\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_ListOfNullableFunc_ContainsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn []interface{}{\n\t\t\t1, nil, 2,\n\t\t}\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, nil, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_ListOfNullableFunc_ReturnsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn nil\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": nil,\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\n// Describe [T] Array<Func()<T>> // equivalent to Array<Promise<T>>\nfunc TestLists_ListOfNullableArrayOfFuncContainsValues(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\n\t// `data` is a slice of functions that return values\n\t// Note that its uses the expected signature `func() (interface{}, error) {...}`\n\tdata := []interface{}{\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 1, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 2, nil\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_ListOfNullableArrayOfFuncContainsNulls(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\n\t// `data` is a slice of functions that return values\n\t// Note that its uses the expected signature `func() (interface{}, error) {...}`\n\tdata := []interface{}{\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 1, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn nil, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 2, nil\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, nil, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\n// Describe [T]! Array<T>\nfunc TestLists_NonNullListOfNullableObjectsContainsValues(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.Int))\n\tdata := []interface{}{\n\t\t1, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNullableObjectsContainsNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.Int))\n\tdata := []interface{}{\n\t\t1, nil, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, nil, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNullableObjectsReturnsNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.Int))\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, nil, expected)\n}\n\n// Describe [T]! Func()Array<T> // equivalent to Promise<Array<T>>\nfunc TestLists_NonNullListOfNullableFunc_ContainsValues(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.Int))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn []interface{}{\n\t\t\t1, 2,\n\t\t}\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNullableFunc_ContainsNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.Int))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn []interface{}{\n\t\t\t1, nil, 2,\n\t\t}\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, nil, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNullableFunc_ReturnsNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.Int))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn nil\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\n// Describe [T]! Array<Func()<T>> // equivalent to Array<Promise<T>>\nfunc TestLists_NonNullListOfNullableArrayOfFunc_ContainsValues(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.Int))\n\n\t// `data` is a slice of functions that return values\n\t// Note that its uses the expected signature `func() (interface{}, error) {...}`\n\tdata := []interface{}{\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 1, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 2, nil\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNullableArrayOfFunc_ContainsNulls(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.Int))\n\n\t// `data` is a slice of functions that return values\n\t// Note that its uses the expected signature `func() (interface{}, error) {...}`\n\tdata := []interface{}{\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 1, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn nil, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 2, nil\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, nil, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\n// Describe [T!] Array<T>\nfunc TestLists_NullableListOfNonNullObjects_ContainsValues(t *testing.T) {\n\tttype := graphql.NewList(graphql.NewNonNull(graphql.Int))\n\tdata := []interface{}{\n\t\t1, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NullableListOfNonNullObjects_ContainsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.NewNonNull(graphql.Int))\n\tdata := []interface{}{\n\t\t1, nil, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": nil,\n\t\t\t},\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t\t1,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NullableListOfNonNullObjects_ReturnsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.NewNonNull(graphql.Int))\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": nil,\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, nil, expected)\n}\n\n// Describe [T!] Func()Array<T> // equivalent to Promise<Array<T>>\nfunc TestLists_NullableListOfNonNullFunc_ContainsValues(t *testing.T) {\n\tttype := graphql.NewList(graphql.NewNonNull(graphql.Int))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn []interface{}{\n\t\t\t1, 2,\n\t\t}\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NullableListOfNonNullFunc_ContainsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.NewNonNull(graphql.Int))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn []interface{}{\n\t\t\t1, nil, 2,\n\t\t}\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": nil,\n\t\t\t},\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t\t1,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NullableListOfNonNullFunc_ReturnsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.NewNonNull(graphql.Int))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn nil\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": nil,\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\n// Describe [T!] Array<Func()<T>> // equivalent to Array<Promise<T>>\nfunc TestLists_NullableListOfNonNullArrayOfFunc_ContainsValues(t *testing.T) {\n\tttype := graphql.NewList(graphql.NewNonNull(graphql.Int))\n\n\t// `data` is a slice of functions that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := []interface{}{\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 1, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 2, nil\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NullableListOfNonNullArrayOfFunc_ContainsNulls(t *testing.T) {\n\tttype := graphql.NewList(graphql.NewNonNull(graphql.Int))\n\n\t// `data` is a slice of functions that return values\n\t// Note that its uses the expected signature `func() (interface{}, error){...}`\n\tdata := []interface{}{\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 1, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn nil, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 2, nil\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\t/*\n\t\t\t// TODO: Because thunks are called after the result map has been assembled,\n\t\t\t// we are not able to traverse up the tree until we find a nullable type,\n\t\t\t// so in this case the entire data is nil. Will need some significant code\n\t\t\t// restructure to restore this.\n\t\t\tData: map[string]interface{}{\n\t\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\t\"test\": nil,\n\t\t\t\t},\n\t\t\t},\n\t\t*/\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t\t1,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\n// Describe [T!]! Array<T>\nfunc TestLists_NonNullListOfNonNullObjects_ContainsValues(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int)))\n\tdata := []interface{}{\n\t\t1, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNonNullObjects_ContainsNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int)))\n\tdata := []interface{}{\n\t\t1, nil, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t\t1,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNonNullObjects_ReturnsNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int)))\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, nil, expected)\n}\n\n// Describe [T!]! Func()Array<T> // equivalent to Promise<Array<T>>\nfunc TestLists_NonNullListOfNonNullFunc_ContainsValues(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int)))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn []interface{}{\n\t\t\t1, 2,\n\t\t}\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNonNullFunc_ContainsNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int)))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn []interface{}{\n\t\t\t1, nil, 2,\n\t\t}\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t\t1,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNonNullFunc_ReturnsNull(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int)))\n\n\t// `data` is a function that return values\n\t// Note that its uses the expected signature `func() interface{} {...}`\n\tdata := func() interface{} {\n\t\treturn nil\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\n// Describe [T!]! Array<Func()<T>> // equivalent to Array<Promise<T>>\nfunc TestLists_NonNullListOfNonNullArrayOfFunc_ContainsValues(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int)))\n\n\t// `data` is a slice of functions that return values\n\t// Note that its uses the expected signature `func() (interface{}, error) {...}`\n\tdata := []interface{}{\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 1, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 2, nil\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\nfunc TestLists_NonNullListOfNonNullArrayOfFunc_ContainsNulls(t *testing.T) {\n\tttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int)))\n\n\t// `data` is a slice of functions that return values\n\t// Note that its uses the expected signature `func() (interface{}, error) {...}`\n\tdata := []interface{}{\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 1, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn nil, nil\n\t\t},\n\t\tfunc() (interface{}, error) {\n\t\t\treturn 2, nil\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\t/*\n\t\t\t// TODO: Because thunks are called after the result map has been assembled,\n\t\t\t// we are not able to traverse up the tree until we find a nullable type,\n\t\t\t// so in this case the entire data is nil. Will need some significant code\n\t\t\t// restructure to restore this.\n\t\t\tData: map[string]interface{}{\n\t\t\t\t\"nest\": nil,\n\t\t\t},\n\t\t*/\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Cannot return null for non-nullable field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t\t1,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\nfunc TestLists_UserErrorExpectIterableButDidNotGetOne(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\tdata := \"Not an iterable\"\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": nil,\n\t\t\t},\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"User Error: expected iterable, but did not find one for field DataType.test.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine:   1,\n\t\t\t\t\t\tColumn: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"test\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\nfunc TestLists_ArrayOfNullableObjects_ContainsValues(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\tdata := [2]interface{}{\n\t\t1, 2,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": []interface{}{\n\t\t\t\t\t1, 2,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n\nfunc TestLists_ValueMayBeNilPointer(t *testing.T) {\n\tvar listTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"list\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(graphql.Int),\n\t\t\t\t\tResolve: func(_ graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn []int(nil), nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tquery := \"{ list }\"\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"list\": []interface{}{},\n\t\t},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        listTestSchema,\n\t\tRequestString: query,\n\t})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestLists_NullableListOfInt_ReturnsNull(t *testing.T) {\n\tttype := graphql.NewList(graphql.Int)\n\ttype dataType *[]int\n\tvar data dataType\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"test\": nil,\n\t\t\t},\n\t\t},\n\t}\n\tcheckList(t, ttype, data, expected)\n}\n"
  },
  {
    "path": "located.go",
    "content": "package graphql\n\nimport (\n\t\"errors\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\nfunc NewLocatedError(err interface{}, nodes []ast.Node) *gqlerrors.Error {\n\treturn newLocatedError(err, nodes, nil)\n}\n\nfunc NewLocatedErrorWithPath(err interface{}, nodes []ast.Node, path []interface{}) *gqlerrors.Error {\n\treturn newLocatedError(err, nodes, path)\n}\n\nfunc newLocatedError(err interface{}, nodes []ast.Node, path []interface{}) *gqlerrors.Error {\n\tif err, ok := err.(*gqlerrors.Error); ok {\n\t\treturn err\n\t}\n\n\tvar origError error\n\tmessage := \"An unknown error occurred.\"\n\tif err, ok := err.(error); ok {\n\t\tmessage = err.Error()\n\t\torigError = err\n\t}\n\tif err, ok := err.(string); ok {\n\t\tmessage = err\n\t\torigError = errors.New(err)\n\t}\n\tstack := message\n\treturn gqlerrors.NewErrorWithPath(\n\t\tmessage,\n\t\tnodes,\n\t\tstack,\n\t\tnil,\n\t\t[]int{},\n\t\tpath,\n\t\torigError,\n\t)\n}\n\nfunc FieldASTsToNodeASTs(fieldASTs []*ast.Field) []ast.Node {\n\tnodes := []ast.Node{}\n\tfor _, fieldAST := range fieldASTs {\n\t\tnodes = append(nodes, fieldAST)\n\t}\n\treturn nodes\n}\n"
  },
  {
    "path": "mutations_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\n// testNumberHolder maps to numberHolderType\ntype testNumberHolder struct {\n\tTheNumber int `json:\"theNumber\"` // map field to `theNumber` so it can be resolve by the default ResolveFn\n}\ntype testRoot struct {\n\tNumberHolder *testNumberHolder\n}\n\nfunc newTestRoot(originalNumber int) *testRoot {\n\treturn &testRoot{\n\t\tNumberHolder: &testNumberHolder{originalNumber},\n\t}\n}\nfunc (r *testRoot) ImmediatelyChangeTheNumber(newNumber int) *testNumberHolder {\n\tr.NumberHolder.TheNumber = newNumber\n\treturn r.NumberHolder\n}\nfunc (r *testRoot) PromiseToChangeTheNumber(newNumber int) *testNumberHolder {\n\treturn r.ImmediatelyChangeTheNumber(newNumber)\n}\nfunc (r *testRoot) FailToChangeTheNumber(newNumber int) *testNumberHolder {\n\tpanic(\"Cannot change the number\")\n}\nfunc (r *testRoot) PromiseAndFailToChangeTheNumber(newNumber int) *testNumberHolder {\n\tpanic(\"Cannot change the number\")\n}\n\n// numberHolderType creates a mapping to testNumberHolder\nvar numberHolderType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"NumberHolder\",\n\tFields: graphql.Fields{\n\t\t\"theNumber\": &graphql.Field{\n\t\t\tType: graphql.Int,\n\t\t},\n\t},\n})\n\nvar mutationsTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"numberHolder\": &graphql.Field{\n\t\t\t\tType: numberHolderType,\n\t\t\t},\n\t\t},\n\t}),\n\tMutation: graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Mutation\",\n\t\tFields: graphql.Fields{\n\t\t\t\"immediatelyChangeTheNumber\": &graphql.Field{\n\t\t\t\tType: numberHolderType,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"newNumber\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tnewNumber := 0\n\t\t\t\t\tobj, _ := p.Source.(*testRoot)\n\t\t\t\t\tnewNumber, _ = p.Args[\"newNumber\"].(int)\n\t\t\t\t\treturn obj.ImmediatelyChangeTheNumber(newNumber), nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"promiseToChangeTheNumber\": &graphql.Field{\n\t\t\t\tType: numberHolderType,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"newNumber\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tnewNumber := 0\n\t\t\t\t\tobj, _ := p.Source.(*testRoot)\n\t\t\t\t\tnewNumber, _ = p.Args[\"newNumber\"].(int)\n\t\t\t\t\treturn obj.PromiseToChangeTheNumber(newNumber), nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"failToChangeTheNumber\": &graphql.Field{\n\t\t\t\tType: numberHolderType,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"newNumber\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tnewNumber := 0\n\t\t\t\t\tobj, _ := p.Source.(*testRoot)\n\t\t\t\t\tnewNumber, _ = p.Args[\"newNumber\"].(int)\n\t\t\t\t\treturn obj.FailToChangeTheNumber(newNumber), nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"promiseAndFailToChangeTheNumber\": &graphql.Field{\n\t\t\t\tType: numberHolderType,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"newNumber\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tnewNumber := 0\n\t\t\t\t\tobj, _ := p.Source.(*testRoot)\n\t\t\t\t\tnewNumber, _ = p.Args[\"newNumber\"].(int)\n\t\t\t\t\treturn obj.PromiseAndFailToChangeTheNumber(newNumber), nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}),\n})\n\nfunc TestMutations_ExecutionOrdering_EvaluatesMutationsSerially(t *testing.T) {\n\n\troot := newTestRoot(6)\n\tdoc := `mutation M {\n      first: immediatelyChangeTheNumber(newNumber: 1) {\n        theNumber\n      },\n      second: promiseToChangeTheNumber(newNumber: 2) {\n        theNumber\n      },\n      third: immediatelyChangeTheNumber(newNumber: 3) {\n        theNumber\n      }\n      fourth: promiseToChangeTheNumber(newNumber: 4) {\n        theNumber\n      },\n      fifth: immediatelyChangeTheNumber(newNumber: 5) {\n        theNumber\n      }\n    }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"first\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 1,\n\t\t\t},\n\t\t\t\"second\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 2,\n\t\t\t},\n\t\t\t\"third\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 3,\n\t\t\t},\n\t\t\t\"fourth\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 4,\n\t\t\t},\n\t\t\t\"fifth\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 5,\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: mutationsTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   root,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestMutations_EvaluatesMutationsCorrectlyInThePresenceOfAFailedMutation(t *testing.T) {\n\n\troot := newTestRoot(6)\n\tdoc := `mutation M {\n      first: immediatelyChangeTheNumber(newNumber: 1) {\n        theNumber\n      },\n      second: promiseToChangeTheNumber(newNumber: 2) {\n        theNumber\n      },\n      third: failToChangeTheNumber(newNumber: 3) {\n        theNumber\n      }\n      fourth: promiseToChangeTheNumber(newNumber: 4) {\n        theNumber\n      },\n      fifth: immediatelyChangeTheNumber(newNumber: 5) {\n        theNumber\n      }\n      sixth: promiseAndFailToChangeTheNumber(newNumber: 6) {\n        theNumber\n      }\n    }`\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"first\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 1,\n\t\t\t},\n\t\t\t\"second\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 2,\n\t\t\t},\n\t\t\t\"third\": nil,\n\t\t\t\"fourth\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 4,\n\t\t\t},\n\t\t\t\"fifth\": map[string]interface{}{\n\t\t\t\t\"theNumber\": 5,\n\t\t\t},\n\t\t\t\"sixth\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Cannot change the number`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 8, Column: 7},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tMessage: `Cannot change the number`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 17, Column: 7},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: mutationsTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   root,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tt.Skipf(\"Testing equality for slice of errors in results\")\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "nonnull_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"sort\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nvar syncError = \"sync\"\nvar nonNullSyncError = \"nonNullSync\"\nvar promiseError = \"promise\"\nvar nonNullPromiseError = \"nonNullPromise\"\n\nvar throwingData = map[string]interface{}{\n\t\"sync\": func() interface{} {\n\t\tpanic(syncError)\n\t},\n\t\"nonNullSync\": func() interface{} {\n\t\tpanic(nonNullSyncError)\n\t},\n\t\"promise\": func() interface{} {\n\t\tpanic(promiseError)\n\t},\n\t\"nonNullPromise\": func() interface{} {\n\t\tpanic(nonNullPromiseError)\n\t},\n}\n\nvar nullingData = map[string]interface{}{\n\t\"sync\": func() interface{} {\n\t\treturn nil\n\t},\n\t\"nonNullSync\": func() interface{} {\n\t\treturn nil\n\t},\n\t\"promise\": func() interface{} {\n\t\treturn nil\n\t},\n\t\"nonNullPromise\": func() interface{} {\n\t\treturn nil\n\t},\n}\n\nvar dataType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"DataType\",\n\tFields: graphql.Fields{\n\t\t\"sync\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"nonNullSync\": &graphql.Field{\n\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t},\n\t\t\"promise\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"nonNullPromise\": &graphql.Field{\n\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t},\n\t},\n})\n\nvar nonNullTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\tQuery: dataType,\n})\n\nfunc init() {\n\tthrowingData[\"nest\"] = func() interface{} {\n\t\treturn throwingData\n\t}\n\tthrowingData[\"nonNullNest\"] = func() interface{} {\n\t\treturn throwingData\n\t}\n\tthrowingData[\"promiseNest\"] = func() interface{} {\n\t\treturn throwingData\n\t}\n\tthrowingData[\"nonNullPromiseNest\"] = func() interface{} {\n\t\treturn throwingData\n\t}\n\n\tnullingData[\"nest\"] = func() interface{} {\n\t\treturn nullingData\n\t}\n\tnullingData[\"nonNullNest\"] = func() interface{} {\n\t\treturn nullingData\n\t}\n\tnullingData[\"promiseNest\"] = func() interface{} {\n\t\treturn nullingData\n\t}\n\tnullingData[\"nonNullPromiseNest\"] = func() interface{} {\n\t\treturn nullingData\n\t}\n\n\tdataType.AddFieldConfig(\"nest\", &graphql.Field{\n\t\tType: dataType,\n\t})\n\tdataType.AddFieldConfig(\"nonNullNest\", &graphql.Field{\n\t\tType: graphql.NewNonNull(dataType),\n\t})\n\tdataType.AddFieldConfig(\"promiseNest\", &graphql.Field{\n\t\tType: dataType,\n\t})\n\tdataType.AddFieldConfig(\"nonNullPromiseNest\", &graphql.Field{\n\t\tType: graphql.NewNonNull(dataType),\n\t})\n}\n\n// nulls a nullable field that panics\nfunc TestNonNull_NullsANullableFieldThatThrowsSynchronously(t *testing.T) {\n\tdoc := `\n      query Q {\n        sync\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"sync\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: syncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 3, Column: 9,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"sync\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsANullableFieldThatThrowsInAPromise(t *testing.T) {\n\tdoc := `\n      query Q {\n        promise\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"promise\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: promiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 3, Column: 9,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promise\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANullableFieldThatThrowsSynchronously(t *testing.T) {\n\tdoc := `\n      query Q {\n        nest {\n          nonNullSync,\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: nonNullSyncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 4, Column: 11,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"nonNullSync\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatThrowsInAPromise(t *testing.T) {\n\tdoc := `\n      query Q {\n        nest {\n          nonNullPromise,\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: nonNullPromiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 4, Column: 11,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"nonNullPromise\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatThrowsSynchronously(t *testing.T) {\n\tdoc := `\n      query Q {\n        promiseNest {\n          nonNullSync,\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"promiseNest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: nonNullSyncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 4, Column: 11,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\",\n\t\t\t\t\t\"nonNullSync\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatThrowsInAPromise(t *testing.T) {\n\tdoc := `\n      query Q {\n        promiseNest {\n          nonNullPromise,\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"promiseNest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: nonNullPromiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 4, Column: 11,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\",\n\t\t\t\t\t\"nonNullPromise\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestNonNull_NullsAComplexTreeOfNullableFieldsThatThrow(t *testing.T) {\n\tdoc := `\n      query Q {\n        nest {\n          sync\n          promise\n          nest {\n            sync\n            promise\n          }\n          promiseNest {\n            sync\n            promise\n          }\n        }\n        promiseNest {\n          sync\n          promise\n          nest {\n            sync\n            promise\n          }\n          promiseNest {\n            sync\n            promise\n          }\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"sync\":    nil,\n\t\t\t\t\"promise\": nil,\n\t\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\t\"sync\":    nil,\n\t\t\t\t\t\"promise\": nil,\n\t\t\t\t},\n\t\t\t\t\"promiseNest\": map[string]interface{}{\n\t\t\t\t\t\"sync\":    nil,\n\t\t\t\t\t\"promise\": nil,\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"promiseNest\": map[string]interface{}{\n\t\t\t\t\"sync\":    nil,\n\t\t\t\t\"promise\": nil,\n\t\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\t\"sync\":    nil,\n\t\t\t\t\t\"promise\": nil,\n\t\t\t\t},\n\t\t\t\t\"promiseNest\": map[string]interface{}{\n\t\t\t\t\t\"sync\":    nil,\n\t\t\t\t\t\"promise\": nil,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: syncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 4, Column: 11},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\", \"sync\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: syncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 7, Column: 13},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\", \"nest\", \"sync\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: syncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 11, Column: 13},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\", \"promiseNest\", \"sync\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: syncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 16, Column: 11},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\", \"sync\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: syncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 19, Column: 13},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\", \"nest\", \"sync\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: syncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 23, Column: 13},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\", \"promiseNest\", \"sync\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: promiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 5, Column: 11},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\", \"promise\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: promiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 8, Column: 13},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\", \"nest\", \"promise\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: promiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 12, Column: 13},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\", \"promiseNest\", \"promise\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: promiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 17, Column: 11},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\", \"promise\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: promiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 20, Column: 13},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\", \"nest\", \"promise\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: promiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 24, Column: 13},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\", \"promiseNest\", \"promise\",\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tsort.Sort(gqlerrors.FormattedErrors(expected.Errors))\n\tsort.Sort(gqlerrors.FormattedErrors(result.Errors))\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n}\nfunc TestNonNull_NullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfFieldsThatAreNonNull(t *testing.T) {\n\tdoc := `\n      query Q {\n        nest {\n          nonNullNest {\n            nonNullPromiseNest {\n              nonNullNest {\n                nonNullPromiseNest {\n                  nonNullSync\n                }\n              }\n            }\n          }\n        }\n        promiseNest {\n          nonNullNest {\n            nonNullPromiseNest {\n              nonNullNest {\n                nonNullPromiseNest {\n                  nonNullSync\n                }\n              }\n            }\n          }\n        }\n        anotherNest: nest {\n          nonNullNest {\n            nonNullPromiseNest {\n              nonNullNest {\n                nonNullPromiseNest {\n                  nonNullPromise\n                }\n              }\n            }\n          }\n        }\n        anotherPromiseNest: promiseNest {\n          nonNullNest {\n            nonNullPromiseNest {\n              nonNullNest {\n                nonNullPromiseNest {\n                  nonNullPromise\n                }\n              }\n            }\n          }\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\":               nil,\n\t\t\t\"promiseNest\":        nil,\n\t\t\t\"anotherNest\":        nil,\n\t\t\t\"anotherPromiseNest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: nonNullSyncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 8, Column: 19},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\", \"nonNullNest\", \"nonNullPromiseNest\", \"nonNullNest\",\n\t\t\t\t\t\"nonNullPromiseNest\", \"nonNullSync\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: nonNullSyncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 19, Column: 19},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\", \"nonNullNest\", \"nonNullPromiseNest\", \"nonNullNest\",\n\t\t\t\t\t\"nonNullPromiseNest\", \"nonNullSync\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: nonNullPromiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 30, Column: 19},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"anotherNest\", \"nonNullNest\", \"nonNullPromiseNest\", \"nonNullNest\",\n\t\t\t\t\t\"nonNullPromiseNest\", \"nonNullPromise\",\n\t\t\t\t},\n\t\t\t}),\n\t\t\tgqlerrors.FormatError(gqlerrors.Error{\n\t\t\t\tMessage: nonNullPromiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 41, Column: 19},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"anotherPromiseNest\", \"nonNullNest\", \"nonNullPromiseNest\", \"nonNullNest\",\n\t\t\t\t\t\"nonNullPromiseNest\", \"nonNullPromise\",\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tsort.Sort(gqlerrors.FormattedErrors(expected.Errors))\n\tsort.Sort(gqlerrors.FormattedErrors(result.Errors))\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\n}\nfunc TestNonNull_NullsANullableFieldThatSynchronouslyReturnsNull(t *testing.T) {\n\tdoc := `\n      query Q {\n        sync\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"sync\": nil,\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsANullableFieldThatSynchronouslyReturnsNullInAPromise(t *testing.T) {\n\tdoc := `\n      query Q {\n        promise\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"promise\": nil,\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatReturnsNullSynchronously(t *testing.T) {\n\tdoc := `\n      query Q {\n        nest {\n          nonNullSync,\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullSync.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 4, Column: 11},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"nonNullSync\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatReturnsNullInAPromise(t *testing.T) {\n\tdoc := `\n      query Q {\n        nest {\n          nonNullPromise,\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullPromise.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 4, Column: 11},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\",\n\t\t\t\t\t\"nonNullPromise\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatReturnsNullSynchronously(t *testing.T) {\n\tdoc := `\n      query Q {\n        promiseNest {\n          nonNullSync,\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"promiseNest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullSync.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 4, Column: 11},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\",\n\t\t\t\t\t\"nonNullSync\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatReturnsNullInAPromise(t *testing.T) {\n\tdoc := `\n      query Q {\n        promiseNest {\n          nonNullPromise,\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"promiseNest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullPromise.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 4, Column: 11},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\",\n\t\t\t\t\t\"nonNullPromise\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsAComplexTreeOfNullableFieldsThatReturnNull(t *testing.T) {\n\tdoc := `\n      query Q {\n        nest {\n          sync\n          promise\n          nest {\n            sync\n            promise\n          }\n          promiseNest {\n            sync\n            promise\n          }\n        }\n        promiseNest {\n          sync\n          promise\n          nest {\n            sync\n            promise\n          }\n          promiseNest {\n            sync\n            promise\n          }\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\"sync\":    nil,\n\t\t\t\t\"promise\": nil,\n\t\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\t\"sync\":    nil,\n\t\t\t\t\t\"promise\": nil,\n\t\t\t\t},\n\t\t\t\t\"promiseNest\": map[string]interface{}{\n\t\t\t\t\t\"sync\":    nil,\n\t\t\t\t\t\"promise\": nil,\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"promiseNest\": map[string]interface{}{\n\t\t\t\t\"sync\":    nil,\n\t\t\t\t\"promise\": nil,\n\t\t\t\t\"nest\": map[string]interface{}{\n\t\t\t\t\t\"sync\":    nil,\n\t\t\t\t\t\"promise\": nil,\n\t\t\t\t},\n\t\t\t\t\"promiseNest\": map[string]interface{}{\n\t\t\t\t\t\"sync\":    nil,\n\t\t\t\t\t\"promise\": nil,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected.Data, result.Data))\n\t}\n}\nfunc TestNonNull_NullsTheFirstNullableObjectAfterAFieldReturnsNullInALongChainOfFieldsThatAreNonNull(t *testing.T) {\n\tdoc := `\n      query Q {\n        nest {\n          nonNullNest {\n            nonNullPromiseNest {\n              nonNullNest {\n                nonNullPromiseNest {\n                  nonNullSync\n                }\n              }\n            }\n          }\n        }\n        promiseNest {\n          nonNullNest {\n            nonNullPromiseNest {\n              nonNullNest {\n                nonNullPromiseNest {\n                  nonNullSync\n                }\n              }\n            }\n          }\n        }\n        anotherNest: nest {\n          nonNullNest {\n            nonNullPromiseNest {\n              nonNullNest {\n                nonNullPromiseNest {\n                  nonNullPromise\n                }\n              }\n            }\n          }\n        }\n        anotherPromiseNest: promiseNest {\n          nonNullNest {\n            nonNullPromiseNest {\n              nonNullNest {\n                nonNullPromiseNest {\n                  nonNullPromise\n                }\n              }\n            }\n          }\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nest\":               nil,\n\t\t\t\"promiseNest\":        nil,\n\t\t\t\"anotherNest\":        nil,\n\t\t\t\"anotherPromiseNest\": nil,\n\t\t},\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullSync.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 8, Column: 19},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nest\", \"nonNullNest\", \"nonNullPromiseNest\", \"nonNullNest\",\n\t\t\t\t\t\"nonNullPromiseNest\", \"nonNullSync\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullSync.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 19, Column: 19},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"promiseNest\", \"nonNullNest\", \"nonNullPromiseNest\", \"nonNullNest\",\n\t\t\t\t\t\"nonNullPromiseNest\", \"nonNullSync\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullPromise.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 30, Column: 19},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"anotherNest\", \"nonNullNest\", \"nonNullPromiseNest\", \"nonNullNest\",\n\t\t\t\t\t\"nonNullPromiseNest\", \"nonNullPromise\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullPromise.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 41, Column: 19},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"anotherPromiseNest\", \"nonNullNest\", \"nonNullPromiseNest\", \"nonNullNest\",\n\t\t\t\t\t\"nonNullPromiseNest\", \"nonNullPromise\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tsort.Sort(gqlerrors.FormattedErrors(expected.Errors))\n\tsort.Sort(gqlerrors.FormattedErrors(result.Errors))\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldThrows(t *testing.T) {\n\tdoc := `\n      query Q { nonNullSync }\n\t`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: nonNullSyncError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 2, Column: 17},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nonNullSync\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldErrors(t *testing.T) {\n\tdoc := `\n      query Q { nonNullPromise }\n\t`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: nonNullPromiseError,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 2, Column: 17},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nonNullPromise\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   throwingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldReturnsNull(t *testing.T) {\n\tdoc := `\n      query Q { nonNullSync }\n\t`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullSync.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 2, Column: 17},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nonNullSync\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldResolvesNull(t *testing.T) {\n\tdoc := `\n      query Q { nonNullPromise }\n\t`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Cannot return null for non-nullable field DataType.nonNullPromise.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{Line: 2, Column: 17},\n\t\t\t\t},\n\t\t\t\tPath: []interface{}{\n\t\t\t\t\t\"nonNullPromise\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: nonNullTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   nullingData,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "quoted_or_list_internal_test.go",
    "content": "package graphql\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestQuotedOrList_DoesNoAcceptAnEmptyList(t *testing.T) {\n\texpected := \"\"\n\tresult := quotedOrList([]string{})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Expected %v, got: %v\", expected, result)\n\t}\n}\nfunc TestQuotedOrList_ReturnsSingleQuotedItem(t *testing.T) {\n\texpected := `\"A\"`\n\tresult := quotedOrList([]string{\"A\"})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Expected %v, got: %v\", expected, result)\n\t}\n}\nfunc TestQuotedOrList_ReturnsTwoItems(t *testing.T) {\n\texpected := `\"A\" or \"B\"`\n\tresult := quotedOrList([]string{\"A\", \"B\"})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Expected %v, got: %v\", expected, result)\n\t}\n}\nfunc TestQuotedOrList_ReturnsCommaSeparatedManyItemList(t *testing.T) {\n\texpected := `\"A\", \"B\", \"C\", \"D\", or \"E\"`\n\tresult := quotedOrList([]string{\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Expected %v, got: %v\", expected, result)\n\t}\n}\n"
  },
  {
    "path": "race_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"io/ioutil\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"testing\"\n)\n\nfunc TestRace(t *testing.T) {\n\ttempdir, err := ioutil.TempDir(\"\", \"race\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer os.RemoveAll(tempdir)\n\n\tfilename := filepath.Join(tempdir, \"example.go\")\n\terr = ioutil.WriteFile(filename, []byte(`\n\t\tpackage main\n\n\t\timport (\n\t\t\t\"runtime\"\n\t\t\t\"sync\"\n\n\t\t\t\"github.com/graphql-go/graphql\"\n\t\t)\n\n\t\tfunc main() {\n\t\t\tvar wg sync.WaitGroup\n\t\t\twg.Add(2)\n\t\t\tfor i := 0; i < 2; i++ {\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer wg.Done()\n\t\t\t\t\tschema, _ := graphql.NewSchema(graphql.SchemaConfig{\n\t\t\t\t\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\t\t\t\t\tName: \"RootQuery\",\n\t\t\t\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\t\t\t\"hello\": &graphql.Field{\n\t\t\t\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\t\t\t\t\treturn \"world\", nil\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t\truntime.KeepAlive(schema)\n\t\t\t\t}()\n\t\t\t}\n\n\t\t\twg.Wait()\n\t\t} \n\t`), 0755)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tresult, err := exec.Command(\"go\", \"run\", \"-race\", filename).CombinedOutput()\n\tif err != nil || len(result) != 0 {\n\t\tt.Log(string(result))\n\t\tt.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "rules.go",
    "content": "package graphql\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/kinds\"\n\t\"github.com/graphql-go/graphql/language/printer\"\n\t\"github.com/graphql-go/graphql/language/visitor\"\n)\n\n// SpecifiedRules set includes all validation rules defined by the GraphQL spec.\nvar SpecifiedRules = []ValidationRuleFn{\n\tArgumentsOfCorrectTypeRule,\n\tDefaultValuesOfCorrectTypeRule,\n\tFieldsOnCorrectTypeRule,\n\tFragmentsOnCompositeTypesRule,\n\tKnownArgumentNamesRule,\n\tKnownDirectivesRule,\n\tKnownFragmentNamesRule,\n\tKnownTypeNamesRule,\n\tLoneAnonymousOperationRule,\n\tNoFragmentCyclesRule,\n\tNoUndefinedVariablesRule,\n\tNoUnusedFragmentsRule,\n\tNoUnusedVariablesRule,\n\tOverlappingFieldsCanBeMergedRule,\n\tPossibleFragmentSpreadsRule,\n\tProvidedNonNullArgumentsRule,\n\tScalarLeafsRule,\n\tUniqueArgumentNamesRule,\n\tUniqueFragmentNamesRule,\n\tUniqueInputFieldNamesRule,\n\tUniqueOperationNamesRule,\n\tUniqueVariableNamesRule,\n\tVariablesAreInputTypesRule,\n\tVariablesInAllowedPositionRule,\n}\n\ntype ValidationRuleInstance struct {\n\tVisitorOpts *visitor.VisitorOptions\n}\ntype ValidationRuleFn func(context *ValidationContext) *ValidationRuleInstance\n\nfunc newValidationError(message string, nodes []ast.Node) *gqlerrors.Error {\n\treturn gqlerrors.NewError(\n\t\tmessage,\n\t\tnodes,\n\t\t\"\",\n\t\tnil,\n\t\t[]int{},\n\t\tnil, // TODO: this is interim, until we port \"better-error-messages-for-inputs\"\n\t)\n}\n\nfunc reportError(context *ValidationContext, message string, nodes []ast.Node) (string, interface{}) {\n\tcontext.ReportError(newValidationError(message, nodes))\n\treturn visitor.ActionNoChange, nil\n}\n\n// ArgumentsOfCorrectTypeRule Argument values of correct type\n//\n// A GraphQL document is only valid if all field argument literal values are\n// of the type expected by their position.\nfunc ArgumentsOfCorrectTypeRule(context *ValidationContext) *ValidationRuleInstance {\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Argument: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif argAST, ok := p.Node.(*ast.Argument); ok {\n\t\t\t\t\t\tif argDef := context.Argument(); argDef != nil {\n\t\t\t\t\t\t\tif isValid, messages := isValidLiteralValue(argDef.Type, argAST.Value); !isValid {\n\t\t\t\t\t\t\t\tvar messagesStr, argNameValue string\n\t\t\t\t\t\t\t\tif argAST.Name != nil {\n\t\t\t\t\t\t\t\t\targNameValue = argAST.Name.Value\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif len(messages) > 0 {\n\t\t\t\t\t\t\t\t\tmessagesStr = \"\\n\" + strings.Join(messages, \"\\n\")\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\tfmt.Sprintf(`Argument \"%v\" has invalid value %v.%v`,\n\t\t\t\t\t\t\t\t\t\targNameValue, printer.Print(argAST.Value), messagesStr),\n\t\t\t\t\t\t\t\t\t[]ast.Node{argAST.Value},\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// DefaultValuesOfCorrectTypeRule Variable default values of correct type\n//\n// A GraphQL document is only valid if all variable default values are of the\n// type expected by their definition.\nfunc DefaultValuesOfCorrectTypeRule(context *ValidationContext) *ValidationRuleInstance {\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.VariableDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif varDefAST, ok := p.Node.(*ast.VariableDefinition); ok {\n\t\t\t\t\t\tvar (\n\t\t\t\t\t\t\tname         string\n\t\t\t\t\t\t\tdefaultValue = varDefAST.DefaultValue\n\t\t\t\t\t\t\tmessagesStr  string\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif varDefAST.Variable != nil && varDefAST.Variable.Name != nil {\n\t\t\t\t\t\t\tname = varDefAST.Variable.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tttype := context.InputType()\n\n\t\t\t\t\t\t// when input variable value must be nonNull, and set default value is unnecessary\n\t\t\t\t\t\tif ttype, ok := ttype.(*NonNull); ok && defaultValue != nil {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Variable \"$%v\" of type \"%v\" is required and will not use the default value. Perhaps you meant to use type \"%v\".`,\n\t\t\t\t\t\t\t\t\tname, ttype, ttype.OfType),\n\t\t\t\t\t\t\t\t[]ast.Node{defaultValue},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif isValid, messages := isValidLiteralValue(ttype, defaultValue); !isValid && defaultValue != nil {\n\t\t\t\t\t\t\tif len(messages) > 0 {\n\t\t\t\t\t\t\t\tmessagesStr = \"\\n\" + strings.Join(messages, \"\\n\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Variable \"$%v\" has invalid default value: %v.%v`,\n\t\t\t\t\t\t\t\t\tname, printer.Print(defaultValue), messagesStr),\n\t\t\t\t\t\t\t\t[]ast.Node{defaultValue},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.SelectionSet: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.FragmentDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\nfunc quoteStrings(slice []string) []string {\n\tquoted := []string{}\n\tfor _, s := range slice {\n\t\tquoted = append(quoted, fmt.Sprintf(`\"%v\"`, s))\n\t}\n\treturn quoted\n}\n\n// quotedOrList Given [ A, B, C ] return '\"A\", \"B\", or \"C\"'.\n// Notice oxford comma\nfunc quotedOrList(slice []string) string {\n\tmaxLength := 5\n\tif len(slice) == 0 {\n\t\treturn \"\"\n\t}\n\tquoted := quoteStrings(slice)\n\tif maxLength > len(quoted) {\n\t\tmaxLength = len(quoted)\n\t}\n\tif maxLength > 2 {\n\t\treturn fmt.Sprintf(\"%v, or %v\", strings.Join(quoted[0:maxLength-1], \", \"), quoted[maxLength-1])\n\t}\n\tif maxLength > 1 {\n\t\treturn fmt.Sprintf(\"%v or %v\", strings.Join(quoted[0:maxLength-1], \", \"), quoted[maxLength-1])\n\t}\n\treturn quoted[0]\n}\nfunc UndefinedFieldMessage(fieldName string, ttypeName string, suggestedTypeNames []string, suggestedFieldNames []string) string {\n\tmessage := fmt.Sprintf(`Cannot query field \"%v\" on type \"%v\".`, fieldName, ttypeName)\n\tif len(suggestedTypeNames) > 0 {\n\t\tmessage = fmt.Sprintf(`%v Did you mean to use an inline fragment on %v?`, message, quotedOrList(suggestedTypeNames))\n\t} else if len(suggestedFieldNames) > 0 {\n\t\tmessage = fmt.Sprintf(`%v Did you mean %v?`, message, quotedOrList(suggestedFieldNames))\n\t}\n\treturn message\n}\n\n// FieldsOnCorrectTypeRule Fields on correct type\n//\n// A GraphQL document is only valid if all fields selected are defined by the\n// parent type, or are an allowed meta field such as __typenamme\nfunc FieldsOnCorrectTypeRule(context *ValidationContext) *ValidationRuleInstance {\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Field: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tvar action = visitor.ActionNoChange\n\t\t\t\t\tif node, ok := p.Node.(*ast.Field); ok {\n\t\t\t\t\t\tvar ttype Composite\n\t\t\t\t\t\tif ttype = context.ParentType(); ttype == nil {\n\t\t\t\t\t\t\treturn action, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\tswitch ttype.(type) {\n\t\t\t\t\t\tcase *Object, *Interface, *Union:\n\t\t\t\t\t\t\tif reflect.ValueOf(ttype).IsNil() {\n\t\t\t\t\t\t\t\treturn action, nil\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfieldDef := context.FieldDef()\n\t\t\t\t\t\tif fieldDef == nil {\n\t\t\t\t\t\t\t// This field doesn't exist, lets look for suggestions.\n\t\t\t\t\t\t\tvar nodeName string\n\t\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\t\tnodeName = node.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// First determine if there are any suggested types to condition on.\n\t\t\t\t\t\t\tsuggestedTypeNames := getSuggestedTypeNames(context.Schema(), ttype, nodeName)\n\n\t\t\t\t\t\t\t// If there are no suggested types, then perhaps this was a typo?\n\t\t\t\t\t\t\tsuggestedFieldNames := []string{}\n\t\t\t\t\t\t\tif len(suggestedTypeNames) == 0 {\n\t\t\t\t\t\t\t\tsuggestedFieldNames = getSuggestedFieldNames(context.Schema(), ttype, nodeName)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tUndefinedFieldMessage(nodeName, ttype.Name(), suggestedTypeNames, suggestedFieldNames),\n\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn action, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// getSuggestedTypeNames Go through all of the implementations of type, as well as the interfaces\n// that they implement. If any of those types include the provided field,\n// suggest them, sorted by how often the type is referenced,  starting\n// with Interfaces.\nfunc getSuggestedTypeNames(schema *Schema, ttype Output, fieldName string) []string {\n\tvar (\n\t\tsuggestedObjectTypes = []string{}\n\t\tsuggestedInterfaces  = []*suggestedInterface{}\n\t\t// stores a map of interface name => index in suggestedInterfaces\n\t\tsuggestedInterfaceMap = map[string]int{}\n\t\t// stores a maps of object name => true to remove duplicates from results\n\t\tsuggestedObjectMap = map[string]bool{}\n\t)\n\tpossibleTypes := schema.PossibleTypes(ttype)\n\n\tfor _, possibleType := range possibleTypes {\n\t\tif field, ok := possibleType.Fields()[fieldName]; !ok || field == nil {\n\t\t\tcontinue\n\t\t}\n\t\t// This object type defines this field.\n\t\tsuggestedObjectTypes = append(suggestedObjectTypes, possibleType.Name())\n\t\tsuggestedObjectMap[possibleType.Name()] = true\n\n\t\tfor _, possibleInterface := range possibleType.Interfaces() {\n\t\t\tif field, ok := possibleInterface.Fields()[fieldName]; !ok || field == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// This interface type defines this field.\n\n\t\t\t// - find the index of the suggestedInterface and retrieving the interface\n\t\t\t// - increase count\n\t\t\tindex, ok := suggestedInterfaceMap[possibleInterface.Name()]\n\t\t\tif !ok {\n\t\t\t\tsuggestedInterfaces = append(suggestedInterfaces, &suggestedInterface{\n\t\t\t\t\tname:  possibleInterface.Name(),\n\t\t\t\t\tcount: 0,\n\t\t\t\t})\n\t\t\t\tindex = len(suggestedInterfaces) - 1\n\t\t\t\tsuggestedInterfaceMap[possibleInterface.Name()] = index\n\t\t\t}\n\t\t\tif index < len(suggestedInterfaces) {\n\t\t\t\ts := suggestedInterfaces[index]\n\t\t\t\tif s.name == possibleInterface.Name() {\n\t\t\t\t\ts.count++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// sort results (by count usage for interfaces, alphabetical order for objects)\n\tsort.Sort(suggestedInterfaceSortedSlice(suggestedInterfaces))\n\tsort.Sort(sort.StringSlice(suggestedObjectTypes))\n\n\t// return concatenated slices of both interface and object type names\n\t// and removing duplicates\n\t// ordered by: interface (sorted) and object (sorted)\n\tresults := []string{}\n\tfor _, s := range suggestedInterfaces {\n\t\tif _, ok := suggestedObjectMap[s.name]; !ok {\n\t\t\tresults = append(results, s.name)\n\n\t\t}\n\t}\n\tresults = append(results, suggestedObjectTypes...)\n\treturn results\n}\n\n// getSuggestedFieldNames For the field name provided, determine if there are any similar field names\n// that may be the result of a typo.\nfunc getSuggestedFieldNames(schema *Schema, ttype Output, fieldName string) []string {\n\n\tfields := FieldDefinitionMap{}\n\tswitch ttype := ttype.(type) {\n\tcase *Object:\n\t\tfields = ttype.Fields()\n\tcase *Interface:\n\t\tfields = ttype.Fields()\n\tdefault:\n\t\treturn []string{}\n\t}\n\n\tpossibleFieldNames := []string{}\n\tfor possibleFieldName := range fields {\n\t\tpossibleFieldNames = append(possibleFieldNames, possibleFieldName)\n\t}\n\treturn suggestionList(fieldName, possibleFieldNames)\n}\n\n// suggestedInterface an internal struct to sort interface by usage count\ntype suggestedInterface struct {\n\tname  string\n\tcount int\n}\ntype suggestedInterfaceSortedSlice []*suggestedInterface\n\nfunc (s suggestedInterfaceSortedSlice) Len() int {\n\treturn len(s)\n}\nfunc (s suggestedInterfaceSortedSlice) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\nfunc (s suggestedInterfaceSortedSlice) Less(i, j int) bool {\n\tif s[i].count == s[j].count {\n\t\treturn s[i].name < s[j].name\n\t}\n\treturn s[i].count > s[j].count\n}\n\n// FragmentsOnCompositeTypesRule Fragments on composite type\n//\n// Fragments use a type condition to determine if they apply, since fragments\n// can only be spread into a composite type (object, interface, or union), the\n// type condition must also be a composite type.\nfunc FragmentsOnCompositeTypesRule(context *ValidationContext) *ValidationRuleInstance {\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.InlineFragment: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.InlineFragment); ok {\n\t\t\t\t\t\tttype := context.Type()\n\t\t\t\t\t\tif node.TypeCondition != nil && ttype != nil && !IsCompositeType(ttype) {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Fragment cannot condition on non composite type \"%v\".`, ttype),\n\t\t\t\t\t\t\t\t[]ast.Node{node.TypeCondition},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.FragmentDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.FragmentDefinition); ok {\n\t\t\t\t\t\tttype := context.Type()\n\t\t\t\t\t\tif ttype != nil && !IsCompositeType(ttype) {\n\t\t\t\t\t\t\tnodeName := \"\"\n\t\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\t\tnodeName = node.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Fragment \"%v\" cannot condition on non composite type \"%v\".`, nodeName, printer.Print(node.TypeCondition)),\n\t\t\t\t\t\t\t\t[]ast.Node{node.TypeCondition},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\nfunc unknownArgMessage(argName string, fieldName string, parentTypeName string, suggestedArgs []string) string {\n\tmessage := fmt.Sprintf(`Unknown argument \"%v\" on field \"%v\" of type \"%v\".`, argName, fieldName, parentTypeName)\n\n\tif len(suggestedArgs) > 0 {\n\t\tmessage = fmt.Sprintf(`%v Did you mean %v?`, message, quotedOrList(suggestedArgs))\n\t}\n\n\treturn message\n}\n\nfunc unknownDirectiveArgMessage(argName string, directiveName string, suggestedArgs []string) string {\n\tmessage := fmt.Sprintf(`Unknown argument \"%v\" on directive \"@%v\".`, argName, directiveName)\n\n\tif len(suggestedArgs) > 0 {\n\t\tmessage = fmt.Sprintf(`%v Did you mean %v?`, message, quotedOrList(suggestedArgs))\n\t}\n\n\treturn message\n}\n\n// KnownArgumentNamesRule Known argument names\n//\n// A GraphQL field is only valid if all supplied arguments are defined by\n// that field.\nfunc KnownArgumentNamesRule(context *ValidationContext) *ValidationRuleInstance {\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Argument: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tvar action = visitor.ActionNoChange\n\t\t\t\t\tif node, ok := p.Node.(*ast.Argument); ok {\n\t\t\t\t\t\tvar argumentOf ast.Node\n\t\t\t\t\t\tif len(p.Ancestors) > 0 {\n\t\t\t\t\t\t\targumentOf = p.Ancestors[len(p.Ancestors)-1]\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif argumentOf == nil {\n\t\t\t\t\t\t\treturn action, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//  verify node, if the node's name exists in Arguments{Field, Directive}\n\t\t\t\t\t\tvar (\n\t\t\t\t\t\t\tfieldArgDef    *Argument\n\t\t\t\t\t\t\tfieldDef       = context.FieldDef()\n\t\t\t\t\t\t\tdirective      = context.Directive()\n\t\t\t\t\t\t\targNames       []string\n\t\t\t\t\t\t\tparentTypeName string\n\t\t\t\t\t\t)\n\t\t\t\t\t\tswitch argumentOf.GetKind() {\n\t\t\t\t\t\tcase kinds.Field:\n\t\t\t\t\t\t\t// get field definition\n\t\t\t\t\t\t\tif fieldDef == nil {\n\t\t\t\t\t\t\t\treturn action, nil\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor _, arg := range fieldDef.Args {\n\t\t\t\t\t\t\t\tif arg.Name() == node.Name.Value {\n\t\t\t\t\t\t\t\t\tfieldArgDef = arg\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\targNames = append(argNames, arg.Name())\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif fieldArgDef == nil {\n\t\t\t\t\t\t\t\tparentType := context.ParentType()\n\t\t\t\t\t\t\t\tif parentType != nil {\n\t\t\t\t\t\t\t\t\tparentTypeName = parentType.Name()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\tunknownArgMessage(\n\t\t\t\t\t\t\t\t\t\tnode.Name.Value,\n\t\t\t\t\t\t\t\t\t\tfieldDef.Name,\n\t\t\t\t\t\t\t\t\t\tparentTypeName, suggestionList(node.Name.Value, argNames),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tcase kinds.Directive:\n\t\t\t\t\t\t\tif directive = context.Directive(); directive == nil {\n\t\t\t\t\t\t\t\treturn action, nil\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor _, arg := range directive.Args {\n\t\t\t\t\t\t\t\tif arg.Name() == node.Name.Value {\n\t\t\t\t\t\t\t\t\tfieldArgDef = arg\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\targNames = append(argNames, arg.Name())\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif fieldArgDef == nil {\n\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\tunknownDirectiveArgMessage(\n\t\t\t\t\t\t\t\t\t\tnode.Name.Value,\n\t\t\t\t\t\t\t\t\t\tdirective.Name,\n\t\t\t\t\t\t\t\t\t\tsuggestionList(node.Name.Value, argNames),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn action, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\nfunc MisplaceDirectiveMessage(directiveName string, location string) string {\n\treturn fmt.Sprintf(`Directive \"%v\" may not be used on %v.`, directiveName, location)\n}\n\n// KnownDirectivesRule Known directives\n//\n// A GraphQL document is only valid if all `@directives` are known by the\n// schema and legally positioned.\nfunc KnownDirectivesRule(context *ValidationContext) *ValidationRuleInstance {\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Directive: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tvar action = visitor.ActionNoChange\n\t\t\t\t\tvar result interface{}\n\t\t\t\t\tif node, ok := p.Node.(*ast.Directive); ok {\n\n\t\t\t\t\t\tnodeName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\tnodeName = node.Name.Value\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar directiveDef *Directive\n\t\t\t\t\t\tfor _, def := range context.Schema().Directives() {\n\t\t\t\t\t\t\tif def.Name == nodeName {\n\t\t\t\t\t\t\t\tdirectiveDef = def\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif directiveDef == nil {\n\t\t\t\t\t\t\treturn reportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Unknown directive \"%v\".`, nodeName),\n\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcandidateLocation := getDirectiveLocationForASTPath(p.Ancestors)\n\n\t\t\t\t\t\tdirectiveHasLocation := false\n\t\t\t\t\t\tfor _, loc := range directiveDef.Locations {\n\t\t\t\t\t\t\tif loc == candidateLocation {\n\t\t\t\t\t\t\t\tdirectiveHasLocation = true\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif candidateLocation == \"\" {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tMisplaceDirectiveMessage(nodeName, node.GetKind()),\n\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else if !directiveHasLocation {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tMisplaceDirectiveMessage(nodeName, candidateLocation),\n\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn action, result\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\nfunc getDirectiveLocationForASTPath(ancestors []ast.Node) string {\n\tvar appliedTo ast.Node\n\tif len(ancestors) > 0 {\n\t\tappliedTo = ancestors[len(ancestors)-1]\n\t}\n\tif appliedTo == nil {\n\t\treturn \"\"\n\t}\n\tkind := appliedTo.GetKind()\n\tif kind == kinds.OperationDefinition {\n\t\tappliedTo, _ := appliedTo.(*ast.OperationDefinition)\n\t\tif appliedTo.Operation == ast.OperationTypeQuery {\n\t\t\treturn DirectiveLocationQuery\n\t\t}\n\t\tif appliedTo.Operation == ast.OperationTypeMutation {\n\t\t\treturn DirectiveLocationMutation\n\t\t}\n\t\tif appliedTo.Operation == ast.OperationTypeSubscription {\n\t\t\treturn DirectiveLocationSubscription\n\t\t}\n\t}\n\tif kind == kinds.Field {\n\t\treturn DirectiveLocationField\n\t}\n\tif kind == kinds.FragmentSpread {\n\t\treturn DirectiveLocationFragmentSpread\n\t}\n\tif kind == kinds.InlineFragment {\n\t\treturn DirectiveLocationInlineFragment\n\t}\n\tif kind == kinds.FragmentDefinition {\n\t\treturn DirectiveLocationFragmentDefinition\n\t}\n\tif kind == kinds.SchemaDefinition {\n\t\treturn DirectiveLocationSchema\n\t}\n\tif kind == kinds.ScalarDefinition {\n\t\treturn DirectiveLocationScalar\n\t}\n\tif kind == kinds.ObjectDefinition {\n\t\treturn DirectiveLocationObject\n\t}\n\tif kind == kinds.FieldDefinition {\n\t\treturn DirectiveLocationFieldDefinition\n\t}\n\tif kind == kinds.InterfaceDefinition {\n\t\treturn DirectiveLocationInterface\n\t}\n\tif kind == kinds.UnionDefinition {\n\t\treturn DirectiveLocationUnion\n\t}\n\tif kind == kinds.EnumDefinition {\n\t\treturn DirectiveLocationEnum\n\t}\n\tif kind == kinds.EnumValueDefinition {\n\t\treturn DirectiveLocationEnumValue\n\t}\n\tif kind == kinds.InputObjectDefinition {\n\t\treturn DirectiveLocationInputObject\n\t}\n\tif kind == kinds.InputValueDefinition {\n\t\tvar parentNode ast.Node\n\t\tif len(ancestors) >= 3 {\n\t\t\tparentNode = ancestors[len(ancestors)-3]\n\t\t}\n\t\tif parentNode.GetKind() == kinds.InputObjectDefinition {\n\t\t\treturn DirectiveLocationInputFieldDefinition\n\t\t} else {\n\t\t\treturn DirectiveLocationArgumentDefinition\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// KnownFragmentNamesRule Known fragment names\n//\n// A GraphQL document is only valid if all `...Fragment` fragment spreads refer\n// to fragments defined in the same document.\nfunc KnownFragmentNamesRule(context *ValidationContext) *ValidationRuleInstance {\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.FragmentSpread: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tvar action = visitor.ActionNoChange\n\t\t\t\t\tvar result interface{}\n\t\t\t\t\tif node, ok := p.Node.(*ast.FragmentSpread); ok {\n\n\t\t\t\t\t\tfragmentName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\tfragmentName = node.Name.Value\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfragment := context.Fragment(fragmentName)\n\t\t\t\t\t\tif fragment == nil {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Unknown fragment \"%v\".`, fragmentName),\n\t\t\t\t\t\t\t\t[]ast.Node{node.Name},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn action, result\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\nfunc unknownTypeMessage(typeName string, suggestedTypes []string) string {\n\tmessage := fmt.Sprintf(`Unknown type \"%v\".`, typeName)\n\tif len(suggestedTypes) > 0 {\n\t\tmessage = fmt.Sprintf(`%v Did you mean %v?`, message, quotedOrList(suggestedTypes))\n\t}\n\n\treturn message\n}\n\n// KnownTypeNamesRule Known type names\n//\n// A GraphQL document is only valid if referenced types (specifically\n// variable definitions and fragment conditions) are defined by the type schema.\nfunc KnownTypeNamesRule(context *ValidationContext) *ValidationRuleInstance {\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.ObjectDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.InterfaceDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.UnionDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.InputObjectDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.Named: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.Named); ok {\n\t\t\t\t\t\ttypeNameValue := \"\"\n\t\t\t\t\t\ttypeName := node.Name\n\t\t\t\t\t\tif typeName != nil {\n\t\t\t\t\t\t\ttypeNameValue = typeName.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tttype := context.Schema().Type(typeNameValue)\n\t\t\t\t\t\tif ttype == nil {\n\t\t\t\t\t\t\tsuggestedTypes := []string{}\n\t\t\t\t\t\t\tfor key := range context.Schema().TypeMap() {\n\t\t\t\t\t\t\t\tsuggestedTypes = append(suggestedTypes, key)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tunknownTypeMessage(typeNameValue, suggestionList(typeNameValue, suggestedTypes)),\n\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// LoneAnonymousOperationRule Lone anonymous operation\n//\n// A GraphQL document is only valid if when it contains an anonymous operation\n// (the query short-hand) that it contains only that one operation definition.\nfunc LoneAnonymousOperationRule(context *ValidationContext) *ValidationRuleInstance {\n\tvar operationCount = 0\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Document: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.Document); ok {\n\t\t\t\t\t\toperationCount = 0\n\t\t\t\t\t\tfor _, definition := range node.Definitions {\n\t\t\t\t\t\t\tif definition.GetKind() == kinds.OperationDefinition {\n\t\t\t\t\t\t\t\toperationCount++\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.OperationDefinition); ok {\n\t\t\t\t\t\tif node.Name == nil && operationCount > 1 {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t`This anonymous operation must be the only defined operation.`,\n\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\nfunc CycleErrorMessage(fragName string, spreadNames []string) string {\n\tvia := \"\"\n\tif len(spreadNames) > 0 {\n\t\tvia = \" via \" + strings.Join(spreadNames, \", \")\n\t}\n\treturn fmt.Sprintf(`Cannot spread fragment \"%v\" within itself%v.`, fragName, via)\n}\n\n// NoFragmentCyclesRule No fragment cycles\nfunc NoFragmentCyclesRule(context *ValidationContext) *ValidationRuleInstance {\n\n\t// Tracks already visited fragments to maintain O(N) and to ensure that cycles\n\t// are not redundantly reported.\n\tvisitedFrags := map[string]bool{}\n\n\t// Array of AST nodes used to produce meaningful errors\n\tspreadPath := []*ast.FragmentSpread{}\n\n\t// Position in the spread path\n\tspreadPathIndexByName := map[string]int{}\n\n\t// This does a straight-forward DFS to find cycles.\n\t// It does not terminate when a cycle was found but continues to explore\n\t// the graph to find all possible cycles.\n\tvar detectCycleRecursive func(fragment *ast.FragmentDefinition)\n\tdetectCycleRecursive = func(fragment *ast.FragmentDefinition) {\n\n\t\tfragmentName := \"\"\n\t\tif fragment.Name != nil {\n\t\t\tfragmentName = fragment.Name.Value\n\t\t}\n\t\tvisitedFrags[fragmentName] = true\n\n\t\tspreadNodes := context.FragmentSpreads(fragment.SelectionSet)\n\t\tif len(spreadNodes) == 0 {\n\t\t\treturn\n\t\t}\n\n\t\tspreadPathIndexByName[fragmentName] = len(spreadPath)\n\n\t\tfor _, spreadNode := range spreadNodes {\n\n\t\t\tspreadName := \"\"\n\t\t\tif spreadNode.Name != nil {\n\t\t\t\tspreadName = spreadNode.Name.Value\n\t\t\t}\n\t\t\tcycleIndex, ok := spreadPathIndexByName[spreadName]\n\t\t\tif !ok {\n\t\t\t\tspreadPath = append(spreadPath, spreadNode)\n\t\t\t\tif visited, ok := visitedFrags[spreadName]; !ok || !visited {\n\t\t\t\t\tspreadFragment := context.Fragment(spreadName)\n\t\t\t\t\tif spreadFragment != nil {\n\t\t\t\t\t\tdetectCycleRecursive(spreadFragment)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tspreadPath = spreadPath[:len(spreadPath)-1]\n\t\t\t} else {\n\t\t\t\tcyclePath := spreadPath[cycleIndex:]\n\n\t\t\t\tspreadNames := []string{}\n\t\t\t\tfor _, s := range cyclePath {\n\t\t\t\t\tname := \"\"\n\t\t\t\t\tif s.Name != nil {\n\t\t\t\t\t\tname = s.Name.Value\n\t\t\t\t\t}\n\t\t\t\t\tspreadNames = append(spreadNames, name)\n\t\t\t\t}\n\n\t\t\t\tnodes := []ast.Node{}\n\t\t\t\tfor _, c := range cyclePath {\n\t\t\t\t\tnodes = append(nodes, c)\n\t\t\t\t}\n\t\t\t\tnodes = append(nodes, spreadNode)\n\n\t\t\t\treportError(\n\t\t\t\t\tcontext,\n\t\t\t\t\tCycleErrorMessage(spreadName, spreadNames),\n\t\t\t\t\tnodes,\n\t\t\t\t)\n\t\t\t}\n\n\t\t}\n\t\tdelete(spreadPathIndexByName, fragmentName)\n\n\t}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.FragmentDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.FragmentDefinition); ok && node != nil {\n\t\t\t\t\t\tnodeName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\tnodeName = node.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif _, ok := visitedFrags[nodeName]; !ok {\n\t\t\t\t\t\t\tdetectCycleRecursive(node)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\nfunc UndefinedVarMessage(varName string, opName string) string {\n\tif opName != \"\" {\n\t\treturn fmt.Sprintf(`Variable \"$%v\" is not defined by operation \"%v\".`, varName, opName)\n\t}\n\treturn fmt.Sprintf(`Variable \"$%v\" is not defined.`, varName)\n}\n\n// NoUndefinedVariablesRule No undefined variables\n//\n// A GraphQL operation is only valid if all variables encountered, both directly\n// and via fragment spreads, are defined by that operation.\nfunc NoUndefinedVariablesRule(context *ValidationContext) *ValidationRuleInstance {\n\tvar variableNameDefined = map[string]bool{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tvariableNameDefined = map[string]bool{}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif operation, ok := p.Node.(*ast.OperationDefinition); ok && operation != nil {\n\t\t\t\t\t\tusages := context.RecursiveVariableUsages(operation)\n\n\t\t\t\t\t\tfor _, usage := range usages {\n\t\t\t\t\t\t\tif usage == nil {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif usage.Node == nil {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvarName := \"\"\n\t\t\t\t\t\t\tif usage.Node.Name != nil {\n\t\t\t\t\t\t\t\tvarName = usage.Node.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\topName := \"\"\n\t\t\t\t\t\t\tif operation.Name != nil {\n\t\t\t\t\t\t\t\topName = operation.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif res, ok := variableNameDefined[varName]; !ok || !res {\n\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\tUndefinedVarMessage(varName, opName),\n\t\t\t\t\t\t\t\t\t[]ast.Node{usage.Node, operation},\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.VariableDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.VariableDefinition); ok && node != nil {\n\t\t\t\t\t\tvariableName := \"\"\n\t\t\t\t\t\tif node.Variable != nil && node.Variable.Name != nil {\n\t\t\t\t\t\t\tvariableName = node.Variable.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvariableNameDefined[variableName] = true\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// NoUnusedFragmentsRule No unused fragments\n//\n// A GraphQL document is only valid if all fragment definitions are spread\n// within operations, or spread within other fragments spread within operations.\nfunc NoUnusedFragmentsRule(context *ValidationContext) *ValidationRuleInstance {\n\n\tvar fragmentDefs = []*ast.FragmentDefinition{}\n\tvar operationDefs = []*ast.OperationDefinition{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.OperationDefinition); ok && node != nil {\n\t\t\t\t\t\toperationDefs = append(operationDefs, node)\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.FragmentDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.FragmentDefinition); ok && node != nil {\n\t\t\t\t\t\tfragmentDefs = append(fragmentDefs, node)\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.Document: {\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tfragmentNameUsed := map[string]bool{}\n\t\t\t\t\tfor _, operation := range operationDefs {\n\t\t\t\t\t\tfragments := context.RecursivelyReferencedFragments(operation)\n\t\t\t\t\t\tfor _, fragment := range fragments {\n\t\t\t\t\t\t\tfragName := \"\"\n\t\t\t\t\t\t\tif fragment.Name != nil {\n\t\t\t\t\t\t\t\tfragName = fragment.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfragmentNameUsed[fragName] = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tfor _, def := range fragmentDefs {\n\t\t\t\t\t\tdefName := \"\"\n\t\t\t\t\t\tif def.Name != nil {\n\t\t\t\t\t\t\tdefName = def.Name.Value\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tisFragNameUsed, ok := fragmentNameUsed[defName]\n\t\t\t\t\t\tif !ok || isFragNameUsed != true {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Fragment \"%v\" is never used.`, defName),\n\t\t\t\t\t\t\t\t[]ast.Node{def},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\nfunc UnusedVariableMessage(varName string, opName string) string {\n\tif opName != \"\" {\n\t\treturn fmt.Sprintf(`Variable \"$%v\" is never used in operation \"%v\".`, varName, opName)\n\t}\n\treturn fmt.Sprintf(`Variable \"$%v\" is never used.`, varName)\n}\n\n// NoUnusedVariablesRule No unused variables\n//\n// A GraphQL operation is only valid if all variables defined by an operation\n// are used, either directly or within a spread fragment.\nfunc NoUnusedVariablesRule(context *ValidationContext) *ValidationRuleInstance {\n\n\tvar variableDefs = []*ast.VariableDefinition{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tvariableDefs = []*ast.VariableDefinition{}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif operation, ok := p.Node.(*ast.OperationDefinition); ok && operation != nil {\n\t\t\t\t\t\tvariableNameUsed := map[string]bool{}\n\t\t\t\t\t\tusages := context.RecursiveVariableUsages(operation)\n\n\t\t\t\t\t\tfor _, usage := range usages {\n\t\t\t\t\t\t\tvarName := \"\"\n\t\t\t\t\t\t\tif usage != nil && usage.Node != nil && usage.Node.Name != nil {\n\t\t\t\t\t\t\t\tvarName = usage.Node.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif varName != \"\" {\n\t\t\t\t\t\t\t\tvariableNameUsed[varName] = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor _, variableDef := range variableDefs {\n\t\t\t\t\t\t\tvariableName := \"\"\n\t\t\t\t\t\t\tif variableDef != nil && variableDef.Variable != nil && variableDef.Variable.Name != nil {\n\t\t\t\t\t\t\t\tvariableName = variableDef.Variable.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\topName := \"\"\n\t\t\t\t\t\t\tif operation.Name != nil {\n\t\t\t\t\t\t\t\topName = operation.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif res, ok := variableNameUsed[variableName]; !ok || !res {\n\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\tUnusedVariableMessage(variableName, opName),\n\t\t\t\t\t\t\t\t\t[]ast.Node{variableDef},\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.VariableDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif def, ok := p.Node.(*ast.VariableDefinition); ok && def != nil {\n\t\t\t\t\t\tvariableDefs = append(variableDefs, def)\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\nfunc getFragmentType(context *ValidationContext, name string) Type {\n\tfrag := context.Fragment(name)\n\tif frag == nil {\n\t\treturn nil\n\t}\n\tttype, _ := typeFromAST(*context.Schema(), frag.TypeCondition)\n\treturn ttype\n}\n\nfunc doTypesOverlap(schema *Schema, t1 Type, t2 Type) bool {\n\tif t1 == t2 {\n\t\treturn true\n\t}\n\tif _, ok := t1.(*Object); ok {\n\t\tif _, ok := t2.(*Object); ok {\n\t\t\treturn false\n\t\t}\n\t\tif t2, ok := t2.(Abstract); ok {\n\t\t\tfor _, ttype := range schema.PossibleTypes(t2) {\n\t\t\t\tif ttype == t1 {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t}\n\tif t1, ok := t1.(Abstract); ok {\n\t\tif _, ok := t2.(*Object); ok {\n\t\t\tfor _, ttype := range schema.PossibleTypes(t1) {\n\t\t\t\tif ttype == t2 {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t\tt1TypeNames := map[string]bool{}\n\t\tfor _, ttype := range schema.PossibleTypes(t1) {\n\t\t\tt1TypeNames[ttype.Name()] = true\n\t\t}\n\t\tif t2, ok := t2.(Abstract); ok {\n\t\t\tfor _, ttype := range schema.PossibleTypes(t2) {\n\t\t\t\tif hasT1TypeName, _ := t1TypeNames[ttype.Name()]; hasT1TypeName {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t}\n\treturn false\n}\n\n// PossibleFragmentSpreadsRule Possible fragment spread\n//\n// A fragment spread is only valid if the type condition could ever possibly\n// be true: if there is a non-empty intersection of the possible parent types,\n// and possible types which pass the type condition.\nfunc PossibleFragmentSpreadsRule(context *ValidationContext) *ValidationRuleInstance {\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.InlineFragment: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.InlineFragment); ok && node != nil {\n\t\t\t\t\t\tfragType := context.Type()\n\t\t\t\t\t\tparentType, _ := context.ParentType().(Type)\n\n\t\t\t\t\t\tif fragType != nil && parentType != nil && !doTypesOverlap(context.Schema(), fragType, parentType) {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Fragment cannot be spread here as objects of `+\n\t\t\t\t\t\t\t\t\t`type \"%v\" can never be of type \"%v\".`, parentType, fragType),\n\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.FragmentSpread: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.FragmentSpread); ok && node != nil {\n\t\t\t\t\t\tfragName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\tfragName = node.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfragType := getFragmentType(context, fragName)\n\t\t\t\t\t\tparentType, _ := context.ParentType().(Type)\n\t\t\t\t\t\tif fragType != nil && parentType != nil && !doTypesOverlap(context.Schema(), fragType, parentType) {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Fragment \"%v\" cannot be spread here as objects of `+\n\t\t\t\t\t\t\t\t\t`type \"%v\" can never be of type \"%v\".`, fragName, parentType, fragType),\n\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// ProvidedNonNullArgumentsRule Provided required arguments\n//\n// A field or directive is only valid if all required (non-null) field arguments\n// have been provided.\nfunc ProvidedNonNullArgumentsRule(context *ValidationContext) *ValidationRuleInstance {\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Field: {\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\t// Validate on leave to allow for deeper errors to appear first.\n\t\t\t\t\tif fieldAST, ok := p.Node.(*ast.Field); ok && fieldAST != nil {\n\t\t\t\t\t\tfieldDef := context.FieldDef()\n\t\t\t\t\t\tif fieldDef == nil {\n\t\t\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\targASTs := fieldAST.Arguments\n\n\t\t\t\t\t\targASTMap := map[string]*ast.Argument{}\n\t\t\t\t\t\tfor _, arg := range argASTs {\n\t\t\t\t\t\t\tname := \"\"\n\t\t\t\t\t\t\tif arg.Name != nil {\n\t\t\t\t\t\t\t\tname = arg.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\targASTMap[name] = arg\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor _, argDef := range fieldDef.Args {\n\t\t\t\t\t\t\targAST, _ := argASTMap[argDef.Name()]\n\t\t\t\t\t\t\tif argAST == nil {\n\t\t\t\t\t\t\t\tif argDefType, ok := argDef.Type.(*NonNull); ok {\n\t\t\t\t\t\t\t\t\tfieldName := \"\"\n\t\t\t\t\t\t\t\t\tif fieldAST.Name != nil {\n\t\t\t\t\t\t\t\t\t\tfieldName = fieldAST.Name.Value\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(`Field \"%v\" argument \"%v\" of type \"%v\" `+\n\t\t\t\t\t\t\t\t\t\t\t`is required but not provided.`, fieldName, argDef.Name(), argDefType),\n\t\t\t\t\t\t\t\t\t\t[]ast.Node{fieldAST},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.Directive: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\t// Validate on leave to allow for deeper errors to appear first.\n\n\t\t\t\t\tif directiveAST, ok := p.Node.(*ast.Directive); ok && directiveAST != nil {\n\t\t\t\t\t\tdirectiveDef := context.Directive()\n\t\t\t\t\t\tif directiveDef == nil {\n\t\t\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\targASTs := directiveAST.Arguments\n\n\t\t\t\t\t\targASTMap := map[string]*ast.Argument{}\n\t\t\t\t\t\tfor _, arg := range argASTs {\n\t\t\t\t\t\t\tname := \"\"\n\t\t\t\t\t\t\tif arg.Name != nil {\n\t\t\t\t\t\t\t\tname = arg.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\targASTMap[name] = arg\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor _, argDef := range directiveDef.Args {\n\t\t\t\t\t\t\targAST, _ := argASTMap[argDef.Name()]\n\t\t\t\t\t\t\tif argAST == nil {\n\t\t\t\t\t\t\t\tif argDefType, ok := argDef.Type.(*NonNull); ok {\n\t\t\t\t\t\t\t\t\tdirectiveName := \"\"\n\t\t\t\t\t\t\t\t\tif directiveAST.Name != nil {\n\t\t\t\t\t\t\t\t\t\tdirectiveName = directiveAST.Name.Value\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(`Directive \"@%v\" argument \"%v\" of type `+\n\t\t\t\t\t\t\t\t\t\t\t`\"%v\" is required but not provided.`, directiveName, argDef.Name(), argDefType),\n\t\t\t\t\t\t\t\t\t\t[]ast.Node{directiveAST},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// ScalarLeafsRule Scalar leafs\n//\n// A GraphQL document is valid only if all leaf fields (fields without\n// sub selections) are of scalar or enum types.\nfunc ScalarLeafsRule(context *ValidationContext) *ValidationRuleInstance {\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Field: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.Field); ok && node != nil {\n\t\t\t\t\t\tnodeName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\tnodeName = node.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tttype := context.Type()\n\t\t\t\t\t\tif ttype != nil {\n\t\t\t\t\t\t\tif IsLeafType(ttype) {\n\t\t\t\t\t\t\t\tif node.SelectionSet != nil {\n\t\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(`Field \"%v\" of type \"%v\" must not have a sub selection.`, nodeName, ttype),\n\t\t\t\t\t\t\t\t\t\t[]ast.Node{node.SelectionSet},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if node.SelectionSet == nil {\n\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\tfmt.Sprintf(`Field \"%v\" of type \"%v\" must have a sub selection.`, nodeName, ttype),\n\t\t\t\t\t\t\t\t\t[]ast.Node{node},\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// UniqueArgumentNamesRule Unique argument names\n//\n// A GraphQL field or directive is only valid if all supplied arguments are\n// uniquely named.\nfunc UniqueArgumentNamesRule(context *ValidationContext) *ValidationRuleInstance {\n\tknownArgNames := map[string]*ast.Name{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.Field: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tknownArgNames = map[string]*ast.Name{}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.Directive: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tknownArgNames = map[string]*ast.Name{}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.Argument: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.Argument); ok {\n\t\t\t\t\t\targName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\targName = node.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif nameAST, ok := knownArgNames[argName]; ok {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`There can be only one argument named \"%v\".`, argName),\n\t\t\t\t\t\t\t\t[]ast.Node{nameAST, node.Name},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tknownArgNames[argName] = node.Name\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// UniqueFragmentNamesRule Unique fragment names\n//\n// A GraphQL document is only valid if all defined fragments have unique names.\nfunc UniqueFragmentNamesRule(context *ValidationContext) *ValidationRuleInstance {\n\tknownFragmentNames := map[string]*ast.Name{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.FragmentDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.FragmentDefinition); ok && node != nil {\n\t\t\t\t\t\tfragmentName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\tfragmentName = node.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif nameAST, ok := knownFragmentNames[fragmentName]; ok {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`There can only be one fragment named \"%v\".`, fragmentName),\n\t\t\t\t\t\t\t\t[]ast.Node{nameAST, node.Name},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tknownFragmentNames[fragmentName] = node.Name\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// UniqueInputFieldNamesRule Unique input field names\n//\n// A GraphQL input object value is only valid if all supplied fields are\n// uniquely named.\nfunc UniqueInputFieldNamesRule(context *ValidationContext) *ValidationRuleInstance {\n\tknownNameStack := []map[string]*ast.Name{}\n\tknownNames := map[string]*ast.Name{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.ObjectValue: {\n\t\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tknownNameStack = append(knownNameStack, knownNames)\n\t\t\t\t\tknownNames = map[string]*ast.Name{}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\t// pop\n\t\t\t\t\tknownNames, knownNameStack = knownNameStack[len(knownNameStack)-1], knownNameStack[:len(knownNameStack)-1]\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.ObjectField: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.ObjectField); ok {\n\t\t\t\t\t\tfieldName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\tfieldName = node.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif knownNameAST, ok := knownNames[fieldName]; ok {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`There can be only one input field named \"%v\".`, fieldName),\n\t\t\t\t\t\t\t\t[]ast.Node{knownNameAST, node.Name},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tknownNames[fieldName] = node.Name\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// UniqueOperationNamesRule Unique operation names\n//\n// A GraphQL document is only valid if all defined operations have unique names.\nfunc UniqueOperationNamesRule(context *ValidationContext) *ValidationRuleInstance {\n\tknownOperationNames := make(map[string]ast.Node)\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.OperationDefinition); ok && node != nil {\n\t\t\t\t\t\toperationName := \"\"\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\toperationName = node.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar errNode ast.Node = node\n\t\t\t\t\t\tif node.Name != nil {\n\t\t\t\t\t\t\terrNode = node.Name\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif nameAST, ok := knownOperationNames[operationName]; ok {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`There can only be one operation named \"%v\".`, operationName),\n\t\t\t\t\t\t\t\t[]ast.Node{nameAST, errNode},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tknownOperationNames[operationName] = errNode\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.FragmentDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// UniqueVariableNamesRule Unique variable names\n//\n// A GraphQL operation is only valid if all its variables are uniquely named.\nfunc UniqueVariableNamesRule(context *ValidationContext) *ValidationRuleInstance {\n\tknownVariableNames := map[string]*ast.Name{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.OperationDefinition); ok && node != nil {\n\t\t\t\t\t\tknownVariableNames = map[string]*ast.Name{}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.VariableDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.VariableDefinition); ok && node != nil {\n\t\t\t\t\t\tvariableName := \"\"\n\t\t\t\t\t\tvar variableNameAST *ast.Name\n\t\t\t\t\t\tif node.Variable != nil && node.Variable.Name != nil {\n\t\t\t\t\t\t\tvariableNameAST = node.Variable.Name\n\t\t\t\t\t\t\tvariableName = node.Variable.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif nameAST, ok := knownVariableNames[variableName]; ok {\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`There can only be one variable named \"%v\".`, variableName),\n\t\t\t\t\t\t\t\t[]ast.Node{nameAST, variableNameAST},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tknownVariableNames[variableName] = variableNameAST\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// VariablesAreInputTypesRule Variables are input types\n//\n// A GraphQL operation is only valid if all the variables it defines are of\n// input types (scalar, enum, or input object).\nfunc VariablesAreInputTypesRule(context *ValidationContext) *ValidationRuleInstance {\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.VariableDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.VariableDefinition); ok && node != nil {\n\t\t\t\t\t\tttype, _ := typeFromAST(*context.Schema(), node.Type)\n\n\t\t\t\t\t\t// If the variable type is not an input type, return an error.\n\t\t\t\t\t\tif ttype != nil && !IsInputType(ttype) {\n\t\t\t\t\t\t\tvariableName := \"\"\n\t\t\t\t\t\t\tif node.Variable != nil && node.Variable.Name != nil {\n\t\t\t\t\t\t\t\tvariableName = node.Variable.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\tfmt.Sprintf(`Variable \"$%v\" cannot be non-input type \"%v\".`,\n\t\t\t\t\t\t\t\t\tvariableName, printer.Print(node.Type)),\n\t\t\t\t\t\t\t\t[]ast.Node{node.Type},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// If a variable definition has a default value, it's effectively non-null.\nfunc effectiveType(varType Type, varDef *ast.VariableDefinition) Type {\n\tif varDef.DefaultValue == nil {\n\t\treturn varType\n\t}\n\tif _, ok := varType.(*NonNull); ok {\n\t\treturn varType\n\t}\n\treturn NewNonNull(varType)\n}\n\n// VariablesInAllowedPositionRule Variables passed to field arguments conform to type\nfunc VariablesInAllowedPositionRule(context *ValidationContext) *ValidationRuleInstance {\n\n\tvarDefMap := map[string]*ast.VariableDefinition{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.OperationDefinition: {\n\t\t\t\tEnter: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tvarDefMap = map[string]*ast.VariableDefinition{}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t\tLeave: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif operation, ok := p.Node.(*ast.OperationDefinition); ok {\n\n\t\t\t\t\t\tusages := context.RecursiveVariableUsages(operation)\n\t\t\t\t\t\tfor _, usage := range usages {\n\t\t\t\t\t\t\tvarName := \"\"\n\t\t\t\t\t\t\tif usage != nil && usage.Node != nil && usage.Node.Name != nil {\n\t\t\t\t\t\t\t\tvarName = usage.Node.Name.Value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvarDef, _ := varDefMap[varName]\n\t\t\t\t\t\t\tif varDef != nil && usage.Type != nil {\n\t\t\t\t\t\t\t\tvarType, err := typeFromAST(*context.Schema(), varDef.Type)\n\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\tvarType = nil\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif varType != nil && !isTypeSubTypeOf(context.Schema(), effectiveType(varType, varDef), usage.Type) {\n\t\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(`Variable \"$%v\" of type \"%v\" used in position `+\n\t\t\t\t\t\t\t\t\t\t\t`expecting type \"%v\".`, varName, varType, usage.Type),\n\t\t\t\t\t\t\t\t\t\t[]ast.Node{varDef, usage.Node},\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.VariableDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif varDefAST, ok := p.Node.(*ast.VariableDefinition); ok {\n\t\t\t\t\t\tdefName := \"\"\n\t\t\t\t\t\tif varDefAST.Variable != nil && varDefAST.Variable.Name != nil {\n\t\t\t\t\t\t\tdefName = varDefAST.Variable.Name.Value\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif defName != \"\" {\n\t\t\t\t\t\t\tvarDefMap[defName] = varDefAST\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n// Utility for validators which determines if a value literal AST is valid given\n// an input type.\n//\n// Note that this only validates literal values, variables are assumed to\n// provide values of the correct type.\nfunc isValidLiteralValue(ttype Input, valueAST ast.Value) (bool, []string) {\n\tif _, ok := ttype.(*NonNull); !ok {\n\t\tif valueAST == nil {\n\t\t\treturn true, nil\n\t\t}\n\n\t\t// This function only tests literals, and assumes variables will provide\n\t\t// values of the correct type.\n\t\tif valueAST.GetKind() == kinds.Variable {\n\t\t\treturn true, nil\n\t\t}\n\t}\n\tswitch ttype := ttype.(type) {\n\tcase *NonNull:\n\t\t// A value must be provided if the type is non-null.\n\t\tif e := ttype.Error(); e != nil {\n\t\t\treturn false, []string{e.Error()}\n\t\t}\n\t\tif valueAST == nil {\n\t\t\tif ttype.OfType.Name() != \"\" {\n\t\t\t\treturn false, []string{fmt.Sprintf(`Expected \"%v!\", found null.`, ttype.OfType.Name())}\n\t\t\t}\n\t\t\treturn false, []string{\"Expected non-null value, found null.\"}\n\t\t}\n\t\tofType, _ := ttype.OfType.(Input)\n\t\treturn isValidLiteralValue(ofType, valueAST)\n\tcase *List:\n\t\t// Lists accept a non-list value as a list of one.\n\t\titemType, _ := ttype.OfType.(Input)\n\t\tif valueAST, ok := valueAST.(*ast.ListValue); ok {\n\t\t\tmessagesReduce := []string{}\n\t\t\tfor _, value := range valueAST.Values {\n\t\t\t\t_, messages := isValidLiteralValue(itemType, value)\n\t\t\t\tfor idx, message := range messages {\n\t\t\t\t\tmessagesReduce = append(messagesReduce, fmt.Sprintf(`In element #%v: %v`, idx+1, message))\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (len(messagesReduce) == 0), messagesReduce\n\t\t}\n\t\treturn isValidLiteralValue(itemType, valueAST)\n\tcase *InputObject:\n\t\t// Input objects check each defined field and look for undefined fields.\n\t\tvalueAST, ok := valueAST.(*ast.ObjectValue)\n\t\tif !ok {\n\t\t\treturn false, []string{fmt.Sprintf(`Expected \"%v\", found not an object.`, ttype.Name())}\n\t\t}\n\t\tfields := ttype.Fields()\n\t\tmessagesReduce := []string{}\n\n\t\t// Ensure every provided field is defined.\n\t\tfieldASTs := valueAST.Fields\n\t\tfieldASTMap := map[string]*ast.ObjectField{}\n\t\tfor _, fieldAST := range fieldASTs {\n\t\t\tfieldASTMap[fieldAST.Name.Value] = fieldAST\n\t\t\tfield, ok := fields[fieldAST.Name.Value]\n\t\t\tif !ok || field == nil {\n\t\t\t\tmessagesReduce = append(messagesReduce, fmt.Sprintf(`In field \"%v\": Unknown field.`, fieldAST.Name.Value))\n\t\t\t}\n\t\t}\n\t\t// Ensure every defined field is valid.\n\t\tfor fieldName, field := range fields {\n\t\t\tvar fieldASTValue ast.Value\n\t\t\tif fieldAST := fieldASTMap[fieldName]; fieldAST != nil {\n\t\t\t\tfieldASTValue = fieldAST.Value\n\t\t\t}\n\t\t\tif isValid, messages := isValidLiteralValue(field.Type, fieldASTValue); !isValid {\n\t\t\t\tfor _, message := range messages {\n\t\t\t\t\tmessagesReduce = append(messagesReduce, fmt.Sprintf(\"In field \\\"%v\\\": %v\", fieldName, message))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn (len(messagesReduce) == 0), messagesReduce\n\tcase *Scalar:\n\t\tif isNullish(ttype.ParseLiteral(valueAST)) {\n\t\t\treturn false, []string{fmt.Sprintf(`Expected type \"%v\", found %v.`, ttype.Name(), printer.Print(valueAST))}\n\t\t}\n\tcase *Enum:\n\t\tif isNullish(ttype.ParseLiteral(valueAST)) {\n\t\t\treturn false, []string{fmt.Sprintf(`Expected type \"%v\", found %v.`, ttype.Name(), printer.Print(valueAST))}\n\t\t}\n\t}\n\n\treturn true, nil\n}\n\n// Internal struct to sort results from suggestionList()\ntype suggestionListResult struct {\n\tOptions   []string\n\tDistances []float64\n}\n\nfunc (s suggestionListResult) Len() int {\n\treturn len(s.Options)\n}\nfunc (s suggestionListResult) Swap(i, j int) {\n\ts.Options[i], s.Options[j] = s.Options[j], s.Options[i]\n}\nfunc (s suggestionListResult) Less(i, j int) bool {\n\treturn s.Distances[i] < s.Distances[j]\n}\n\n// suggestionList Given an invalid input string and a list of valid options, returns a filtered\n// list of valid options sorted based on their similarity with the input.\nfunc suggestionList(input string, options []string) []string {\n\tdists := []float64{}\n\tfilteredOpts := []string{}\n\tinputThreshold := float64(len(input) / 2)\n\n\tfor _, opt := range options {\n\t\tdist := lexicalDistance(input, opt)\n\t\tthreshold := math.Max(inputThreshold, float64(len(opt)/2))\n\t\tthreshold = math.Max(threshold, 1)\n\t\tif dist <= threshold {\n\t\t\tfilteredOpts = append(filteredOpts, opt)\n\t\t\tdists = append(dists, dist)\n\t\t}\n\t}\n\t//sort results\n\tsuggested := suggestionListResult{filteredOpts, dists}\n\tsort.Sort(suggested)\n\treturn suggested.Options\n}\n\n// lexicalDistance Computes the lexical distance between strings A and B.\n// The \"distance\" between two strings is given by counting the minimum number\n// of edits needed to transform string A into string B. An edit can be an\n// insertion, deletion, or substitution of a single character, or a swap of two\n// adjacent characters.\n// This distance can be useful for detecting typos in input or sorting\nfunc lexicalDistance(a, b string) float64 {\n\td := [][]float64{}\n\taLen := len(a)\n\tbLen := len(b)\n\tfor i := 0; i <= aLen; i++ {\n\t\td = append(d, []float64{float64(i)})\n\t}\n\tfor k := 1; k <= bLen; k++ {\n\t\td[0] = append(d[0], float64(k))\n\t}\n\n\tfor i := 1; i <= aLen; i++ {\n\t\tfor k := 1; k <= bLen; k++ {\n\t\t\tcost := 1.0\n\t\t\tif a[i-1] == b[k-1] {\n\t\t\t\tcost = 0.0\n\t\t\t}\n\t\t\tminCostFloat := math.Min(\n\t\t\t\td[i-1][k]+1.0,\n\t\t\t\td[i][k-1]+1.0,\n\t\t\t)\n\t\t\tminCostFloat = math.Min(\n\t\t\t\tminCostFloat,\n\t\t\t\td[i-1][k-1]+cost,\n\t\t\t)\n\t\t\td[i] = append(d[i], minCostFloat)\n\n\t\t\tif i > 1 && k < 1 &&\n\t\t\t\ta[i-1] == b[k-2] &&\n\t\t\t\ta[i-2] == b[k-1] {\n\t\t\t\td[i][k] = math.Min(d[i][k], d[i-2][k-2]+cost)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn d[aLen][bLen]\n}\n"
  },
  {
    "path": "rules_arguments_of_correct_type_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_ArgValuesOfCorrectType_ValidValue_GoodIntValue(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            intArgField(intArg: 2)\n          }\n        }\n    `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidValue_GoodBooleanValue(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            booleanArgField(booleanArg: true)\n          }\n        }\n    `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidValue_GoodStringValue(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringArgField(stringArg: \"foo\")\n          }\n        }\n    `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidValue_GoodFloatValue(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            floatArgField(floatArg: 1.1)\n          }\n        }\n    `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidValue_IntIntoFloat(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            floatArgField(floatArg: 1)\n          }\n        }\n    `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidValue_IntIntoID(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            idArgField(idArg: 1)\n          }\n        }\n    `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidValue_StringIntoID(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            idArgField(idArg: \"someIdString\")\n          }\n        }\n    `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidValue_GoodEnumValue(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            doesKnowCommand(dogCommand: SIT)\n          }\n        }\n    `)\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidStringValues_IntIntoString(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringArgField(stringArg: 1)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"stringArg\\\" has invalid value 1.\\nExpected type \\\"String\\\", found 1.\",\n\t\t\t\t4, 39,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidStringValues_FloatIntoString(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringArgField(stringArg: 1.0)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"stringArg\\\" has invalid value 1.0.\\nExpected type \\\"String\\\", found 1.0.\",\n\t\t\t\t4, 39,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidStringValues_BooleanIntoString(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringArgField(stringArg: true)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"stringArg\\\" has invalid value true.\\nExpected type \\\"String\\\", found true.\",\n\t\t\t\t4, 39,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidStringValues_UnquotedStringIntoString(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringArgField(stringArg: BAR)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"stringArg\\\" has invalid value BAR.\\nExpected type \\\"String\\\", found BAR.\",\n\t\t\t\t4, 39,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidIntValues_StringIntoInt(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            intArgField(intArg: \"3\")\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"intArg\\\" has invalid value \\\"3\\\".\\nExpected type \\\"Int\\\", found \\\"3\\\".\",\n\t\t\t\t4, 33,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidIntValues_BigIntIntoInt(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            intArgField(intArg: 829384293849283498239482938)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"intArg\\\" has invalid value 829384293849283498239482938.\\nExpected type \\\"Int\\\", found 829384293849283498239482938.\",\n\t\t\t\t4, 33,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidIntValues_UnquotedStringIntoInt(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            intArgField(intArg: FOO)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"intArg\\\" has invalid value FOO.\\nExpected type \\\"Int\\\", found FOO.\",\n\t\t\t\t4, 33,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidIntValues_SimpleFloatIntoInt(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            intArgField(intArg: 3.0)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"intArg\\\" has invalid value 3.0.\\nExpected type \\\"Int\\\", found 3.0.\",\n\t\t\t\t4, 33,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidIntValues_FloatIntoInt(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            intArgField(intArg: 3.333)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"intArg\\\" has invalid value 3.333.\\nExpected type \\\"Int\\\", found 3.333.\",\n\t\t\t\t4, 33,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidFloatValues_StringIntoFloat(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            floatArgField(floatArg: \"3.333\")\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"floatArg\\\" has invalid value \\\"3.333\\\".\\nExpected type \\\"Float\\\", found \\\"3.333\\\".\",\n\t\t\t\t4, 37,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidFloatValues_BooleanIntoFloat(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            floatArgField(floatArg: true)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"floatArg\\\" has invalid value true.\\nExpected type \\\"Float\\\", found true.\",\n\t\t\t\t4, 37,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidFloatValues_UnquotedIntoFloat(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            floatArgField(floatArg: FOO)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"floatArg\\\" has invalid value FOO.\\nExpected type \\\"Float\\\", found FOO.\",\n\t\t\t\t4, 37,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidBooleanValues_IntIntoBoolean(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            booleanArgField(booleanArg: 2)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"booleanArg\\\" has invalid value 2.\\nExpected type \\\"Boolean\\\", found 2.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidBooleanValues_FloatIntoBoolean(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            booleanArgField(booleanArg: 1.0)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"booleanArg\\\" has invalid value 1.0.\\nExpected type \\\"Boolean\\\", found 1.0.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidBooleanValues_StringIntoBoolean(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            booleanArgField(booleanArg: \"true\")\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"booleanArg\\\" has invalid value \\\"true\\\".\\nExpected type \\\"Boolean\\\", found \\\"true\\\".\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidBooleanValues_UnquotedStringIntoBoolean(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            booleanArgField(booleanArg: TRUE)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"booleanArg\\\" has invalid value TRUE.\\nExpected type \\\"Boolean\\\", found TRUE.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidIDValue_FloatIntoID(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            idArgField(idArg: 1.0)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"idArg\\\" has invalid value 1.0.\\nExpected type \\\"ID\\\", found 1.0.\",\n\t\t\t\t4, 31,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidIDValue_BooleanIntoID(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            idArgField(idArg: true)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"idArg\\\" has invalid value true.\\nExpected type \\\"ID\\\", found true.\",\n\t\t\t\t4, 31,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidIDValue_UnquotedIntoID(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            idArgField(idArg: SOMETHING)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"idArg\\\" has invalid value SOMETHING.\\nExpected type \\\"ID\\\", found SOMETHING.\",\n\t\t\t\t4, 31,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidEnumValue_IntIntoEnum(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            doesKnowCommand(dogCommand: 2)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"dogCommand\\\" has invalid value 2.\\nExpected type \\\"DogCommand\\\", found 2.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidEnumValue_FloatIntoEnum(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            doesKnowCommand(dogCommand: 1.0)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"dogCommand\\\" has invalid value 1.0.\\nExpected type \\\"DogCommand\\\", found 1.0.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidEnumValue_StringIntoEnum(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            doesKnowCommand(dogCommand: \"SIT\")\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"dogCommand\\\" has invalid value \\\"SIT\\\".\\nExpected type \\\"DogCommand\\\", found \\\"SIT\\\".\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidEnumValue_BooleanIntoEnum(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            doesKnowCommand(dogCommand: true)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"dogCommand\\\" has invalid value true.\\nExpected type \\\"DogCommand\\\", found true.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidEnumValue_UnknownEnumValueIntoEnum(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            doesKnowCommand(dogCommand: JUGGLE)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"dogCommand\\\" has invalid value JUGGLE.\\nExpected type \\\"DogCommand\\\", found JUGGLE.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidEnumValue_DifferentCaseEnumValueIntoEnum(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            doesKnowCommand(dogCommand: sit)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"dogCommand\\\" has invalid value sit.\\nExpected type \\\"DogCommand\\\", found sit.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_ValidListValue_GoodListValue(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringListArgField(stringListArg: [\"one\", \"two\"])\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidListValue_EmptyListValue(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringListArgField(stringListArg: [])\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidListValue_SingleValueIntoList(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringListArgField(stringListArg: \"one\")\n          }\n        }\n        `)\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidListValue_IncorrectItemType(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringListArgField(stringListArg: [\"one\", 2])\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"stringListArg\\\" has invalid value [\\\"one\\\", 2].\\nIn element #1: Expected type \\\"String\\\", found 2.\",\n\t\t\t\t4, 47,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidListValue_SingleValueOfIncorrentType(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            stringListArgField(stringListArg: 1)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"stringListArg\\\" has invalid value 1.\\nExpected type \\\"String\\\", found 1.\",\n\t\t\t\t4, 47,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_ArgOnOptionalArg(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            isHousetrained(atOtherHomes: true)\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_NoArgOnOptionalArg(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog {\n            isHousetrained\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_MultipleArgs(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleReqs(req1: 1, req2: 2)\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_MultipleArgsReverseOrder(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleReqs(req2: 2, req1: 1)\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_NoArgsOnMultipleOptional(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleOpts\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_OneArgOnMultipleOptional(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleOpts(opt1: 1)\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_SecondArgOnMultipleOptional(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleOpts(opt2: 1)\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_MultipleRequiredsOnMixedList(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleOptAndReq(req1: 3, req2: 4)\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_MultipleRequiredsAndOptionalOnMixedList(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleOptAndReq(req1: 3, req2: 4, opt1: 5)\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidNonNullableValue_AllRequiredsAndOptionalOnMixedList(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleOptAndReq(req1: 3, req2: 4, opt1: 5, opt2: 6)\n          }\n        }\n        `)\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidNonNullableValue_IncorrectValueType(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleReqs(req2: \"two\", req1: \"one\")\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"req2\\\" has invalid value \\\"two\\\".\\nExpected type \\\"Int\\\", found \\\"two\\\".\",\n\t\t\t\t4, 32,\n\t\t\t),\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"req1\\\" has invalid value \\\"one\\\".\\nExpected type \\\"Int\\\", found \\\"one\\\".\",\n\t\t\t\t4, 45,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidNonNullableValue_IncorrectValueAndMissingArgument(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            multipleReqs(req1: \"one\")\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"req1\\\" has invalid value \\\"one\\\".\\nExpected type \\\"Int\\\", found \\\"one\\\".\",\n\t\t\t\t4, 32,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_ValidInputObjectValue_OptionalArg_DespiteRequiredFieldInType(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            complexArgField\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidInputObjectValue_PartialObject_OnlyRequired(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            complexArgField(complexArg: { requiredField: true })\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidInputObjectValue_PartialObject_RequiredFieldCanBeFalsey(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            complexArgField(complexArg: { requiredField: false })\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidInputObjectValue_PartialObject_IncludingRequired(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n\t\t\t  complexArgField(complexArg: { requiredField: false, intField: 4 })\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidInputObjectValue_FullObject(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            complexArgField(complexArg: {\n              requiredField: true,\n              intField: 4,\n              stringField: \"foo\",\n              booleanField: false,\n              stringListField: [\"one\", \"two\"]\n            })\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_ValidInputObjectValue_FullObject_WithFieldsInDifferentOrder(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            complexArgField(complexArg: {\n              stringListField: [\"one\", \"two\"],\n              booleanField: false,\n              requiredField: true,\n              stringField: \"foo\",\n              intField: 4,\n            })\n          }\n        }\n        `)\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_InvalidInputObjectValue_PartialObject_MissingRequired(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            complexArgField(complexArg: { intField: 4 })\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"complexArg\\\" has invalid value {intField: 4}.\\nIn field \\\"requiredField\\\": Expected \\\"Boolean!\\\", found null.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidInputObjectValue_PartialObject_InvalidFieldType(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            complexArgField(complexArg: {\n              stringListField: [\"one\", 2],\n              requiredField: true,\n            })\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"complexArg\\\" has invalid value {stringListField: [\\\"one\\\", 2], requiredField: true}.\\nIn field \\\"stringListField\\\": In element #1: Expected type \\\"String\\\", found 2.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_ArgValuesOfCorrectType_InvalidInputObjectValue_PartialObject_UnknownFieldArg(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          complicatedArgs {\n            complexArgField(complexArg: {\n              requiredField: true,\n              unknownField: \"value\"\n            })\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t\"Argument \\\"complexArg\\\" has invalid value {requiredField: true, unknownField: \\\"value\\\"}.\\nIn field \\\"unknownField\\\": Unknown field.\",\n\t\t\t\t4, 41,\n\t\t\t),\n\t\t})\n}\n\nfunc TestValidate_ArgValuesOfCorrectType_DirectiveArguments_WithDirectivesOfValidType(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog @include(if: true) {\n            name\n          }\n          human @skip(if: false) {\n            name\n          }\n        }\n        `)\n}\nfunc TestValidate_ArgValuesOfCorrectType_DirectiveArguments_WithDirectivesWithIncorrectTypes(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ArgumentsOfCorrectTypeRule, `\n        {\n          dog @include(if: \"yes\") {\n            name @skip(if: ENUM)\n          }\n        }\n        `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t`Argument \"if\" has invalid value \"yes\".`+\n\t\t\t\t\t\"\\nExpected type \\\"Boolean\\\", found \\\"yes\\\".\",\n\t\t\t\t3, 28,\n\t\t\t),\n\t\t\ttestutil.RuleError(\n\t\t\t\t`Argument \"if\" has invalid value ENUM.`+\n\t\t\t\t\t\"\\nExpected type \\\"Boolean\\\", found ENUM.\",\n\t\t\t\t4, 28,\n\t\t\t),\n\t\t})\n}\n"
  },
  {
    "path": "rules_default_values_of_correct_type_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_VariableDefaultValuesOfCorrectType_VariablesWithNoDefaultValues(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.DefaultValuesOfCorrectTypeRule, `\n      query NullableValues($a: Int, $b: String, $c: ComplexInput) {\n        dog { name }\n      }\n    `)\n}\nfunc TestValidate_VariableDefaultValuesOfCorrectType_RequiredVariablesWithoutDefaultValues(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.DefaultValuesOfCorrectTypeRule, `\n      query RequiredValues($a: Int!, $b: String!) {\n        dog { name }\n      }\n    `)\n}\nfunc TestValidate_VariableDefaultValuesOfCorrectType_VariablesWithValidDefaultValues(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.DefaultValuesOfCorrectTypeRule, `\n      query WithDefaultValues(\n        $a: Int = 1,\n        $b: String = \"ok\",\n        $c: ComplexInput = { requiredField: true, intField: 3 }\n      ) {\n        dog { name }\n      }\n    `)\n}\nfunc TestValidate_VariableDefaultValuesOfCorrectType_NoRequiredVariablesWithDefaultValues(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.DefaultValuesOfCorrectTypeRule, `\n      query UnreachableDefaultValues($a: Int! = 3, $b: String! = \"default\") {\n        dog { name }\n      }\n    `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t`Variable \"$a\" of type \"Int!\" is required and will not `+\n\t\t\t\t\t`use the default value. Perhaps you meant to use type \"Int\".`,\n\t\t\t\t2, 49,\n\t\t\t),\n\t\t\ttestutil.RuleError(\n\t\t\t\t`Variable \"$b\" of type \"String!\" is required and will not `+\n\t\t\t\t\t`use the default value. Perhaps you meant to use type \"String\".`,\n\t\t\t\t2, 66,\n\t\t\t),\n\t\t})\n}\nfunc TestValidate_VariableDefaultValuesOfCorrectType_VariablesWithInvalidDefaultValues(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.DefaultValuesOfCorrectTypeRule, `\n      query InvalidDefaultValues(\n        $a: Int = \"one\",\n        $b: String = 4,\n        $c: ComplexInput = \"notverycomplex\"\n      ) {\n        dog { name }\n      }\n    `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(`Variable \"$a\" has invalid default value: \"one\".`+\n\t\t\t\t\"\\nExpected type \\\"Int\\\", found \\\"one\\\".\",\n\t\t\t\t3, 19),\n\t\t\ttestutil.RuleError(`Variable \"$b\" has invalid default value: 4.`+\n\t\t\t\t\"\\nExpected type \\\"String\\\", found 4.\",\n\t\t\t\t4, 22),\n\t\t\ttestutil.RuleError(\n\t\t\t\t`Variable \"$c\" has invalid default value: \"notverycomplex\".`+\n\t\t\t\t\t\"\\nExpected \\\"ComplexInput\\\", found not an object.\",\n\t\t\t\t5, 28),\n\t\t})\n}\nfunc TestValidate_VariableDefaultValuesOfCorrectType_ComplexVariablesMissingRequiredField(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.DefaultValuesOfCorrectTypeRule, `\n      query MissingRequiredField($a: ComplexInput = {intField: 3}) {\n        dog { name }\n      }\n    `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t`Variable \"$a\" has invalid default value: {intField: 3}.`+\n\t\t\t\t\t\"\\nIn field \\\"requiredField\\\": Expected \\\"Boolean!\\\", found null.\",\n\t\t\t\t2, 53),\n\t\t})\n}\nfunc TestValidate_VariableDefaultValuesOfCorrectType_ListVariablesWithInvalidItem(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.DefaultValuesOfCorrectTypeRule, `\n      query InvalidItem($a: [String] = [\"one\", 2]) {\n        dog { name }\n      }\n    `,\n\t\t[]gqlerrors.FormattedError{\n\t\t\ttestutil.RuleError(\n\t\t\t\t`Variable \"$a\" has invalid default value: [\"one\", 2].`+\n\t\t\t\t\t\"\\nIn element #1: Expected type \\\"String\\\", found 2.\",\n\t\t\t\t2, 40),\n\t\t})\n}\n\nfunc TestValidate_VariableDefaultValuesOfCorrectType_InvalidNonNull(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.DefaultValuesOfCorrectTypeRule, `query($g:e!){a}`)\n}\n"
  },
  {
    "path": "rules_fields_on_correct_type_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_FieldsOnCorrectType_ObjectFieldSelection(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment objectFieldSelection on Dog {\n        __typename\n        name\n      }\n    `)\n}\nfunc TestValidate_FieldsOnCorrectType_AliasedObjectFieldSelection(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment aliasedObjectFieldSelection on Dog {\n        tn : __typename\n        otherName : name\n      }\n    `)\n}\nfunc TestValidate_FieldsOnCorrectType_InterfaceFieldSelection(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment interfaceFieldSelection on Pet {\n        __typename\n        name\n      }\n    `)\n}\nfunc TestValidate_FieldsOnCorrectType_AliasedInterfaceFieldSelection(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment interfaceFieldSelection on Pet {\n        otherName : name\n      }\n    `)\n}\nfunc TestValidate_FieldsOnCorrectType_LyingAliasSelection(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment lyingAliasSelection on Dog {\n        name : nickname\n      }\n    `)\n}\nfunc TestValidate_FieldsOnCorrectType_IgnoresFieldsOnUnknownType(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment unknownSelection on UnknownType {\n        unknownField\n      }\n    `)\n}\nfunc TestValidate_FieldsOnCorrectType_ReportErrorsWhenTheTypeIsKnownAgain(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment typeKnownAgain on Pet {\n        unknown_pet_field {\n          ... on Cat {\n            unknown_cat_field\n          }\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"unknown_pet_field\" on type \"Pet\".`, 3, 9),\n\t\ttestutil.RuleError(`Cannot query field \"unknown_cat_field\" on type \"Cat\".`, 5, 13),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_FieldNotDefinedOnFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment fieldNotDefined on Dog {\n        meowVolume\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"meowVolume\" on type \"Dog\". Did you mean \"barkVolume\"?`, 3, 9),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_IgnoreDeeplyUnknownField(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment deepFieldNotDefined on Dog {\n        unknown_field {\n          deeper_unknown_field\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"unknown_field\" on type \"Dog\".`, 3, 9),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_SubFieldNotDefined(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment subFieldNotDefined on Human {\n        pets {\n          unknown_field\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"unknown_field\" on type \"Pet\".`, 4, 11),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_FieldNotDefinedOnInlineFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment fieldNotDefined on Pet {\n        ... on Dog {\n          meowVolume\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"meowVolume\" on type \"Dog\". Did you mean \"barkVolume\"?`, 4, 11),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_AliasedFieldTargetNotDefined(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment aliasedFieldTargetNotDefined on Dog {\n        volume : mooVolume\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"mooVolume\" on type \"Dog\". Did you mean \"barkVolume\"?`, 3, 9),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_AliasedLyingFieldTargetNotDefined(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment aliasedLyingFieldTargetNotDefined on Dog {\n        barkVolume : kawVolume\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"kawVolume\" on type \"Dog\". Did you mean \"barkVolume\"?`, 3, 9),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_NotDefinedOnInterface(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment notDefinedOnInterface on Pet {\n        tailLength\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"tailLength\" on type \"Pet\".`, 3, 9),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_DefinedOnImplementorsButNotOnInterface(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment definedOnImplementorsButNotInterface on Pet {\n        nickname\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"nickname\" on type \"Pet\". Did you mean to use an inline fragment on \"Cat\" or \"Dog\"?`, 3, 9),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_MetaFieldSelectionOnUnion(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment directFieldSelectionOnUnion on CatOrDog {\n        __typename\n      }\n    `)\n}\nfunc TestValidate_FieldsOnCorrectType_DirectFieldSelectionOnUnion(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment directFieldSelectionOnUnion on CatOrDog {\n        directField\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"directField\" on type \"CatOrDog\".`, 3, 9),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_DefinedImplementorsQueriedOnUnion(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment definedOnImplementorsQueriedOnUnion on CatOrDog {\n        name\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot query field \"name\" on type \"CatOrDog\". Did you mean to use an inline fragment on \"Being\", \"Pet\", \"Canine\", \"Cat\", or \"Dog\"?`, 3, 9),\n\t})\n}\nfunc TestValidate_FieldsOnCorrectType_ValidFieldInInlineFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `\n      fragment objectFieldSelection on Pet {\n        ... on Dog {\n          name\n        }\n        ... {\n          name\n        }\n      }\n    `)\n}\n\nfunc TestValidate_FieldsOnCorrectTypeErrorMessage_WorksWithNoSuggestions(t *testing.T) {\n\tmessage := graphql.UndefinedFieldMessage(\"f\", \"T\", []string{}, []string{})\n\texpected := `Cannot query field \"f\" on type \"T\".`\n\tif message != expected {\n\t\tt.Fatalf(\"Unexpected message, expected: %v, got %v\", expected, message)\n\t}\n}\n\nfunc TestValidate_FieldsOnCorrectTypeErrorMessage_WorksWithNoSmallNumbersOfTypeSuggestions(t *testing.T) {\n\tmessage := graphql.UndefinedFieldMessage(\"f\", \"T\", []string{\"A\", \"B\"}, []string{})\n\texpected := `Cannot query field \"f\" on type \"T\". ` +\n\t\t`Did you mean to use an inline fragment on \"A\" or \"B\"?`\n\tif message != expected {\n\t\tt.Fatalf(\"Unexpected message, expected: %v, got %v\", expected, message)\n\t}\n}\n\nfunc TestValidate_FieldsOnCorrectTypeErrorMessage_WorksWithNoSmallNumbersOfFieldSuggestions(t *testing.T) {\n\tmessage := graphql.UndefinedFieldMessage(\"f\", \"T\", []string{}, []string{\"z\", \"y\"})\n\texpected := `Cannot query field \"f\" on type \"T\". ` +\n\t\t`Did you mean \"z\" or \"y\"?`\n\tif message != expected {\n\t\tt.Fatalf(\"Unexpected message, expected: %v, got %v\", expected, message)\n\t}\n}\nfunc TestValidate_FieldsOnCorrectTypeErrorMessage_OnlyShowsOneSetOfSuggestionsAtATimePreferringTypes(t *testing.T) {\n\tmessage := graphql.UndefinedFieldMessage(\"f\", \"T\", []string{\"A\", \"B\"}, []string{\"z\", \"y\"})\n\texpected := `Cannot query field \"f\" on type \"T\". ` +\n\t\t`Did you mean to use an inline fragment on \"A\" or \"B\"?`\n\tif message != expected {\n\t\tt.Fatalf(\"Unexpected message, expected: %v, got %v\", expected, message)\n\t}\n}\n\nfunc TestValidate_FieldsOnCorrectTypeErrorMessage_LimitLotsOfTypeSuggestions(t *testing.T) {\n\tmessage := graphql.UndefinedFieldMessage(\"f\", \"T\", []string{\"A\", \"B\", \"C\", \"D\", \"E\", \"F\"}, []string{})\n\texpected := `Cannot query field \"f\" on type \"T\". ` +\n\t\t`Did you mean to use an inline fragment on \"A\", \"B\", \"C\", \"D\", or \"E\"?`\n\tif message != expected {\n\t\tt.Fatalf(\"Unexpected message, expected: %v, got %v\", expected, message)\n\t}\n}\n\nfunc TestValidate_FieldsOnCorrectTypeErrorMessage_LimitLotsOfFieldSuggestions(t *testing.T) {\n\tmessage := graphql.UndefinedFieldMessage(\n\t\t\"f\", \"T\", []string{}, []string{\"z\", \"y\", \"x\", \"w\", \"v\", \"u\"},\n\t)\n\texpected := `Cannot query field \"f\" on type \"T\". ` +\n\t\t`Did you mean \"z\", \"y\", \"x\", \"w\", or \"v\"?`\n\tif message != expected {\n\t\tt.Fatalf(\"Unexpected message, expected: %v, got %v\", expected, message)\n\t}\n}\n\nfunc TestValidate_FieldsOnCorrectType_NilCrash(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FieldsOnCorrectTypeRule, `mutation{o}`)\n}\n"
  },
  {
    "path": "rules_fragments_on_composite_types_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_FragmentsOnCompositeTypes_ObjectIsValidFragmentType(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment validFragment on Dog {\n        barks\n      }\n    `)\n}\nfunc TestValidate_FragmentsOnCompositeTypes_InterfaceIsValidFragmentType(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment validFragment on Pet {\n        name\n      }\n    `)\n}\nfunc TestValidate_FragmentsOnCompositeTypes_ObjectIsValidInlineFragmentType(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment validFragment on Pet {\n        ... on Dog {\n          barks\n        }\n      }\n    `)\n}\nfunc TestValidate_FragmentsOnCompositeTypes_InlineFragmentWithoutTypeIsValid(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment validFragment on Pet {\n        ... {\n          name\n        }\n      }\n    `)\n}\nfunc TestValidate_FragmentsOnCompositeTypes_UnionIsValidFragmentType(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment validFragment on CatOrDog {\n        __typename\n      }\n    `)\n}\nfunc TestValidate_FragmentsOnCompositeTypes_ScalarIsInvalidFragmentType(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment scalarFragment on Boolean {\n        bad\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"scalarFragment\" cannot condition on non composite type \"Boolean\".`, 2, 34),\n\t})\n}\nfunc TestValidate_FragmentsOnCompositeTypes_EnumIsInvalidFragmentType(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment scalarFragment on FurColor {\n        bad\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"scalarFragment\" cannot condition on non composite type \"FurColor\".`, 2, 34),\n\t})\n}\nfunc TestValidate_FragmentsOnCompositeTypes_InputObjectIsInvalidFragmentType(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment inputFragment on ComplexInput {\n        stringField\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"inputFragment\" cannot condition on non composite type \"ComplexInput\".`, 2, 33),\n\t})\n}\nfunc TestValidate_FragmentsOnCompositeTypes_ScalarIsInvalidInlineFragmentType(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.FragmentsOnCompositeTypesRule, `\n      fragment invalidFragment on Pet {\n        ... on String {\n          barks\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment cannot condition on non composite type \"String\".`, 3, 16),\n\t})\n}\n"
  },
  {
    "path": "rules_known_argument_names_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_KnownArgumentNames_SingleArgIsKnown(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownArgumentNamesRule, `\n      fragment argOnRequiredArg on Dog {\n        doesKnowCommand(dogCommand: SIT)\n      }\n    `)\n}\nfunc TestValidate_KnownArgumentNames_MultipleArgsAreKnown(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownArgumentNamesRule, `\n      fragment multipleArgs on ComplicatedArgs {\n        multipleReqs(req1: 1, req2: 2)\n      }\n    `)\n}\nfunc TestValidate_KnownArgumentNames_IgnoresArgsOfUnknownFields(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownArgumentNamesRule, `\n      fragment argOnUnknownField on Dog {\n        unknownField(unknownArg: SIT)\n      }\n    `)\n}\nfunc TestValidate_KnownArgumentNames_MultipleArgsInReverseOrderAreKnown(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownArgumentNamesRule, `\n      fragment multipleArgsReverseOrder on ComplicatedArgs {\n        multipleReqs(req2: 2, req1: 1)\n      }\n    `)\n}\nfunc TestValidate_KnownArgumentNames_NoArgsOnOptionalArg(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownArgumentNamesRule, `\n      fragment noArgOnOptionalArg on Dog {\n        isHousetrained\n      }\n    `)\n}\nfunc TestValidate_KnownArgumentNames_ArgsAreKnownDeeply(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownArgumentNamesRule, `\n      {\n        dog {\n          doesKnowCommand(dogCommand: SIT)\n        }\n        human {\n          pet {\n            ... on Dog {\n              doesKnowCommand(dogCommand: SIT)\n            }\n          }\n        }\n      }\n    `)\n}\nfunc TestValidate_KnownArgumentNames_DirectiveArgsAreKnown(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownArgumentNamesRule, `\n      {\n        dog @skip(if: true)\n      }\n    `)\n}\nfunc TestValidate_KnownArgumentNames_UndirectiveArgsAreInvalid(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownArgumentNamesRule, `\n      {\n        dog @skip(unless: true)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown argument \"unless\" on directive \"@skip\".`, 3, 19),\n\t})\n}\nfunc TestValidate_KnownArgumentNames_UndirectiveArgsAreInvalidWithSuggestion(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownArgumentNamesRule, `\n      {\n        dog @skip(of: true)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown argument \"of\" on directive \"@skip\". `+\n\t\t\t`Did you mean \"if\"?`, 3, 19),\n\t})\n}\nfunc TestValidate_KnownArgumentNames_InvalidArgName(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownArgumentNamesRule, `\n      fragment invalidArgName on Dog {\n        doesKnowCommand(unknown: true)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown argument \"unknown\" on field \"doesKnowCommand\" of type \"Dog\".`, 3, 25),\n\t})\n}\nfunc TestValidate_KnownArgumentNames_UnknownArgsAmongstKnownArgs(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownArgumentNamesRule, `\n      fragment oneGoodArgOneInvalidArg on Dog {\n        doesKnowCommand(whoknows: 1, dogCommand: SIT, unknown: true)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown argument \"whoknows\" on field \"doesKnowCommand\" of type \"Dog\".`, 3, 25),\n\t\ttestutil.RuleError(`Unknown argument \"unknown\" on field \"doesKnowCommand\" of type \"Dog\".`, 3, 55),\n\t})\n}\nfunc TestValidate_KnownArgumentNames_UnknownArgsAmongstKnownArgsWithSuggestions(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownArgumentNamesRule, `\n      fragment oneGoodArgOneInvalidArg on Dog {\n        doesKnowCommand(ddogCommand: SIT,)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown argument \"ddogCommand\" on field \"doesKnowCommand\" of type \"Dog\". `+\n\t\t\t`Did you mean \"dogCommand\" or \"nextDogCommand\"?`, 3, 25),\n\t})\n}\nfunc TestValidate_KnownArgumentNames_UnknownArgsDeeply(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownArgumentNamesRule, `\n      {\n        dog {\n          doesKnowCommand(unknown: true)\n        }\n        human {\n          pet {\n            ... on Dog {\n              doesKnowCommand(unknown: true)\n            }\n          }\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown argument \"unknown\" on field \"doesKnowCommand\" of type \"Dog\".`, 4, 27),\n\t\ttestutil.RuleError(`Unknown argument \"unknown\" on field \"doesKnowCommand\" of type \"Dog\".`, 9, 31),\n\t})\n}\n"
  },
  {
    "path": "rules_known_directives_rule_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_KnownDirectives_WithNoDirectives(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownDirectivesRule, `\n      query Foo {\n        name\n        ...Frag\n      }\n\n      fragment Frag on Dog {\n        name\n      }\n    `)\n}\nfunc TestValidate_KnownDirectives_WithKnownDirective(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownDirectivesRule, `\n      {\n        dog @include(if: true) {\n          name\n        }\n        human @skip(if: false) {\n          name\n        }\n      }\n    `)\n}\nfunc TestValidate_KnownDirectives_WithUnknownDirective(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownDirectivesRule, `\n      {\n        dog @unknown(directive: \"value\") {\n          name\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown directive \"unknown\".`, 3, 13),\n\t})\n}\nfunc TestValidate_KnownDirectives_WithManyUnknownDirectives(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownDirectivesRule, `\n      {\n        dog @unknown(directive: \"value\") {\n          name\n        }\n        human @unknown(directive: \"value\") {\n          name\n          pets @unknown(directive: \"value\") {\n            name\n          }\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown directive \"unknown\".`, 3, 13),\n\t\ttestutil.RuleError(`Unknown directive \"unknown\".`, 6, 15),\n\t\ttestutil.RuleError(`Unknown directive \"unknown\".`, 8, 16),\n\t})\n}\nfunc TestValidate_KnownDirectives_WithWellPlacedDirectives(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownDirectivesRule, `\n      query Foo @onQuery {\n        name @include(if: true)\n        ...Frag @include(if: true)\n        skippedField @skip(if: true)\n        ...SkippedFrag @skip(if: true)\n      }\n\n      mutation Bar @onMutation {\n        someField\n      }\n    `)\n}\nfunc TestValidate_KnownDirectives_WithMisplacedDirectives(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownDirectivesRule, `\n      query Foo @include(if: true) {\n        name @onQuery\n        ...Frag @onQuery\n      }\n\n      mutation Bar @onQuery {\n        someField\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Directive \"include\" may not be used on QUERY.`, 2, 17),\n\t\ttestutil.RuleError(`Directive \"onQuery\" may not be used on FIELD.`, 3, 14),\n\t\ttestutil.RuleError(`Directive \"onQuery\" may not be used on FRAGMENT_SPREAD.`, 4, 17),\n\t\ttestutil.RuleError(`Directive \"onQuery\" may not be used on MUTATION.`, 7, 20),\n\t})\n}\n\nfunc TestValidate_KnownDirectives_WithinSchemaLanguage_WithWellPlacedDirectives(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownDirectivesRule, `\n        type MyObj implements MyInterface @onObject {\n          myField(myArg: Int @onArgumentDefinition): String @onFieldDefinition\n        }\n\n        scalar MyScalar @onScalar\n\n        interface MyInterface @onInterface {\n          myField(myArg: Int @onArgumentDefinition): String @onFieldDefinition\n        }\n\n        union MyUnion @onUnion = MyObj | Other\n\n        enum MyEnum @onEnum {\n          MY_VALUE @onEnumValue\n        }\n\n        input MyInput @onInputObject {\n          myField: Int @onInputFieldDefinition\n        }\n\n        schema @onSchema {\n          query: MyQuery\n        }\n    `)\n}\n\nfunc TestValidate_KnownDirectives_WithinSchemaLanguage_WithMisplacedDirectives(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownDirectivesRule, `\n        type MyObj implements MyInterface @onInterface {\n          myField(myArg: Int @onInputFieldDefinition): String @onInputFieldDefinition\n        }\n\n        scalar MyScalar @onEnum\n\n        interface MyInterface @onObject {\n          myField(myArg: Int @onInputFieldDefinition): String @onInputFieldDefinition\n        }\n\n        union MyUnion @onEnumValue = MyObj | Other\n\n        enum MyEnum @onScalar {\n          MY_VALUE @onUnion\n        }\n\n        input MyInput @onEnum {\n          myField: Int @onArgumentDefinition\n        }\n\n        schema @onObject {\n          query: MyQuery\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Directive \"onInterface\" may not be used on OBJECT.`, 2, 43),\n\t\ttestutil.RuleError(`Directive \"onInputFieldDefinition\" may not be used on ARGUMENT_DEFINITION.`, 3, 30),\n\t\ttestutil.RuleError(`Directive \"onInputFieldDefinition\" may not be used on FIELD_DEFINITION.`, 3, 63),\n\t\ttestutil.RuleError(`Directive \"onEnum\" may not be used on SCALAR.`, 6, 25),\n\t\ttestutil.RuleError(`Directive \"onObject\" may not be used on INTERFACE.`, 8, 31),\n\t\ttestutil.RuleError(`Directive \"onInputFieldDefinition\" may not be used on ARGUMENT_DEFINITION.`, 9, 30),\n\t\ttestutil.RuleError(`Directive \"onInputFieldDefinition\" may not be used on FIELD_DEFINITION.`, 9, 63),\n\t\ttestutil.RuleError(`Directive \"onEnumValue\" may not be used on UNION.`, 12, 23),\n\t\ttestutil.RuleError(`Directive \"onScalar\" may not be used on ENUM.`, 14, 21),\n\t\ttestutil.RuleError(`Directive \"onUnion\" may not be used on ENUM_VALUE.`, 15, 20),\n\t\ttestutil.RuleError(`Directive \"onEnum\" may not be used on INPUT_OBJECT.`, 18, 23),\n\t\ttestutil.RuleError(`Directive \"onArgumentDefinition\" may not be used on INPUT_FIELD_DEFINITION.`, 19, 24),\n\t\ttestutil.RuleError(`Directive \"onObject\" may not be used on SCHEMA.`, 22, 16),\n\t})\n}\n"
  },
  {
    "path": "rules_known_fragment_names_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_KnownFragmentNames_KnownFragmentNamesAreValid(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownFragmentNamesRule, `\n      {\n        human(id: 4) {\n          ...HumanFields1\n          ... on Human {\n            ...HumanFields2\n          }\n          ... {\n            name\n          }\n        }\n      }\n      fragment HumanFields1 on Human {\n        name\n        ...HumanFields3\n      }\n      fragment HumanFields2 on Human {\n        name\n      }\n      fragment HumanFields3 on Human {\n        name\n      }\n    `)\n}\nfunc TestValidate_KnownFragmentNames_UnknownFragmentNamesAreInvalid(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownFragmentNamesRule, `\n      {\n        human(id: 4) {\n          ...UnknownFragment1\n          ... on Human {\n            ...UnknownFragment2\n          }\n        }\n      }\n      fragment HumanFields on Human {\n        name\n        ...UnknownFragment3\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown fragment \"UnknownFragment1\".`, 4, 14),\n\t\ttestutil.RuleError(`Unknown fragment \"UnknownFragment2\".`, 6, 16),\n\t\ttestutil.RuleError(`Unknown fragment \"UnknownFragment3\".`, 12, 12),\n\t})\n}\n"
  },
  {
    "path": "rules_known_type_names_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_KnownTypeNames_KnownTypeNamesAreValid(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.KnownTypeNamesRule, `\n      query Foo($var: String, $required: [String!]!) {\n        user(id: 4) {\n          pets { ... on Pet { name }, ...PetFields, ... { name } }\n        }\n      }\n      fragment PetFields on Pet {\n        name\n      }\n    `)\n}\nfunc TestValidate_KnownTypeNames_UnknownTypeNamesAreInValid(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownTypeNamesRule, `\n      query Foo($var: JumbledUpLetters) {\n        user(id: 4) {\n          name\n          pets { ... on Badger { name }, ...PetFields }\n        }\n      }\n      fragment PetFields on Peettt {\n        name\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown type \"JumbledUpLetters\".`, 2, 23),\n\t\ttestutil.RuleError(`Unknown type \"Badger\".`, 5, 25),\n\t\ttestutil.RuleError(`Unknown type \"Peettt\". Did you mean \"Pet\"?`, 8, 29),\n\t})\n}\n\nfunc TestValidate_KnownTypeNames_IgnoresTypeDefinitions(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.KnownTypeNamesRule, `\n      type NotInTheSchema {\n        field: FooBar\n      }\n      interface FooBar {\n        field: NotInTheSchema\n      }\n      union U = A | B\n      input Blob {\n        field: UnknownType\n      }\n      query Foo($var: NotInTheSchema) {\n        user(id: $var) {\n          id\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Unknown type \"NotInTheSchema\".`, 12, 23),\n\t})\n}\n"
  },
  {
    "path": "rules_lone_anonymous_operation_rule_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_AnonymousOperationMustBeAlone_NoOperations(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.LoneAnonymousOperationRule, `\n      fragment fragA on Type {\n        field\n      }\n    `)\n}\nfunc TestValidate_AnonymousOperationMustBeAlone_OneAnonOperation(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.LoneAnonymousOperationRule, `\n      {\n        field\n      }\n    `)\n}\nfunc TestValidate_AnonymousOperationMustBeAlone_MultipleNamedOperations(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.LoneAnonymousOperationRule, `\n      query Foo {\n        field\n      }\n\n      query Bar {\n        field\n      }\n    `)\n}\nfunc TestValidate_AnonymousOperationMustBeAlone_AnonOperationWithFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.LoneAnonymousOperationRule, `\n      {\n        ...Foo\n      }\n      fragment Foo on Type {\n        field\n      }\n    `)\n}\nfunc TestValidate_AnonymousOperationMustBeAlone_MultipleAnonOperations(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.LoneAnonymousOperationRule, `\n      {\n        fieldA\n      }\n      {\n        fieldB\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`This anonymous operation must be the only defined operation.`, 2, 7),\n\t\ttestutil.RuleError(`This anonymous operation must be the only defined operation.`, 5, 7),\n\t})\n}\nfunc TestValidate_AnonymousOperationMustBeAlone_AnonOperationWithAMutation(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.LoneAnonymousOperationRule, `\n      {\n        fieldA\n      }\n      mutation Foo {\n        fieldB\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`This anonymous operation must be the only defined operation.`, 2, 7),\n\t})\n}\n\nfunc TestValidate_AnonymousOperationMustBeAlone_AnonOperationWithASubscription(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.LoneAnonymousOperationRule, `\n      {\n        fieldA\n      }\n      mutation Foo {\n        fieldB\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`This anonymous operation must be the only defined operation.`, 2, 7),\n\t})\n}\n"
  },
  {
    "path": "rules_no_fragment_cycles_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_NoCircularFragmentSpreads_SingleReferenceIsValid(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragB }\n      fragment fragB on Dog { name }\n    `)\n}\nfunc TestValidate_NoCircularFragmentSpreads_SpreadingTwiceIsNotCircular(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragB, ...fragB }\n      fragment fragB on Dog { name }\n    `)\n}\nfunc TestValidate_NoCircularFragmentSpreads_SpreadingTwiceIndirectlyIsNotCircular(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragB, ...fragC }\n      fragment fragB on Dog { ...fragC }\n      fragment fragC on Dog { name }\n    `)\n}\nfunc TestValidate_NoCircularFragmentSpreads_DoubleSpreadWithinAbstractTypes(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoFragmentCyclesRule, `\n      fragment nameFragment on Pet {\n        ... on Dog { name }\n        ... on Cat { name }\n      }\n\n      fragment spreadsInAnon on Pet {\n        ... on Dog { ...nameFragment }\n        ... on Cat { ...nameFragment }\n      }\n    `)\n}\nfunc TestValidate_NoCircularFragmentSpreads_DoesNotFalsePositiveOnUnknownFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoFragmentCyclesRule, `\n      fragment nameFragment on Pet {\n        ...UnknownFragment\n      }\n    `)\n}\nfunc TestValidate_NoCircularFragmentSpreads_SpreadingRecursivelyWithinFieldFails(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Human { relatives { ...fragA } },\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself.`, 2, 45),\n\t})\n}\n\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfDirectly(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragA }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself.`, 2, 31),\n\t})\n}\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfDirectlyWithinInlineFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Pet {\n        ... on Dog {\n          ...fragA\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself.`, 4, 11),\n\t})\n}\n\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfIndirectly(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragB }\n      fragment fragB on Dog { ...fragA }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself via fragB.`, 2, 31, 3, 31),\n\t})\n}\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfIndirectlyReportsOppositeOrder(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragB on Dog { ...fragA }\n      fragment fragA on Dog { ...fragB }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragB\" within itself via fragA.`, 2, 31, 3, 31),\n\t})\n}\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfIndirectlyWithinInlineFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Pet {\n        ... on Dog {\n          ...fragB\n        }\n      }\n      fragment fragB on Pet {\n        ... on Dog {\n          ...fragA\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself via fragB.`, 4, 11, 9, 11),\n\t})\n}\n\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfDeeply(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragB }\n      fragment fragB on Dog { ...fragC }\n      fragment fragC on Dog { ...fragO }\n      fragment fragX on Dog { ...fragY }\n      fragment fragY on Dog { ...fragZ }\n      fragment fragZ on Dog { ...fragO }\n      fragment fragO on Dog { ...fragP }\n      fragment fragP on Dog { ...fragA, ...fragX }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself via fragB, fragC, fragO, fragP.`,\n\t\t\t2, 31,\n\t\t\t3, 31,\n\t\t\t4, 31,\n\t\t\t8, 31,\n\t\t\t9, 31),\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragO\" within itself via fragP, fragX, fragY, fragZ.`,\n\t\t\t8, 31,\n\t\t\t9, 41,\n\t\t\t5, 31,\n\t\t\t6, 31,\n\t\t\t7, 31),\n\t})\n}\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfDeeplyTwoPaths(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragB, ...fragC }\n      fragment fragB on Dog { ...fragA }\n      fragment fragC on Dog { ...fragA }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself via fragB.`,\n\t\t\t2, 31,\n\t\t\t3, 31),\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself via fragC.`,\n\t\t\t2, 41,\n\t\t\t4, 31),\n\t})\n}\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfDeeplyTwoPaths_AltTraverseOrder(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragC }\n      fragment fragB on Dog { ...fragC }\n      fragment fragC on Dog { ...fragA, ...fragB }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself via fragC.`,\n\t\t\t2, 31,\n\t\t\t4, 31),\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragC\" within itself via fragB.`,\n\t\t\t4, 41,\n\t\t\t3, 31),\n\t})\n}\nfunc TestValidate_NoCircularFragmentSpreads_NoSpreadingItselfDeeplyAndImmediately(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoFragmentCyclesRule, `\n      fragment fragA on Dog { ...fragB }\n      fragment fragB on Dog { ...fragB, ...fragC }\n      fragment fragC on Dog { ...fragA, ...fragB }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragB\" within itself.`, 3, 31),\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragA\" within itself via fragB, fragC.`,\n\t\t\t2, 31,\n\t\t\t3, 41,\n\t\t\t4, 31),\n\t\ttestutil.RuleError(`Cannot spread fragment \"fragB\" within itself via fragC.`,\n\t\t\t3, 41,\n\t\t\t4, 41),\n\t})\n}\n"
  },
  {
    "path": "rules_no_undefined_variables_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_NoUndefinedVariables_AllVariablesDefined(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        field(a: $a, b: $b, c: $c)\n      }\n    `)\n}\nfunc TestValidate_NoUndefinedVariables_AllVariablesDeeplyDefined(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        field(a: $a) {\n          field(b: $b) {\n            field(c: $c)\n          }\n        }\n      }\n    `)\n}\nfunc TestValidate_NoUndefinedVariables_AllVariablesDeeplyDefinedInInlineFragmentsDefined(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        ... on Type {\n          field(a: $a) {\n            field(b: $b) {\n              ... on Type {\n                field(c: $c)\n              }\n            }\n          }\n        }\n      }\n    `)\n}\nfunc TestValidate_NoUndefinedVariables_AllVariablesInFragmentsDeeplyDefined(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a) {\n          ...FragB\n        }\n      }\n      fragment FragB on Type {\n        field(b: $b) {\n          ...FragC\n        }\n      }\n      fragment FragC on Type {\n        field(c: $c)\n      }\n    `)\n}\nfunc TestValidate_NoUndefinedVariables_VariablesWithinSingleFragmentDefinedInMultipleOperations(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String) {\n        ...FragA\n      }\n      query Bar($a: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a)\n      }\n    `)\n}\nfunc TestValidate_NoUndefinedVariables_VariableWithinFragmentsDefinedInOperations(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String) {\n        ...FragA\n      }\n      query Bar($b: String) {\n        ...FragB\n      }\n      fragment FragA on Type {\n        field(a: $a)\n      }\n      fragment FragB on Type {\n        field(b: $b)\n      }\n    `)\n}\nfunc TestValidate_NoUndefinedVariables_VariableWithinRecursiveFragmentDefined(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a) {\n          ...FragA\n        }\n      }\n    `)\n}\nfunc TestValidate_NoUndefinedVariables_VariableNotDefined(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        field(a: $a, b: $b, c: $c, d: $d)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$d\" is not defined by operation \"Foo\".`, 3, 39, 2, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_VariableNotDefinedByUnnamedQuery(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      {\n        field(a: $a)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is not defined.`, 3, 18, 2, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_MultipleVariablesNotDefined(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($b: String) {\n        field(a: $a, b: $b, c: $c)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is not defined by operation \"Foo\".`, 3, 18, 2, 7),\n\t\ttestutil.RuleError(`Variable \"$c\" is not defined by operation \"Foo\".`, 3, 32, 2, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_VariableInFragmentNotDefinedByUnnamedQuery(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is not defined.`, 6, 18, 2, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_VariableInFragmentNotDefinedByOperation(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String, $b: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a) {\n          ...FragB\n        }\n      }\n      fragment FragB on Type {\n        field(b: $b) {\n          ...FragC\n        }\n      }\n      fragment FragC on Type {\n        field(c: $c)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$c\" is not defined by operation \"Foo\".`, 16, 18, 2, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_MultipleVariablesInFragmentsNotDefined(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($b: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a) {\n          ...FragB\n        }\n      }\n      fragment FragB on Type {\n        field(b: $b) {\n          ...FragC\n        }\n      }\n      fragment FragC on Type {\n        field(c: $c)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is not defined by operation \"Foo\".`, 6, 18, 2, 7),\n\t\ttestutil.RuleError(`Variable \"$c\" is not defined by operation \"Foo\".`, 16, 18, 2, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_SingleVariableInFragmentNotDefinedByMultipleOperations(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($a: String) {\n        ...FragAB\n      }\n      query Bar($a: String) {\n        ...FragAB\n      }\n      fragment FragAB on Type {\n        field(a: $a, b: $b)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$b\" is not defined by operation \"Foo\".`, 9, 25, 2, 7),\n\t\ttestutil.RuleError(`Variable \"$b\" is not defined by operation \"Bar\".`, 9, 25, 5, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_VariablesInFragmentNotDefinedByMultipleOperations(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($b: String) {\n        ...FragAB\n      }\n      query Bar($a: String) {\n        ...FragAB\n      }\n      fragment FragAB on Type {\n        field(a: $a, b: $b)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is not defined by operation \"Foo\".`, 9, 18, 2, 7),\n\t\ttestutil.RuleError(`Variable \"$b\" is not defined by operation \"Bar\".`, 9, 25, 5, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_VariableInFragmentUsedByOtherOperation(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($b: String) {\n        ...FragA\n      }\n      query Bar($a: String) {\n        ...FragB\n      }\n      fragment FragA on Type {\n        field(a: $a)\n      }\n      fragment FragB on Type {\n        field(b: $b)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is not defined by operation \"Foo\".`, 9, 18, 2, 7),\n\t\ttestutil.RuleError(`Variable \"$b\" is not defined by operation \"Bar\".`, 12, 18, 5, 7),\n\t})\n}\nfunc TestValidate_NoUndefinedVariables_VaMultipleUndefinedVariablesProduceMultipleErrors(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUndefinedVariablesRule, `\n      query Foo($b: String) {\n        ...FragAB\n      }\n      query Bar($a: String) {\n        ...FragAB\n      }\n      fragment FragAB on Type {\n        field1(a: $a, b: $b)\n        ...FragC\n        field3(a: $a, b: $b)\n      }\n      fragment FragC on Type {\n        field2(c: $c)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is not defined by operation \"Foo\".`, 9, 19, 2, 7),\n\t\ttestutil.RuleError(`Variable \"$c\" is not defined by operation \"Foo\".`, 14, 19, 2, 7),\n\t\ttestutil.RuleError(`Variable \"$a\" is not defined by operation \"Foo\".`, 11, 19, 2, 7),\n\t\ttestutil.RuleError(`Variable \"$b\" is not defined by operation \"Bar\".`, 9, 26, 5, 7),\n\t\ttestutil.RuleError(`Variable \"$c\" is not defined by operation \"Bar\".`, 14, 19, 5, 7),\n\t\ttestutil.RuleError(`Variable \"$b\" is not defined by operation \"Bar\".`, 11, 26, 5, 7),\n\t})\n}\n"
  },
  {
    "path": "rules_no_unused_fragments_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_NoUnusedFragments_AllFragmentNamesAreUsed(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUnusedFragmentsRule, `\n      {\n        human(id: 4) {\n          ...HumanFields1\n          ... on Human {\n            ...HumanFields2\n          }\n        }\n      }\n      fragment HumanFields1 on Human {\n        name\n        ...HumanFields3\n      }\n      fragment HumanFields2 on Human {\n        name\n      }\n      fragment HumanFields3 on Human {\n        name\n      }\n    `)\n}\nfunc TestValidate_NoUnusedFragments_AllFragmentNamesAreUsedByMultipleOperations(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUnusedFragmentsRule, `\n      query Foo {\n        human(id: 4) {\n          ...HumanFields1\n        }\n      }\n      query Bar {\n        human(id: 4) {\n          ...HumanFields2\n        }\n      }\n      fragment HumanFields1 on Human {\n        name\n        ...HumanFields3\n      }\n      fragment HumanFields2 on Human {\n        name\n      }\n      fragment HumanFields3 on Human {\n        name\n      }\n    `)\n}\nfunc TestValidate_NoUnusedFragments_ContainsUnknownFragments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedFragmentsRule, `\n      query Foo {\n        human(id: 4) {\n          ...HumanFields1\n        }\n      }\n      query Bar {\n        human(id: 4) {\n          ...HumanFields2\n        }\n      }\n      fragment HumanFields1 on Human {\n        name\n        ...HumanFields3\n      }\n      fragment HumanFields2 on Human {\n        name\n      }\n      fragment HumanFields3 on Human {\n        name\n      }\n      fragment Unused1 on Human {\n        name\n      }\n      fragment Unused2 on Human {\n        name\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"Unused1\" is never used.`, 22, 7),\n\t\ttestutil.RuleError(`Fragment \"Unused2\" is never used.`, 25, 7),\n\t})\n}\nfunc TestValidate_NoUnusedFragments_ContainsUnknownFragmentsWithRefCycle(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedFragmentsRule, `\n      query Foo {\n        human(id: 4) {\n          ...HumanFields1\n        }\n      }\n      query Bar {\n        human(id: 4) {\n          ...HumanFields2\n        }\n      }\n      fragment HumanFields1 on Human {\n        name\n        ...HumanFields3\n      }\n      fragment HumanFields2 on Human {\n        name\n      }\n      fragment HumanFields3 on Human {\n        name\n      }\n      fragment Unused1 on Human {\n        name\n        ...Unused2\n      }\n      fragment Unused2 on Human {\n        name\n        ...Unused1\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"Unused1\" is never used.`, 22, 7),\n\t\ttestutil.RuleError(`Fragment \"Unused2\" is never used.`, 26, 7),\n\t})\n}\nfunc TestValidate_NoUnusedFragments_ContainsUnknownAndUndefFragments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedFragmentsRule, `\n      query Foo {\n        human(id: 4) {\n          ...bar\n        }\n      }\n      fragment foo on Human {\n        name\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"foo\" is never used.`, 7, 7),\n\t})\n}\n"
  },
  {
    "path": "rules_no_unused_variables_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_NoUnusedVariables_UsesAllVariables(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUnusedVariablesRule, `\n      query ($a: String, $b: String, $c: String) {\n        field(a: $a, b: $b, c: $c)\n      }\n    `)\n}\nfunc TestValidate_NoUnusedVariables_UsesAllVariablesDeeply(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        field(a: $a) {\n          field(b: $b) {\n            field(c: $c)\n          }\n        }\n      }\n    `)\n}\nfunc TestValidate_NoUnusedVariables_UsesAllVariablesDeeplyInInlineFragments(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        ... on Type {\n          field(a: $a) {\n            field(b: $b) {\n              ... on Type {\n                field(c: $c)\n              }\n            }\n          }\n        }\n      }\n    `)\n}\nfunc TestValidate_NoUnusedVariables_UsesAllVariablesInFragments(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a) {\n          ...FragB\n        }\n      }\n      fragment FragB on Type {\n        field(b: $b) {\n          ...FragC\n        }\n      }\n      fragment FragC on Type {\n        field(c: $c)\n      }\n    `)\n}\nfunc TestValidate_NoUnusedVariables_VariableUsedByFragmentInMultipleOperations(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($a: String) {\n        ...FragA\n      }\n      query Bar($b: String) {\n        ...FragB\n      }\n      fragment FragA on Type {\n        field(a: $a)\n      }\n      fragment FragB on Type {\n        field(b: $b)\n      }\n    `)\n}\nfunc TestValidate_NoUnusedVariables_VariableUsedByRecursiveFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($a: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a) {\n          ...FragA\n        }\n      }\n    `)\n}\nfunc TestValidate_NoUnusedVariables_VariableNotUsed(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedVariablesRule, `\n      query ($a: String, $b: String, $c: String) {\n        field(a: $a, b: $b)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$c\" is never used.`, 2, 38),\n\t})\n}\nfunc TestValidate_NoUnusedVariables_MultipleVariablesNotUsed(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        field(b: $b)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is never used in operation \"Foo\".`, 2, 17),\n\t\ttestutil.RuleError(`Variable \"$c\" is never used in operation \"Foo\".`, 2, 41),\n\t})\n}\nfunc TestValidate_NoUnusedVariables_VariableNotUsedInFragments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a) {\n          ...FragB\n        }\n      }\n      fragment FragB on Type {\n        field(b: $b) {\n          ...FragC\n        }\n      }\n      fragment FragC on Type {\n        field\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$c\" is never used in operation \"Foo\".`, 2, 41),\n\t})\n}\nfunc TestValidate_NoUnusedVariables_MultipleVariablesNotUsed2(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($a: String, $b: String, $c: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field {\n          ...FragB\n        }\n      }\n      fragment FragB on Type {\n        field(b: $b) {\n          ...FragC\n        }\n      }\n      fragment FragC on Type {\n        field\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" is never used in operation \"Foo\".`, 2, 17),\n\t\ttestutil.RuleError(`Variable \"$c\" is never used in operation \"Foo\".`, 2, 41),\n\t})\n}\nfunc TestValidate_NoUnusedVariables_VariableNotUsedByUnreferencedFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($b: String) {\n        ...FragA\n      }\n      fragment FragA on Type {\n        field(a: $a)\n      }\n      fragment FragB on Type {\n        field(b: $b)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$b\" is never used in operation \"Foo\".`, 2, 17),\n\t})\n}\nfunc TestValidate_NoUnusedVariables_VariableNotUsedByFragmentUsedByOtherOperation(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.NoUnusedVariablesRule, `\n      query Foo($b: String) {\n        ...FragA\n      }\n      query Bar($a: String) {\n        ...FragB\n      }\n      fragment FragA on Type {\n        field(a: $a)\n      }\n      fragment FragB on Type {\n        field(b: $b)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$b\" is never used in operation \"Foo\".`, 2, 17),\n\t\ttestutil.RuleError(`Variable \"$a\" is never used in operation \"Bar\".`, 5, 17),\n\t})\n}\n"
  },
  {
    "path": "rules_overlapping_fields_can_be_merged.go",
    "content": "package graphql\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/kinds\"\n\t\"github.com/graphql-go/graphql/language/printer\"\n\t\"github.com/graphql-go/graphql/language/visitor\"\n)\n\nfunc fieldsConflictMessage(responseName string, reason conflictReason) string {\n\treturn fmt.Sprintf(`Fields \"%v\" conflict because %v. `+\n\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\tresponseName,\n\t\tfieldsConflictReasonMessage(reason),\n\t)\n}\n\nfunc fieldsConflictReasonMessage(message interface{}) string {\n\tswitch reason := message.(type) {\n\tcase string:\n\t\treturn reason\n\tcase conflictReason:\n\t\treturn fieldsConflictReasonMessage(reason.Message)\n\tcase []conflictReason:\n\t\tmessages := []string{}\n\t\tfor _, r := range reason {\n\t\t\tmessages = append(messages, fmt.Sprintf(\n\t\t\t\t`subfields \"%v\" conflict because %v`,\n\t\t\t\tr.Name,\n\t\t\t\tfieldsConflictReasonMessage(r.Message),\n\t\t\t))\n\t\t}\n\t\treturn strings.Join(messages, \" and \")\n\t}\n\treturn \"\"\n}\n\n// OverlappingFieldsCanBeMergedRule Overlapping fields can be merged\n//\n// A selection set is only valid if all fields (including spreading any\n// fragments) either correspond to distinct response names or can be merged\n// without ambiguity.\nfunc OverlappingFieldsCanBeMergedRule(context *ValidationContext) *ValidationRuleInstance {\n\n\t// A memoization for when two fragments are compared \"between\" each other for\n\t// conflicts. Two fragments may be compared many times, so memoizing this can\n\t// dramatically improve the performance of this validator.\n\tcomparedSet := newPairSet()\n\n\t// A cache for the \"field map\" and list of fragment names found in any given\n\t// selection set. Selection sets may be asked for this information multiple\n\t// times, so this improves the performance of this validator.\n\tcacheMap := map[*ast.SelectionSet]*fieldsAndFragmentNames{}\n\n\tvisitorOpts := &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.SelectionSet: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif selectionSet, ok := p.Node.(*ast.SelectionSet); ok && selectionSet != nil {\n\t\t\t\t\t\tparentType, _ := context.ParentType().(Named)\n\n\t\t\t\t\t\trule := &overlappingFieldsCanBeMergedRule{\n\t\t\t\t\t\t\tcontext:     context,\n\t\t\t\t\t\t\tcomparedSet: comparedSet,\n\t\t\t\t\t\t\tcacheMap:    cacheMap,\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconflicts := rule.findConflictsWithinSelectionSet(parentType, selectionSet)\n\t\t\t\t\t\tif len(conflicts) > 0 {\n\t\t\t\t\t\t\tfor _, c := range conflicts {\n\t\t\t\t\t\t\t\tresponseName := c.Reason.Name\n\t\t\t\t\t\t\t\treason := c.Reason\n\t\t\t\t\t\t\t\treportError(\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t\tfieldsConflictMessage(responseName, reason),\n\t\t\t\t\t\t\t\t\tappend(c.FieldsLeft, c.FieldsRight...),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\treturn &ValidationRuleInstance{\n\t\tVisitorOpts: visitorOpts,\n\t}\n}\n\n/**\n * Algorithm:\n *\n * Conflicts occur when two fields exist in a query which will produce the same\n * response name, but represent differing values, thus creating a conflict.\n * The algorithm below finds all conflicts via making a series of comparisons\n * between fields. In order to compare as few fields as possible, this makes\n * a series of comparisons \"within\" sets of fields and \"between\" sets of fields.\n *\n * Given any selection set, a collection produces both a set of fields by\n * also including all inline fragments, as well as a list of fragments\n * referenced by fragment spreads.\n *\n * A) Each selection set represented in the document first compares \"within\" its\n * collected set of fields, finding any conflicts between every pair of\n * overlapping fields.\n * Note: This is the *only time* that a the fields \"within\" a set are compared\n * to each other. After this only fields \"between\" sets are compared.\n *\n * B) Also, if any fragment is referenced in a selection set, then a\n * comparison is made \"between\" the original set of fields and the\n * referenced fragment.\n *\n * C) Also, if multiple fragments are referenced, then comparisons\n * are made \"between\" each referenced fragment.\n *\n * D) When comparing \"between\" a set of fields and a referenced fragment, first\n * a comparison is made between each field in the original set of fields and\n * each field in the the referenced set of fields.\n *\n * E) Also, if any fragment is referenced in the referenced selection set,\n * then a comparison is made \"between\" the original set of fields and the\n * referenced fragment (recursively referring to step D).\n *\n * F) When comparing \"between\" two fragments, first a comparison is made between\n * each field in the first referenced set of fields and each field in the the\n * second referenced set of fields.\n *\n * G) Also, any fragments referenced by the first must be compared to the\n * second, and any fragments referenced by the second must be compared to the\n * first (recursively referring to step F).\n *\n * H) When comparing two fields, if both have selection sets, then a comparison\n * is made \"between\" both selection sets, first comparing the set of fields in\n * the first selection set with the set of fields in the second.\n *\n * I) Also, if any fragment is referenced in either selection set, then a\n * comparison is made \"between\" the other set of fields and the\n * referenced fragment.\n *\n * J) Also, if two fragments are referenced in both selection sets, then a\n * comparison is made \"between\" the two fragments.\n *\n */\n\ntype overlappingFieldsCanBeMergedRule struct {\n\tcontext *ValidationContext\n\n\t// A memoization for when two fragments are compared \"between\" each other for\n\t// conflicts. Two fragments may be compared many times, so memoizing this can\n\t// dramatically improve the performance of this validator.\n\tcomparedSet *pairSet\n\n\t// A cache for the \"field map\" and list of fragment names found in any given\n\t// selection set. Selection sets may be asked for this information multiple\n\t// times, so this improves the performance of this validator.\n\tcacheMap map[*ast.SelectionSet]*fieldsAndFragmentNames\n}\n\n// Find all conflicts found \"within\" a selection set, including those found\n// via spreading in fragments. Called when visiting each SelectionSet in the\n// GraphQL Document.\nfunc (rule *overlappingFieldsCanBeMergedRule) findConflictsWithinSelectionSet(parentType Named, selectionSet *ast.SelectionSet) []conflict {\n\tconflicts := []conflict{}\n\n\tfieldsInfo := rule.getFieldsAndFragmentNames(parentType, selectionSet)\n\n\t// (A) Find find all conflicts \"within\" the fields of this selection set.\n\t// Note: this is the *only place* `collectConflictsWithin` is called.\n\tconflicts = rule.collectConflictsWithin(conflicts, fieldsInfo)\n\n\t// (B) Then collect conflicts between these fields and those represented by\n\t// each spread fragment name found.\n\tfor i := 0; i < len(fieldsInfo.fragmentNames); i++ {\n\n\t\tconflicts = rule.collectConflictsBetweenFieldsAndFragment(conflicts, false, fieldsInfo, fieldsInfo.fragmentNames[i])\n\n\t\t// (C) Then compare this fragment with all other fragments found in this\n\t\t// selection set to collect conflicts between fragments spread together.\n\t\t// This compares each item in the list of fragment names to every other item\n\t\t// in that same list (except for itself).\n\t\tfor k := i + 1; k < len(fieldsInfo.fragmentNames); k++ {\n\t\t\tconflicts = rule.collectConflictsBetweenFragments(conflicts, false, fieldsInfo.fragmentNames[i], fieldsInfo.fragmentNames[k])\n\t\t}\n\t}\n\treturn conflicts\n}\n\n// Collect all conflicts found between a set of fields and a fragment reference\n// including via spreading in any nested fragments.\nfunc (rule *overlappingFieldsCanBeMergedRule) collectConflictsBetweenFieldsAndFragment(conflicts []conflict, areMutuallyExclusive bool, fieldsInfo *fieldsAndFragmentNames, fragmentName string) []conflict {\n\tfragment := rule.context.Fragment(fragmentName)\n\tif fragment == nil {\n\t\treturn conflicts\n\t}\n\n\tfieldsInfo2 := rule.getReferencedFieldsAndFragmentNames(fragment)\n\n\t// (D) First collect any conflicts between the provided collection of fields\n\t// and the collection of fields represented by the given fragment.\n\tconflicts = rule.collectConflictsBetween(conflicts, areMutuallyExclusive, fieldsInfo, fieldsInfo2)\n\n\t// (E) Then collect any conflicts between the provided collection of fields\n\t// and any fragment names found in the given fragment.\n\tfor _, fragmentName2 := range fieldsInfo2.fragmentNames {\n\t\tconflicts = rule.collectConflictsBetweenFieldsAndFragment(conflicts, areMutuallyExclusive, fieldsInfo2, fragmentName2)\n\t}\n\n\treturn conflicts\n\n}\n\n// Collect all conflicts found between two fragments, including via spreading in\n// any nested fragments.\nfunc (rule *overlappingFieldsCanBeMergedRule) collectConflictsBetweenFragments(conflicts []conflict, areMutuallyExclusive bool, fragmentName1 string, fragmentName2 string) []conflict {\n\tfragment1 := rule.context.Fragment(fragmentName1)\n\tfragment2 := rule.context.Fragment(fragmentName2)\n\n\tif fragment1 == nil || fragment2 == nil {\n\t\treturn conflicts\n\t}\n\n\t// No need to compare a fragment to itself.\n\tif fragment1 == fragment2 {\n\t\treturn conflicts\n\t}\n\n\t// Memoize so two fragments are not compared for conflicts more than once.\n\tif rule.comparedSet.Has(fragmentName1, fragmentName2, areMutuallyExclusive) {\n\t\treturn conflicts\n\t}\n\trule.comparedSet.Add(fragmentName1, fragmentName2, areMutuallyExclusive)\n\n\tfieldsInfo1 := rule.getReferencedFieldsAndFragmentNames(fragment1)\n\tfieldsInfo2 := rule.getReferencedFieldsAndFragmentNames(fragment2)\n\n\t// (F) First, collect all conflicts between these two collections of fields\n\t// (not including any nested fragments).\n\tconflicts = rule.collectConflictsBetween(conflicts, areMutuallyExclusive, fieldsInfo1, fieldsInfo2)\n\n\t// (G) Then collect conflicts between the first fragment and any nested\n\t// fragments spread in the second fragment.\n\tfor _, innerFragmentName2 := range fieldsInfo2.fragmentNames {\n\t\tconflicts = rule.collectConflictsBetweenFragments(conflicts, areMutuallyExclusive, fragmentName1, innerFragmentName2)\n\t}\n\n\t// (G) Then collect conflicts between the second fragment and any nested\n\t// fragments spread in the first fragment.\n\tfor _, innerFragmentName1 := range fieldsInfo1.fragmentNames {\n\t\tconflicts = rule.collectConflictsBetweenFragments(conflicts, areMutuallyExclusive, innerFragmentName1, fragmentName2)\n\t}\n\n\treturn conflicts\n}\n\n// Find all conflicts found between two selection sets, including those found\n// via spreading in fragments. Called when determining if conflicts exist\n// between the sub-fields of two overlapping fields.\nfunc (rule *overlappingFieldsCanBeMergedRule) findConflictsBetweenSubSelectionSets(areMutuallyExclusive bool, parentType1 Named, selectionSet1 *ast.SelectionSet, parentType2 Named, selectionSet2 *ast.SelectionSet) []conflict {\n\tconflicts := []conflict{}\n\n\tfieldsInfo1 := rule.getFieldsAndFragmentNames(parentType1, selectionSet1)\n\tfieldsInfo2 := rule.getFieldsAndFragmentNames(parentType2, selectionSet2)\n\n\t// (H) First, collect all conflicts between these two collections of field.\n\tconflicts = rule.collectConflictsBetween(conflicts, areMutuallyExclusive, fieldsInfo1, fieldsInfo2)\n\n\t// (I) Then collect conflicts between the first collection of fields and\n\t// those referenced by each fragment name associated with the second.\n\tfor _, fragmentName2 := range fieldsInfo2.fragmentNames {\n\t\tconflicts = rule.collectConflictsBetweenFieldsAndFragment(conflicts, areMutuallyExclusive, fieldsInfo1, fragmentName2)\n\t}\n\n\t// (I) Then collect conflicts between the second collection of fields and\n\t// those referenced by each fragment name associated with the first.\n\tfor _, fragmentName1 := range fieldsInfo1.fragmentNames {\n\t\tconflicts = rule.collectConflictsBetweenFieldsAndFragment(conflicts, areMutuallyExclusive, fieldsInfo2, fragmentName1)\n\t}\n\n\t// (J) Also collect conflicts between any fragment names by the first and\n\t// fragment names by the second. This compares each item in the first set of\n\t// names to each item in the second set of names.\n\tfor _, fragmentName1 := range fieldsInfo1.fragmentNames {\n\t\tfor _, fragmentName2 := range fieldsInfo2.fragmentNames {\n\t\t\tconflicts = rule.collectConflictsBetweenFragments(conflicts, areMutuallyExclusive, fragmentName1, fragmentName2)\n\t\t}\n\t}\n\treturn conflicts\n}\n\n// Collect all Conflicts \"within\" one collection of fields.\nfunc (rule *overlappingFieldsCanBeMergedRule) collectConflictsWithin(conflicts []conflict, fieldsInfo *fieldsAndFragmentNames) []conflict {\n\t// A field map is a keyed collection, where each key represents a response\n\t// name and the value at that key is a list of all fields which provide that\n\t// response name. For every response name, if there are multiple fields, they\n\t// must be compared to find a potential conflict.\n\tfor _, responseName := range fieldsInfo.fieldsOrder {\n\t\tfields, ok := fieldsInfo.fieldMap[responseName]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\t// This compares every field in the list to every other field in this list\n\t\t// (except to itself). If the list only has one item, nothing needs to\n\t\t// be compared.\n\t\tif len(fields) <= 1 {\n\t\t\tcontinue\n\t\t}\n\t\tfor i := 0; i < len(fields); i++ {\n\t\t\tfor k := i + 1; k < len(fields); k++ {\n\t\t\t\t// within one collection is never mutually exclusive\n\t\t\t\tisMutuallyExclusive := false\n\t\t\t\tconflict := rule.findConflict(isMutuallyExclusive, responseName, fields[i], fields[k])\n\t\t\t\tif conflict != nil {\n\t\t\t\t\tconflicts = append(conflicts, *conflict)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn conflicts\n}\n\n// Collect all Conflicts between two collections of fields. This is similar to,\n// but different from the `collectConflictsWithin` function above. This check\n// assumes that `collectConflictsWithin` has already been called on each\n// provided collection of fields. This is true because this validator traverses\n// each individual selection set.\nfunc (rule *overlappingFieldsCanBeMergedRule) collectConflictsBetween(conflicts []conflict, parentFieldsAreMutuallyExclusive bool,\n\tfieldsInfo1 *fieldsAndFragmentNames,\n\tfieldsInfo2 *fieldsAndFragmentNames) []conflict {\n\t// A field map is a keyed collection, where each key represents a response\n\t// name and the value at that key is a list of all fields which provide that\n\t// response name. For any response name which appears in both provided field\n\t// maps, each field from the first field map must be compared to every field\n\t// in the second field map to find potential conflicts.\n\tfor _, responseName := range fieldsInfo1.fieldsOrder {\n\t\tfields1, ok1 := fieldsInfo1.fieldMap[responseName]\n\t\tfields2, ok2 := fieldsInfo2.fieldMap[responseName]\n\t\tif !ok1 || !ok2 {\n\t\t\tcontinue\n\t\t}\n\t\tfor i := 0; i < len(fields1); i++ {\n\t\t\tfor k := 0; k < len(fields2); k++ {\n\t\t\t\tconflict := rule.findConflict(parentFieldsAreMutuallyExclusive, responseName, fields1[i], fields2[k])\n\t\t\t\tif conflict != nil {\n\t\t\t\t\tconflicts = append(conflicts, *conflict)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn conflicts\n}\n\n// findConflict Determines if there is a conflict between two particular fields.\nfunc (rule *overlappingFieldsCanBeMergedRule) findConflict(parentFieldsAreMutuallyExclusive bool, responseName string, field *fieldDefPair, field2 *fieldDefPair) *conflict {\n\n\tparentType1 := field.ParentType\n\tast1 := field.Field\n\tdef1 := field.FieldDef\n\n\tparentType2 := field2.ParentType\n\tast2 := field2.Field\n\tdef2 := field2.FieldDef\n\n\t// If it is known that two fields could not possibly apply at the same\n\t// time, due to the parent types, then it is safe to permit them to diverge\n\t// in aliased field or arguments used as they will not present any ambiguity\n\t// by differing.\n\t// It is known that two parent types could never overlap if they are\n\t// different Object types. Interface or Union types might overlap - if not\n\t// in the current state of the schema, then perhaps in some future version,\n\t// thus may not safely diverge.\n\t_, isParentType1Object := parentType1.(*Object)\n\t_, isParentType2Object := parentType2.(*Object)\n\tareMutuallyExclusive := parentFieldsAreMutuallyExclusive || parentType1 != parentType2 && isParentType1Object && isParentType2Object\n\n\t// The return type for each field.\n\tvar type1 Type\n\tvar type2 Type\n\tif def1 != nil {\n\t\ttype1 = def1.Type\n\t}\n\tif def2 != nil {\n\t\ttype2 = def2.Type\n\t}\n\n\tif !areMutuallyExclusive {\n\t\t// Two aliases must refer to the same field.\n\t\tname1 := \"\"\n\t\tname2 := \"\"\n\n\t\tif ast1.Name != nil {\n\t\t\tname1 = ast1.Name.Value\n\t\t}\n\t\tif ast2.Name != nil {\n\t\t\tname2 = ast2.Name.Value\n\t\t}\n\t\tif name1 != name2 {\n\t\t\treturn &conflict{\n\t\t\t\tReason: conflictReason{\n\t\t\t\t\tName:    responseName,\n\t\t\t\t\tMessage: fmt.Sprintf(`%v and %v are different fields`, name1, name2),\n\t\t\t\t},\n\t\t\t\tFieldsLeft:  []ast.Node{ast1},\n\t\t\t\tFieldsRight: []ast.Node{ast2},\n\t\t\t}\n\t\t}\n\n\t\t// Two field calls must have the same arguments.\n\t\tif !sameArguments(ast1.Arguments, ast2.Arguments) {\n\t\t\treturn &conflict{\n\t\t\t\tReason: conflictReason{\n\t\t\t\t\tName:    responseName,\n\t\t\t\t\tMessage: `they have differing arguments`,\n\t\t\t\t},\n\t\t\t\tFieldsLeft:  []ast.Node{ast1},\n\t\t\t\tFieldsRight: []ast.Node{ast2},\n\t\t\t}\n\t\t}\n\t}\n\n\tif type1 != nil && type2 != nil && doTypesConflict(type1, type2) {\n\t\treturn &conflict{\n\t\t\tReason: conflictReason{\n\t\t\t\tName:    responseName,\n\t\t\t\tMessage: fmt.Sprintf(`they return conflicting types %v and %v`, type1, type2),\n\t\t\t},\n\t\t\tFieldsLeft:  []ast.Node{ast1},\n\t\t\tFieldsRight: []ast.Node{ast2},\n\t\t}\n\t}\n\n\t// Collect and compare sub-fields. Use the same \"visited fragment names\" list\n\t// for both collections so fields in a fragment reference are never\n\t// compared to themselves.\n\tselectionSet1 := ast1.SelectionSet\n\tselectionSet2 := ast2.SelectionSet\n\tif selectionSet1 != nil && selectionSet2 != nil {\n\t\tconflicts := rule.findConflictsBetweenSubSelectionSets(areMutuallyExclusive, GetNamed(type1), selectionSet1, GetNamed(type2), selectionSet2)\n\t\treturn subfieldConflicts(conflicts, responseName, ast1, ast2)\n\t}\n\treturn nil\n}\n\n// Given a selection set, return the collection of fields (a mapping of response\n// name to field ASTs and definitions) as well as a list of fragment names\n// referenced via fragment spreads.\nfunc (rule *overlappingFieldsCanBeMergedRule) getFieldsAndFragmentNames(parentType Named, selectionSet *ast.SelectionSet) *fieldsAndFragmentNames {\n\tif cached, ok := rule.cacheMap[selectionSet]; ok && cached != nil {\n\t\treturn cached\n\t}\n\n\tastAndDefs := astAndDefCollection{}\n\tfieldsOrder := []string{}\n\tfragmentNames := []string{}\n\tfragmentNamesMap := map[string]bool{}\n\n\tvar collectFieldsAndFragmentNames func(parentType Named, selectionSet *ast.SelectionSet)\n\tcollectFieldsAndFragmentNames = func(parentType Named, selectionSet *ast.SelectionSet) {\n\t\tfor _, selection := range selectionSet.Selections {\n\t\t\tswitch selection := selection.(type) {\n\t\t\tcase *ast.Field:\n\t\t\t\tfieldName := \"\"\n\t\t\t\tif selection.Name != nil {\n\t\t\t\t\tfieldName = selection.Name.Value\n\t\t\t\t}\n\t\t\t\tvar fieldDef *FieldDefinition\n\t\t\t\tif parentType, ok := parentType.(*Object); ok && parentType != nil {\n\t\t\t\t\tfieldDef, _ = parentType.Fields()[fieldName]\n\t\t\t\t}\n\t\t\t\tif parentType, ok := parentType.(*Interface); ok && parentType != nil {\n\t\t\t\t\tfieldDef, _ = parentType.Fields()[fieldName]\n\t\t\t\t}\n\n\t\t\t\tresponseName := fieldName\n\t\t\t\tif selection.Alias != nil {\n\t\t\t\t\tresponseName = selection.Alias.Value\n\t\t\t\t}\n\n\t\t\t\tfieldDefPairs, ok := astAndDefs[responseName]\n\t\t\t\tif !ok || fieldDefPairs == nil {\n\t\t\t\t\tfieldDefPairs = []*fieldDefPair{}\n\t\t\t\t\tfieldsOrder = append(fieldsOrder, responseName)\n\t\t\t\t}\n\n\t\t\t\tfieldDefPairs = append(fieldDefPairs, &fieldDefPair{\n\t\t\t\t\tParentType: parentType,\n\t\t\t\t\tField:      selection,\n\t\t\t\t\tFieldDef:   fieldDef,\n\t\t\t\t})\n\t\t\t\tastAndDefs[responseName] = fieldDefPairs\n\t\t\tcase *ast.FragmentSpread:\n\t\t\t\tfieldName := \"\"\n\t\t\t\tif selection.Name != nil {\n\t\t\t\t\tfieldName = selection.Name.Value\n\t\t\t\t}\n\t\t\t\tif val, ok := fragmentNamesMap[fieldName]; !ok || !val {\n\t\t\t\t\tfragmentNamesMap[fieldName] = true\n\t\t\t\t\tfragmentNames = append(fragmentNames, fieldName)\n\t\t\t\t}\n\t\t\tcase *ast.InlineFragment:\n\t\t\t\ttypeCondition := selection.TypeCondition\n\t\t\t\tinlineFragmentType := parentType\n\t\t\t\tif typeCondition != nil {\n\t\t\t\t\tttype, err := typeFromAST(*(rule.context.Schema()), typeCondition)\n\t\t\t\t\tif err == nil {\n\t\t\t\t\t\tinlineFragmentType, _ = ttype.(Named)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcollectFieldsAndFragmentNames(inlineFragmentType, selection.SelectionSet)\n\t\t\t}\n\t\t}\n\t}\n\tcollectFieldsAndFragmentNames(parentType, selectionSet)\n\n\tcached := &fieldsAndFragmentNames{\n\t\tfieldMap:      astAndDefs,\n\t\tfieldsOrder:   fieldsOrder,\n\t\tfragmentNames: fragmentNames,\n\t}\n\n\trule.cacheMap[selectionSet] = cached\n\treturn cached\n}\n\nfunc (rule *overlappingFieldsCanBeMergedRule) getReferencedFieldsAndFragmentNames(fragment *ast.FragmentDefinition) *fieldsAndFragmentNames {\n\t// Short-circuit building a type from the AST if possible.\n\tif cached, ok := rule.cacheMap[fragment.SelectionSet]; ok && cached != nil {\n\t\treturn cached\n\t}\n\tfragmentType, err := typeFromAST(*(rule.context.Schema()), fragment.TypeCondition)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn rule.getFieldsAndFragmentNames(fragmentType, fragment.SelectionSet)\n}\n\ntype conflictReason struct {\n\tName    string\n\tMessage interface{} // conflictReason || []conflictReason\n}\ntype conflict struct {\n\tReason      conflictReason\n\tFieldsLeft  []ast.Node\n\tFieldsRight []ast.Node\n}\n\n// a.k.a AstAndDef\ntype fieldDefPair struct {\n\tParentType Named\n\tField      *ast.Field\n\tFieldDef   *FieldDefinition\n}\ntype astAndDefCollection map[string][]*fieldDefPair\n\n// cache struct for fields, its order and fragments names\ntype fieldsAndFragmentNames struct {\n\tfieldMap      astAndDefCollection\n\tfieldsOrder   []string // stores the order of field names in fieldMap\n\tfragmentNames []string\n}\n\n// pairSet A way to keep track of pairs of things when the ordering of the pair does\n// not matter. We do this by maintaining a sort of double adjacency sets.\ntype pairSet struct {\n\tdata map[string]map[string]bool\n}\n\nfunc newPairSet() *pairSet {\n\treturn &pairSet{\n\t\tdata: map[string]map[string]bool{},\n\t}\n}\nfunc (pair *pairSet) Has(a string, b string, areMutuallyExclusive bool) bool {\n\tfirst, ok := pair.data[a]\n\tif !ok || first == nil {\n\t\treturn false\n\t}\n\tres, ok := first[b]\n\tif !ok {\n\t\treturn false\n\t}\n\t// areMutuallyExclusive being false is a superset of being true,\n\t// hence if we want to know if this PairSet \"has\" these two with no\n\t// exclusivity, we have to ensure it was added as such.\n\tif !areMutuallyExclusive {\n\t\treturn res == false\n\t}\n\treturn true\n}\nfunc (pair *pairSet) Add(a string, b string, areMutuallyExclusive bool) {\n\tpair.data = pairSetAdd(pair.data, a, b, areMutuallyExclusive)\n\tpair.data = pairSetAdd(pair.data, b, a, areMutuallyExclusive)\n}\nfunc pairSetAdd(data map[string]map[string]bool, a, b string, areMutuallyExclusive bool) map[string]map[string]bool {\n\tset, ok := data[a]\n\tif !ok || set == nil {\n\t\tset = map[string]bool{}\n\t}\n\tset[b] = areMutuallyExclusive\n\tdata[a] = set\n\treturn data\n}\n\nfunc sameArguments(args1 []*ast.Argument, args2 []*ast.Argument) bool {\n\tif len(args1) != len(args2) {\n\t\treturn false\n\t}\n\n\tfor _, arg1 := range args1 {\n\t\targ1Name := \"\"\n\t\tif arg1.Name != nil {\n\t\t\targ1Name = arg1.Name.Value\n\t\t}\n\n\t\tvar foundArgs2 *ast.Argument\n\t\tfor _, arg2 := range args2 {\n\t\t\targ2Name := \"\"\n\t\t\tif arg2.Name != nil {\n\t\t\t\targ2Name = arg2.Name.Value\n\t\t\t}\n\t\t\tif arg1Name == arg2Name {\n\t\t\t\tfoundArgs2 = arg2\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif foundArgs2 == nil {\n\t\t\treturn false\n\t\t}\n\t\tif sameValue(arg1.Value, foundArgs2.Value) == false {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc sameValue(value1 ast.Value, value2 ast.Value) bool {\n\tif value1 == nil && value2 == nil {\n\t\treturn true\n\t}\n\tval1 := printer.Print(value1)\n\tval2 := printer.Print(value2)\n\n\treturn val1 == val2\n}\n\n// Two types conflict if both types could not apply to a value simultaneously.\n// Composite types are ignored as their individual field types will be compared\n// later recursively. However List and Non-Null types must match.\nfunc doTypesConflict(type1 Output, type2 Output) bool {\n\tif type1, ok := type1.(*List); ok {\n\t\tif type2, ok := type2.(*List); ok {\n\t\t\treturn doTypesConflict(type1.OfType, type2.OfType)\n\t\t}\n\t\treturn true\n\t}\n\tif type2, ok := type2.(*List); ok {\n\t\tif type1, ok := type1.(*List); ok {\n\t\t\treturn doTypesConflict(type1.OfType, type2.OfType)\n\t\t}\n\t\treturn true\n\t}\n\tif type1, ok := type1.(*NonNull); ok {\n\t\tif type2, ok := type2.(*NonNull); ok {\n\t\t\treturn doTypesConflict(type1.OfType, type2.OfType)\n\t\t}\n\t\treturn true\n\t}\n\tif type2, ok := type2.(*NonNull); ok {\n\t\tif type1, ok := type1.(*NonNull); ok {\n\t\t\treturn doTypesConflict(type1.OfType, type2.OfType)\n\t\t}\n\t\treturn true\n\t}\n\tif IsLeafType(type1) || IsLeafType(type2) {\n\t\treturn type1 != type2\n\t}\n\treturn false\n}\n\n// subfieldConflicts Given a series of Conflicts which occurred between two sub-fields, generate a single Conflict.\nfunc subfieldConflicts(conflicts []conflict, responseName string, ast1 *ast.Field, ast2 *ast.Field) *conflict {\n\tif len(conflicts) > 0 {\n\t\tconflictReasons := []conflictReason{}\n\t\tconflictFieldsLeft := []ast.Node{ast1}\n\t\tconflictFieldsRight := []ast.Node{ast2}\n\t\tfor _, c := range conflicts {\n\t\t\tconflictReasons = append(conflictReasons, c.Reason)\n\t\t\tconflictFieldsLeft = append(conflictFieldsLeft, c.FieldsLeft...)\n\t\t\tconflictFieldsRight = append(conflictFieldsRight, c.FieldsRight...)\n\t\t}\n\n\t\treturn &conflict{\n\t\t\tReason: conflictReason{\n\t\t\t\tName:    responseName,\n\t\t\t\tMessage: conflictReasons,\n\t\t\t},\n\t\t\tFieldsLeft:  conflictFieldsLeft,\n\t\t\tFieldsRight: conflictFieldsRight,\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "rules_overlapping_fields_can_be_merged_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_OverlappingFieldsCanBeMerged_UniqueFields(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment uniqueFields on Dog {\n        name\n        nickname\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_IdenticalFields(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment mergeIdenticalFields on Dog {\n        name\n        name\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_IdenticalFieldsWithIdenticalArgs(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment mergeIdenticalFieldsWithIdenticalArgs on Dog {\n        doesKnowCommand(dogCommand: SIT)\n        doesKnowCommand(dogCommand: SIT)\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_IdenticalFieldsWithMultipleIdenticalArgs(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment mergeIdenticalFieldsWithIdenticalArgs on Dog {\n        doesKnowCommand(dogCommand: SIT nextDogCommand: DOWN)\n        doesKnowCommand(dogCommand: SIT nextDogCommand: DOWN)\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_IdenticalFieldsWithIdenticalDirectives(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment mergeSameFieldsWithSameDirectives on Dog {\n        name @include(if: true)\n        name @include(if: true)\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_DifferentArgsWithDifferentAliases(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment differentArgsWithDifferentAliases on Dog {\n        knowsSit: doesKnowCommand(dogCommand: SIT)\n        knowsDown: doesKnowCommand(dogCommand: DOWN)\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_DifferentDirectivesWithDifferentAliases(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment differentDirectivesWithDifferentAliases on Dog {\n        nameIfTrue: name @include(if: true)\n        nameIfFalse: name @include(if: false)\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_DifferentSkipIncludeDirectivesAccepted(t *testing.T) {\n\t// Note: Differing skip/include directives don't create an ambiguous return\n\t// value and are acceptable in conditions where differing runtime values\n\t// may have the same desired effect of including or skipping a field.\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment differentDirectivesWithDifferentAliases on Dog {\n        name @include(if: true)\n        name @include(if: false)\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_SameAliasesWithDifferentFieldTargets(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment sameAliasesWithDifferentFieldTargets on Dog {\n        fido: name\n        fido: nickname\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"fido\" conflict because name and nickname are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9, 4, 9),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_SameAliasesAllowedOnNonOverlappingFields(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment sameAliasesWithDifferentFieldTargets on Pet {\n        ... on Dog {\n          name\n        }\n        ... on Cat {\n          name: nickname\n        }\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_AliasMaskingDirectFieldAccess(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment aliasMaskingDirectFieldAccess on Dog {\n        name: nickname\n        name\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"name\" conflict because nickname and name are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9, 4, 9),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_DifferentArgs_SecondAddsAnArgument(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment conflictingArgs on Dog {\n        doesKnowCommand\n        doesKnowCommand(dogCommand: HEEL)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"doesKnowCommand\" conflict because they have differing arguments. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9, 4, 9),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_DifferentArgs_SecondMissingAnArgument(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment conflictingArgs on Dog {\n        doesKnowCommand(dogCommand: SIT)\n        doesKnowCommand\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"doesKnowCommand\" conflict because they have differing arguments. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9, 4, 9),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ConflictingArgs(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment conflictingArgs on Dog {\n        doesKnowCommand(dogCommand: SIT)\n        doesKnowCommand(dogCommand: HEEL)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"doesKnowCommand\" conflict because they have differing arguments. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9, 4, 9),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_AllowDifferentArgsWhereNoConflictIsPossible(t *testing.T) {\n\t// This is valid since no object can be both a \"Dog\" and a \"Cat\", thus\n\t// these fields can never overlap.\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      fragment conflictingArgs on Pet {\n        ... on Dog {\n          name(surname: true)\n        }\n        ... on Cat {\n          name\n        }\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_EncountersConflictInFragments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        ...A\n        ...B\n      }\n      fragment A on Type {\n        x: a\n      }\n      fragment B on Type {\n        x: b\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"x\" conflict because a and b are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t7, 9, 10, 9),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReportsEachConflictOnce(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        f1 {\n          ...A\n          ...B\n        }\n        f2 {\n          ...B\n          ...A\n        }\n        f3 {\n          ...A\n          ...B\n          x: c\n        }\n      }\n      fragment A on Type {\n        x: a\n      }\n      fragment B on Type {\n        x: b\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"x\" conflict because a and b are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t18, 9, 21, 9),\n\t\ttestutil.RuleError(`Fields \"x\" conflict because c and a are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t14, 11, 18, 9),\n\t\ttestutil.RuleError(`Fields \"x\" conflict because c and b are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t14, 11, 21, 9),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_DeepConflict(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        field {\n          x: a\n        },\n        field {\n          x: b\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"field\" conflict because subfields \"x\" conflict because a and b are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9,\n\t\t\t4, 11,\n\t\t\t6, 9,\n\t\t\t7, 11),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_DeepConflictWithMultipleIssues(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        field {\n          x: a\n          y: c\n        },\n        field {\n          x: b\n          y: d\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"field\" conflict because subfields \"x\" conflict because a and b are different fields and `+\n\t\t\t`subfields \"y\" conflict because c and d are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9,\n\t\t\t4, 11,\n\t\t\t5, 11,\n\t\t\t7, 9,\n\t\t\t8, 11,\n\t\t\t9, 11),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_VeryDeepConflict(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        field {\n          deepField {\n            x: a\n          }\n        },\n        field {\n          deepField {\n            x: b\n          }\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"field\" conflict because subfields \"deepField\" conflict because subfields \"x\" conflict because `+\n\t\t\t`a and b are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9,\n\t\t\t4, 11,\n\t\t\t5, 13,\n\t\t\t8, 9,\n\t\t\t9, 11,\n\t\t\t10, 13),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReportsDeepConflictToNearestCommonAncestor(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        field {\n          deepField {\n            x: a\n          }\n          deepField {\n            x: b\n          }\n        },\n        field {\n          deepField {\n            y\n          }\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"deepField\" conflict because subfields \"x\" conflict because `+\n\t\t\t`a and b are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t4, 11,\n\t\t\t5, 13,\n\t\t\t7, 11,\n\t\t\t8, 13),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReportsDeepConflictToNearestCommonAncestorInFragments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        field {\n          ...F\n        }\n        field {\n          ...F\n        }\n      }\n      fragment F on T {\n        deepField {\n          deeperField {\n            x: a\n          }\n          deeperField {\n            x: b\n          }\n        },\n        deepField {\n          deeperField {\n            y\n          }\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"deeperField\" conflict because subfields \"x\" conflict because `+\n\t\t\t`a and b are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t12, 11,\n\t\t\t13, 13,\n\t\t\t15, 11,\n\t\t\t16, 13),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReportsDeepConflictInNestedFragments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        field {\n          ...F\n        }\n        field {\n          ...I\n        }\n      }\n      fragment F on T {\n        x: a\n        ...G\n      }\n      fragment G on T {\n        y: c\n      }\n      fragment I on T {\n        y: d\n        ...J\n      }\n      fragment J on T {\n        x: b\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"field\" conflict because `+\n\t\t\t`subfields \"x\" conflict because a and b are different fields and `+\n\t\t\t`subfields \"y\" conflict because c and d are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t3, 9,\n\t\t\t11, 9,\n\t\t\t15, 9,\n\t\t\t6, 9,\n\t\t\t22, 9,\n\t\t\t18, 9),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_IgnoresUnknownFragments(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `\n    {\n      field\n      ...Unknown\n      ...Known\n    }\n\n    fragment Known on T {\n      field\n      ...OtherUnknown\n    }\n    `)\n}\n\nvar someBoxInterface *graphql.Interface\nvar stringBoxObject *graphql.Object\nvar intBoxObject *graphql.Object\nvar schema graphql.Schema\n\nfunc init() {\n\tsomeBoxInterface = graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"SomeBox\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn stringBoxObject\n\t\t},\n\t\tFields: graphql.FieldsThunk(func() graphql.Fields {\n\t\t\treturn graphql.Fields{\n\t\t\t\t\"deepBox\": &graphql.Field{\n\t\t\t\t\tType: someBoxInterface,\n\t\t\t\t},\n\t\t\t\t\"unrelatedField\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t}\n\t\t}),\n\t})\n\tstringBoxObject = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"StringBox\",\n\t\tInterfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {\n\t\t\treturn []*graphql.Interface{someBoxInterface}\n\t\t}),\n\t\tFields: graphql.FieldsThunk(func() graphql.Fields {\n\t\t\treturn graphql.Fields{\n\t\t\t\t\"scalar\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"deepBox\": &graphql.Field{\n\t\t\t\t\tType: stringBoxObject,\n\t\t\t\t},\n\t\t\t\t\"unrelatedField\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"listStringBox\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(stringBoxObject),\n\t\t\t\t},\n\t\t\t\t\"stringBox\": &graphql.Field{\n\t\t\t\t\tType: stringBoxObject,\n\t\t\t\t},\n\t\t\t\t\"intBox\": &graphql.Field{\n\t\t\t\t\tType: intBoxObject,\n\t\t\t\t},\n\t\t\t}\n\t\t}),\n\t})\n\tintBoxObject = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"IntBox\",\n\t\tInterfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {\n\t\t\treturn []*graphql.Interface{someBoxInterface}\n\t\t}),\n\t\tFields: graphql.FieldsThunk(func() graphql.Fields {\n\t\t\treturn graphql.Fields{\n\t\t\t\t\"scalar\": &graphql.Field{\n\t\t\t\t\tType: graphql.Int,\n\t\t\t\t},\n\t\t\t\t\"deepBox\": &graphql.Field{\n\t\t\t\t\tType: someBoxInterface,\n\t\t\t\t},\n\t\t\t\t\"unrelatedField\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t\t\"listStringBox\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewList(stringBoxObject),\n\t\t\t\t},\n\t\t\t\t\"stringBox\": &graphql.Field{\n\t\t\t\t\tType: stringBoxObject,\n\t\t\t\t},\n\t\t\t\t\"intBox\": &graphql.Field{\n\t\t\t\t\tType: intBoxObject,\n\t\t\t\t},\n\t\t\t}\n\t\t}),\n\t})\n\tvar nonNullStringBox1Interface = graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"NonNullStringBox1\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn stringBoxObject\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"scalar\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\tNonNullStringBox1Impl := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"NonNullStringBox1Impl\",\n\t\tInterfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {\n\t\t\treturn []*graphql.Interface{someBoxInterface, nonNullStringBox1Interface}\n\t\t}),\n\t\tFields: graphql.Fields{\n\t\t\t\"scalar\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t},\n\t\t\t\"unrelatedField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"deepBox\": &graphql.Field{\n\t\t\t\tType: someBoxInterface,\n\t\t\t},\n\t\t},\n\t})\n\tvar nonNullStringBox2Interface = graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"NonNullStringBox2\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn stringBoxObject\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"scalar\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\tNonNullStringBox2Impl := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"NonNullStringBox2Impl\",\n\t\tInterfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {\n\t\t\treturn []*graphql.Interface{someBoxInterface, nonNullStringBox2Interface}\n\t\t}),\n\t\tFields: graphql.Fields{\n\t\t\t\"scalar\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t},\n\t\t\t\"unrelatedField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"deepBox\": &graphql.Field{\n\t\t\t\tType: someBoxInterface,\n\t\t\t},\n\t\t},\n\t})\n\n\tvar connectionObject = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Connection\",\n\t\tFields: graphql.Fields{\n\t\t\t\"edges\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(graphql.NewObject(graphql.ObjectConfig{\n\t\t\t\t\tName: \"Edge\",\n\t\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\t\"node\": &graphql.Field{\n\t\t\t\t\t\t\tType: graphql.NewObject(graphql.ObjectConfig{\n\t\t\t\t\t\t\t\tName: \"Node\",\n\t\t\t\t\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\t\t\t\t\"id\": &graphql.Field{\n\t\t\t\t\t\t\t\t\t\tType: graphql.ID,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"name\": &graphql.Field{\n\t\t\t\t\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})),\n\t\t\t},\n\t\t},\n\t})\n\tvar err error\n\tschema, err = graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"QueryRoot\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"someBox\": &graphql.Field{\n\t\t\t\t\tType: someBoxInterface,\n\t\t\t\t},\n\t\t\t\t\"connection\": &graphql.Field{\n\t\t\t\t\tType: connectionObject,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tTypes: []graphql.Type{\n\t\t\tintBoxObject,\n\t\t\tstringBoxObject,\n\t\t\tNonNullStringBox1Impl,\n\t\t\tNonNullStringBox2Impl,\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_ConflictingReturnTypesWhichPotentiallyOverlap(t *testing.T) {\n\t// This is invalid since an object could potentially be both the Object\n\t// type IntBox and the interface type NonNullStringBox1. While that\n\t// condition does not exist in the current schema, the schema could\n\t// expand in the future to allow this. Thus it is invalid.\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ...on IntBox {\n              scalar\n            }\n            ...on NonNullStringBox1 {\n              scalar\n            }\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"scalar\" conflict because they return conflicting types Int and String!. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t5, 15,\n\t\t\t8, 15),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_CompatibleReturnShapesOnDifferentReturnTypes(t *testing.T) {\n\t// In this case `deepBox` returns `SomeBox` in the first usage, and\n\t// `StringBox` in the second usage. These return types are not the same!\n\t// however this is valid because the return *shapes* are compatible.\n\ttestutil.ExpectPassesRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n      {\n        someBox {\n          ... on SomeBox {\n            deepBox {\n              unrelatedField\n            }\n          }\n          ... on StringBox {\n            deepBox {\n              unrelatedField\n            }\n          }\n        }\n      }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_DisallowsDifferingReturnTypesDespiteNoOverlap(t *testing.T) {\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ... on IntBox {\n              scalar\n            }\n            ... on StringBox {\n              scalar\n            }\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"scalar\" conflict because they return conflicting types Int and String. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t5, 15,\n\t\t\t8, 15),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_ReportsCorrectlyWhenANonExclusiveFollosAnExclusive(t *testing.T) {\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ... on IntBox {\n              deepBox {\n                ...X\n              }\n            }\n          }\n          someBox {\n            ... on StringBox {\n              deepBox {\n                ...Y\n              }\n            }\n          }\n          memoed: someBox {\n            ... on IntBox {\n              deepBox {\n                ...X\n              }\n            }\n          }\n          memoed: someBox {\n            ... on StringBox {\n              deepBox {\n                ...Y\n              }\n            }\n          }\n          other: someBox {\n            ...X\n          }\n          other: someBox {\n            ...Y\n          }\n        }\n        fragment X on SomeBox {\n          scalar\n        }\n        fragment Y on SomeBox {\n          scalar: unrelatedField\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"other\" conflict because subfields \"scalar\" conflict `+\n\t\t\t`because scalar and unrelatedField are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t31, 11,\n\t\t\t39, 11,\n\t\t\t34, 11,\n\t\t\t42, 11),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_DisallowsDifferingReturnTypeNullabilityDespiteNoOverlap(t *testing.T) {\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ... on NonNullStringBox1 {\n              scalar\n            }\n            ... on StringBox {\n              scalar\n            }\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"scalar\" conflict because they return conflicting types String! and String. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t5, 15,\n\t\t\t8, 15),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_DisallowsDifferingReturnTypeListDespiteNoOverlap(t *testing.T) {\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ... on IntBox {\n              box: listStringBox {\n                scalar\n              }\n            }\n            ... on StringBox {\n              box: stringBox {\n                scalar\n              }\n            }\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"box\" conflict because they return conflicting types [StringBox] and StringBox. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t5, 15,\n\t\t\t10, 15),\n\t})\n\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ... on IntBox {\n              box: stringBox {\n                scalar\n              }\n            }\n            ... on StringBox {\n              box: listStringBox {\n                scalar\n              }\n            }\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"box\" conflict because they return conflicting types StringBox and [StringBox]. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t5, 15,\n\t\t\t10, 15),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_DisallowsDifferingSubfields(t *testing.T) {\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ... on IntBox {\n              box: stringBox {\n                val: scalar\n                val: unrelatedField\n              }\n            }\n            ... on StringBox {\n              box: stringBox {\n                val: scalar\n              }\n            }\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"val\" conflict because scalar and unrelatedField are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t6, 17,\n\t\t\t7, 17),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_DisallowsDifferingDeepReturnTypesDespiteNoOverlap(t *testing.T) {\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ... on IntBox {\n              box: stringBox {\n                scalar\n              }\n            }\n            ... on StringBox {\n              box: intBox {\n                scalar\n              }\n            }\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"box\" conflict because subfields \"scalar\" conflict because they return conflicting types String and Int. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t5, 15,\n\t\t\t6, 17,\n\t\t\t10, 15,\n\t\t\t11, 17),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_AllowsNonConflictingOverlappingTypes(t *testing.T) {\n\ttestutil.ExpectPassesRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ... on IntBox {\n              scalar: unrelatedField\n            }\n            ... on StringBox {\n              scalar\n            }\n          }\n        }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_SameWrappedScalarReturnTypes(t *testing.T) {\n\ttestutil.ExpectPassesRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ...on NonNullStringBox1 {\n              scalar\n            }\n            ...on NonNullStringBox2 {\n              scalar\n            }\n          }\n        }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_AllowsInlineTypelessFragments(t *testing.T) {\n\ttestutil.ExpectPassesRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          a\n          ... {\n            a\n          }\n        }\n    `)\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_ComparesDeepTypesIncludingList(t *testing.T) {\n\ttestutil.ExpectFailsRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          connection {\n            ...edgeID\n            edges {\n              node {\n                id: name\n              }\n            }\n          }\n        }\n\n        fragment edgeID on Connection {\n          edges {\n            node {\n              id\n            }\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fields \"edges\" conflict because subfields \"node\" conflict because subfields \"id\" conflict because `+\n\t\t\t`name and id are different fields. `+\n\t\t\t`Use different aliases on the fields to fetch both if this was intentional.`,\n\t\t\t5, 13,\n\t\t\t6, 15,\n\t\t\t7, 17,\n\t\t\t14, 11,\n\t\t\t15, 13,\n\t\t\t16, 15),\n\t})\n}\nfunc TestValidate_OverlappingFieldsCanBeMerged_ReturnTypesMustBeUnambiguous_IgnoresUnknownTypes(t *testing.T) {\n\ttestutil.ExpectPassesRuleWithSchema(t, &schema, graphql.OverlappingFieldsCanBeMergedRule, `\n        {\n          someBox {\n            ...on UnknownType {\n              scalar\n            }\n            ...on NonNullStringBox2 {\n              scalar\n            }\n          }\n        }\n    `)\n}\n\nfunc TestValidate_OverlappingFieldsCanBeMerged_NilCrash(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.OverlappingFieldsCanBeMergedRule, `subscription {e}`)\n}\n"
  },
  {
    "path": "rules_possible_fragment_spreads_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_PossibleFragmentSpreads_OfTheSameObject(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment objectWithinObject on Dog { ...dogFragment }\n      fragment dogFragment on Dog { barkVolume }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_OfTheSameObjectWithInlineFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment objectWithinObjectAnon on Dog { ... on Dog { barkVolume } }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_ObjectIntoAnImplementedInterface(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment objectWithinInterface on Pet { ...dogFragment }\n      fragment dogFragment on Dog { barkVolume }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_ObjectIntoContainingUnion(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment objectWithinUnion on CatOrDog { ...dogFragment }\n      fragment dogFragment on Dog { barkVolume }\n    `)\n}\n\nfunc TestValidate_PossibleFragmentSpreads_UnionIntoContainedObject(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment unionWithinObject on Dog { ...catOrDogFragment }\n      fragment catOrDogFragment on CatOrDog { __typename }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_UnionIntoOverlappingInterface(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment unionWithinInterface on Pet { ...catOrDogFragment }\n      fragment catOrDogFragment on CatOrDog { __typename }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_UnionIntoOverlappingUnion(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment unionWithinUnion on DogOrHuman { ...catOrDogFragment }\n      fragment catOrDogFragment on CatOrDog { __typename }\n    `)\n}\n\nfunc TestValidate_PossibleFragmentSpreads_InterfaceIntoImplementedObject(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment interfaceWithinObject on Dog { ...petFragment }\n      fragment petFragment on Pet { name }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_InterfaceIntoOverlappingInterface(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment interfaceWithinInterface on Pet { ...beingFragment }\n      fragment beingFragment on Being { name }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_InterfaceIntoOverlappingInterfaceInInlineFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment interfaceWithinInterface on Pet { ... on Being { name } }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_InterfaceIntoOverlappingUnion(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment interfaceWithinUnion on CatOrDog { ...petFragment }\n      fragment petFragment on Pet { name }\n    `)\n}\nfunc TestValidate_PossibleFragmentSpreads_DifferentObjectIntoObject(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidObjectWithinObject on Cat { ...dogFragment }\n      fragment dogFragment on Dog { barkVolume }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"dogFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"Cat\" can never be of type \"Dog\".`, 2, 51),\n\t})\n}\nfunc TestValidate_PossibleFragmentSpreads_DifferentObjectIntoObjectInInlineFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidObjectWithinObjectAnon on Cat {\n        ... on Dog { barkVolume }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment cannot be spread here as objects of `+\n\t\t\t`type \"Cat\" can never be of type \"Dog\".`, 3, 9),\n\t})\n}\n\nfunc TestValidate_PossibleFragmentSpreads_ObjectIntoNotImplementingInterface(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidObjectWithinInterface on Pet { ...humanFragment }\n      fragment humanFragment on Human { pets { name } }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"humanFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"Pet\" can never be of type \"Human\".`, 2, 54),\n\t})\n}\nfunc TestValidate_PossibleFragmentSpreads_ObjectIntoNotContainingUnion(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidObjectWithinUnion on CatOrDog { ...humanFragment }\n      fragment humanFragment on Human { pets { name } }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"humanFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"CatOrDog\" can never be of type \"Human\".`, 2, 55),\n\t})\n}\n\nfunc TestValidate_PossibleFragmentSpreads_UnionIntoNotContainedObject(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidUnionWithinObject on Human { ...catOrDogFragment }\n      fragment catOrDogFragment on CatOrDog { __typename }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"catOrDogFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"Human\" can never be of type \"CatOrDog\".`, 2, 52),\n\t})\n}\nfunc TestValidate_PossibleFragmentSpreads_UnionIntoNonOverlappingInterface(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidUnionWithinInterface on Pet { ...humanOrAlienFragment }\n      fragment humanOrAlienFragment on HumanOrAlien { __typename }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"humanOrAlienFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"Pet\" can never be of type \"HumanOrAlien\".`, 2, 53),\n\t})\n}\nfunc TestValidate_PossibleFragmentSpreads_UnionIntoNonOverlappingUnion(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidUnionWithinUnion on CatOrDog { ...humanOrAlienFragment }\n      fragment humanOrAlienFragment on HumanOrAlien { __typename }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"humanOrAlienFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"CatOrDog\" can never be of type \"HumanOrAlien\".`, 2, 54),\n\t})\n}\n\nfunc TestValidate_PossibleFragmentSpreads_InterfaceIntoNonImplementingObject(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidInterfaceWithinObject on Cat { ...intelligentFragment }\n      fragment intelligentFragment on Intelligent { iq }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"intelligentFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"Cat\" can never be of type \"Intelligent\".`, 2, 54),\n\t})\n}\nfunc TestValidate_PossibleFragmentSpreads_InterfaceIntoNonOverlappingInterface(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidInterfaceWithinInterface on Pet {\n        ...intelligentFragment\n      }\n      fragment intelligentFragment on Intelligent { iq }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"intelligentFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"Pet\" can never be of type \"Intelligent\".`, 3, 9),\n\t})\n}\nfunc TestValidate_PossibleFragmentSpreads_InterfaceIntoNonOverlappingInterfaceInInlineFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidInterfaceWithinInterfaceAnon on Pet {\n        ...on Intelligent { iq }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment cannot be spread here as objects of `+\n\t\t\t`type \"Pet\" can never be of type \"Intelligent\".`, 3, 9),\n\t})\n}\nfunc TestValidate_PossibleFragmentSpreads_InterfaceIntoNonOverlappingUnion(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.PossibleFragmentSpreadsRule, `\n      fragment invalidInterfaceWithinUnion on HumanOrAlien { ...petFragment }\n      fragment petFragment on Pet { name }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Fragment \"petFragment\" cannot be spread here as objects of `+\n\t\t\t`type \"HumanOrAlien\" can never be of type \"Pet\".`, 2, 62),\n\t})\n}\n"
  },
  {
    "path": "rules_provided_non_null_arguments_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_ProvidedNonNullArguments_IgnoresUnknownArguments(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n      {\n        dog {\n          isHousetrained(unknownArgument: true)\n        }\n      }\n    `)\n}\n\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_ArgOnOptionalArg(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          dog {\n            isHousetrained(atOtherHomes: true)\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_NoArgOnOptionalArg(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          dog {\n            isHousetrained\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_MultipleArgs(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleReqs(req1: 1, req2: 2)\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_MultipleArgsReverseOrder(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleReqs(req2: 2, req1: 1)\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_NoArgsOnMultipleOptional(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleOpts\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_OneArgOnMultipleOptional(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleOpts(opt1: 1)\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_SecondArgOnMultipleOptional(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleOpts(opt2: 1)\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_MultipleReqsOnMixedList(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleOptAndReq(req1: 3, req2: 4)\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_MultipleReqsAndOneOptOnMixedList(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleOptAndReq(req1: 3, req2: 4, opt1: 5)\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_AllReqsAndOptsOnMixedList(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleOptAndReq(req1: 3, req2: 4, opt1: 5, opt2: 6)\n          }\n        }\n    `)\n}\n\nfunc TestValidate_ProvidedNonNullArguments_InvalidNonNullableValue_MissingOneNonNullableArgument(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleReqs(req2: 2)\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"multipleReqs\" argument \"req1\" of type \"Int!\" is required but not provided.`, 4, 13),\n\t})\n}\nfunc TestValidate_ProvidedNonNullArguments_InvalidNonNullableValue_MissingMultipleNonNullableArguments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleReqs\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"multipleReqs\" argument \"req1\" of type \"Int!\" is required but not provided.`, 4, 13),\n\t\ttestutil.RuleError(`Field \"multipleReqs\" argument \"req2\" of type \"Int!\" is required but not provided.`, 4, 13),\n\t})\n}\nfunc TestValidate_ProvidedNonNullArguments_InvalidNonNullableValue_IncorrectValueAndMissingArgument(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          complicatedArgs {\n            multipleReqs(req1: \"one\")\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"multipleReqs\" argument \"req2\" of type \"Int!\" is required but not provided.`, 4, 13),\n\t})\n}\n\nfunc TestValidate_ProvidedNonNullArguments_DirectiveArguments_IgnoresUnknownDirectives(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          dog @unknown\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_DirectiveArguments_WithDirectivesOfValidTypes(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          dog @include(if: true) {\n            name\n          }\n          human @skip(if: false) {\n            name\n          }\n        }\n    `)\n}\nfunc TestValidate_ProvidedNonNullArguments_DirectiveArguments_WithDirectiveWithMissingTypes(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ProvidedNonNullArgumentsRule, `\n        {\n          dog @include {\n            name @skip\n          }\n        }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Directive \"@include\" argument \"if\" of type \"Boolean!\" is required but not provided.`, 3, 15),\n\t\ttestutil.RuleError(`Directive \"@skip\" argument \"if\" of type \"Boolean!\" is required but not provided.`, 4, 18),\n\t})\n}\n"
  },
  {
    "path": "rules_scalar_leafs_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_ScalarLeafs_ValidScalarSelection(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ScalarLeafsRule, `\n      fragment scalarSelection on Dog {\n        barks\n      }\n    `)\n}\nfunc TestValidate_ScalarLeafs_ObjectTypeMissingSelection(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ScalarLeafsRule, `\n      query directQueryOnObjectWithoutSubFields {\n        human\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"human\" of type \"Human\" must have a sub selection.`, 3, 9),\n\t})\n}\nfunc TestValidate_ScalarLeafs_InterfaceTypeMissingSelection(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ScalarLeafsRule, `\n      {\n        human { pets }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"pets\" of type \"[Pet]\" must have a sub selection.`, 3, 17),\n\t})\n}\nfunc TestValidate_ScalarLeafs_ValidScalarSelectionWithArgs(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.ScalarLeafsRule, `\n      fragment scalarSelectionWithArgs on Dog {\n        doesKnowCommand(dogCommand: SIT)\n      }\n    `)\n}\n\nfunc TestValidate_ScalarLeafs_ScalarSelectionNotAllowedOnBoolean(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ScalarLeafsRule, `\n      fragment scalarSelectionsNotAllowedOnBoolean on Dog {\n        barks { sinceWhen }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"barks\" of type \"Boolean\" must not have a sub selection.`, 3, 15),\n\t})\n}\nfunc TestValidate_ScalarLeafs_ScalarSelectionNotAllowedOnEnum(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ScalarLeafsRule, `\n      fragment scalarSelectionsNotAllowedOnEnum on Cat {\n        furColor { inHexdec }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"furColor\" of type \"FurColor\" must not have a sub selection.`, 3, 18),\n\t})\n}\nfunc TestValidate_ScalarLeafs_ScalarSelectionNotAllowedWithArgs(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ScalarLeafsRule, `\n      fragment scalarSelectionsNotAllowedWithArgs on Dog {\n        doesKnowCommand(dogCommand: SIT) { sinceWhen }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"doesKnowCommand\" of type \"Boolean\" must not have a sub selection.`, 3, 42),\n\t})\n}\nfunc TestValidate_ScalarLeafs_ScalarSelectionNotAllowedWithDirectives(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ScalarLeafsRule, `\n      fragment scalarSelectionsNotAllowedWithDirectives on Dog {\n        name @include(if: true) { isAlsoHumanName }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"name\" of type \"String\" must not have a sub selection.`, 3, 33),\n\t})\n}\nfunc TestValidate_ScalarLeafs_ScalarSelectionNotAllowedWithDirectivesAndArgs(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.ScalarLeafsRule, `\n      fragment scalarSelectionsNotAllowedWithDirectivesAndArgs on Dog {\n        doesKnowCommand(dogCommand: SIT) @include(if: true) { sinceWhen }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Field \"doesKnowCommand\" of type \"Boolean\" must not have a sub selection.`, 3, 61),\n\t})\n}\n"
  },
  {
    "path": "rules_unique_argument_names_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_UniqueArgumentNames_NoArgumentsOnField(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_NoArgumentsOnDirective(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field @directive\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_ArgumentOnField(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field(arg: \"value\")\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_ArgumentOnDirective(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field @directive(arg: \"value\")\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_SameArgumentOnTwoFields(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        one: field(arg: \"value\")\n        two: field(arg: \"value\")\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_SameArgumentOnFieldAndDirective(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field(arg: \"value\") @directive(arg: \"value\")\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_SameArgumentOnTwoDirectives(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field @directive1(arg: \"value\") @directive2(arg: \"value\")\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_MultipleFieldArguments(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field(arg1: \"value\", arg2: \"value\", arg3: \"value\")\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_MultipleDirectiveArguments(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field @directive(arg1: \"value\", arg2: \"value\", arg3: \"value\")\n      }\n    `)\n}\nfunc TestValidate_UniqueArgumentNames_DuplicateFieldArguments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field(arg1: \"value\", arg1: \"value\")\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can be only one argument named \"arg1\".`, 3, 15, 3, 30),\n\t})\n}\nfunc TestValidate_UniqueArgumentNames_ManyDuplicateFieldArguments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field(arg1: \"value\", arg1: \"value\", arg1: \"value\")\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can be only one argument named \"arg1\".`, 3, 15, 3, 30),\n\t\ttestutil.RuleError(`There can be only one argument named \"arg1\".`, 3, 15, 3, 45),\n\t})\n}\nfunc TestValidate_UniqueArgumentNames_DuplicateDirectiveArguments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field @directive(arg1: \"value\", arg1: \"value\")\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can be only one argument named \"arg1\".`, 3, 26, 3, 41),\n\t})\n}\nfunc TestValidate_UniqueArgumentNames_ManyDuplicateDirectiveArguments(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueArgumentNamesRule, `\n      {\n        field @directive(arg1: \"value\", arg1: \"value\", arg1: \"value\")\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can be only one argument named \"arg1\".`, 3, 26, 3, 41),\n\t\ttestutil.RuleError(`There can be only one argument named \"arg1\".`, 3, 26, 3, 56),\n\t})\n}\n"
  },
  {
    "path": "rules_unique_fragment_names_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_UniqueFragmentNames_NoFragments(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueFragmentNamesRule, `\n      {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueFragmentNames_OneFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueFragmentNamesRule, `\n      {\n        ...fragA\n      }\n\n      fragment fragA on Type {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueFragmentNames_ManyFragments(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueFragmentNamesRule, `\n      {\n        ...fragA\n        ...fragB\n        ...fragC\n      }\n      fragment fragA on Type {\n        fieldA\n      }\n      fragment fragB on Type {\n        fieldB\n      }\n      fragment fragC on Type {\n        fieldC\n      }\n    `)\n}\nfunc TestValidate_UniqueFragmentNames_InlineFragmentsAreAlwaysUnique(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueFragmentNamesRule, `\n      {\n        ...on Type {\n          fieldA\n        }\n        ...on Type {\n          fieldB\n        }\n      }\n    `)\n}\nfunc TestValidate_UniqueFragmentNames_FragmentAndOperationNamedTheSame(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueFragmentNamesRule, `\n      query Foo {\n        ...Foo\n      }\n      fragment Foo on Type {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueFragmentNames_FragmentsNamedTheSame(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueFragmentNamesRule, `\n      {\n        ...fragA\n      }\n      fragment fragA on Type {\n        fieldA\n      }\n      fragment fragA on Type {\n        fieldB\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can only be one fragment named \"fragA\".`, 5, 16, 8, 16),\n\t})\n}\nfunc TestValidate_UniqueFragmentNames_FragmentsNamedTheSameWithoutBeingReferenced(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueFragmentNamesRule, `\n      fragment fragA on Type {\n        fieldA\n      }\n      fragment fragA on Type {\n        fieldB\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can only be one fragment named \"fragA\".`, 2, 16, 5, 16),\n\t})\n}\n"
  },
  {
    "path": "rules_unique_input_field_names_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_UniqueInputFieldNames_InputObjectWithFields(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueInputFieldNamesRule, `\n      {\n        field(arg: { f: true })\n      }\n    `)\n}\nfunc TestValidate_UniqueInputFieldNames_SameInputObjectWithinTwoArgs(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueInputFieldNamesRule, `\n      {\n        field(arg1: { f: true }, arg2: { f: true })\n      }\n    `)\n}\nfunc TestValidate_UniqueInputFieldNames_MultipleInputObjectFields(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueInputFieldNamesRule, `\n      {\n        field(arg: { f1: \"value\", f2: \"value\", f3: \"value\" })\n      }\n    `)\n}\nfunc TestValidate_UniqueInputFieldNames_AllowsForNestedInputObjectsWithSimilarFields(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueInputFieldNamesRule, `\n      {\n        field(arg: {\n          deep: {\n            deep: {\n              id: 1\n            }\n            id: 1\n          }\n          id: 1\n        })\n      }\n    `)\n}\nfunc TestValidate_UniqueInputFieldNames_DuplicateInputObjectFields(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueInputFieldNamesRule, `\n      {\n        field(arg: { f1: \"value\", f1: \"value\" })\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can be only one input field named \"f1\".`, 3, 22, 3, 35),\n\t})\n}\nfunc TestValidate_UniqueInputFieldNames_ManyDuplicateInputObjectFields(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueInputFieldNamesRule, `\n      {\n        field(arg: { f1: \"value\", f1: \"value\", f1: \"value\" })\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can be only one input field named \"f1\".`, 3, 22, 3, 35),\n\t\ttestutil.RuleError(`There can be only one input field named \"f1\".`, 3, 22, 3, 48),\n\t})\n}\n"
  },
  {
    "path": "rules_unique_operation_names_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_UniqueOperationNames_NoOperations(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueOperationNamesRule, `\n      fragment fragA on Type {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueOperationNames_OneAnonOperation(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueOperationNamesRule, `\n      {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueOperationNames_OneNamedOperation(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueOperationNamesRule, `\n      query Foo {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueOperationNames_MultipleOperations(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueOperationNamesRule, `\n      query Foo {\n        field\n      }\n\n      query Bar {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueOperationNames_MultipleOperationsOfDifferentTypes(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueOperationNamesRule, `\n      query Foo {\n        field\n      }\n\n      mutation Bar {\n        field\n      }\n\n      subscription Baz {\n      \tfield\n      }\n    `)\n}\nfunc TestValidate_UniqueOperationNames_FragmentAndOperationNamedTheSame(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueOperationNamesRule, `\n      query Foo {\n        ...Foo\n      }\n      fragment Foo on Type {\n        field\n      }\n    `)\n}\nfunc TestValidate_UniqueOperationNames_MultipleOperationsOfSameName(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueOperationNamesRule, `\n      query Foo {\n        fieldA\n      }\n      query Foo {\n        fieldB\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can only be one operation named \"Foo\".`, 2, 13, 5, 13),\n\t})\n}\nfunc TestValidate_UniqueOperationNames_MultipleOperationsOfSameNameOfDifferentTypes_Mutation(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueOperationNamesRule, `\n      query Foo {\n        fieldA\n      }\n      mutation Foo {\n        fieldB\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can only be one operation named \"Foo\".`, 2, 13, 5, 16),\n\t})\n}\n\nfunc TestValidate_UniqueOperationNames_MultipleOperationsOfSameNameOfDifferentTypes_Subscription(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueOperationNamesRule, `\n      query Foo {\n        fieldA\n      }\n      subscription Foo {\n        fieldB\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can only be one operation named \"Foo\".`, 2, 13, 5, 20),\n\t})\n}\n\nfunc TestValidate_UniqueOperationNames_MultipleAnonymousOperations(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueOperationNamesRule, `{a}{b}`, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can only be one operation named \"\".`, 1, 1, 1, 4),\n\t})\n}\n"
  },
  {
    "path": "rules_unique_variable_names_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_UniqueVariableNames_UniqueVariableNames(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.UniqueVariableNamesRule, `\n      query A($x: Int, $y: String) { __typename }\n      query B($x: String, $y: Int) { __typename }\n    `)\n}\nfunc TestValidate_UniqueVariableNames_DuplicateVariableNames(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.UniqueVariableNamesRule, `\n      query A($x: Int, $x: Int, $x: String) { __typename }\n      query B($x: String, $x: Int) { __typename }\n      query C($x: Int, $x: Int) { __typename }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`There can only be one variable named \"x\".`, 2, 16, 2, 25),\n\t\ttestutil.RuleError(`There can only be one variable named \"x\".`, 2, 16, 2, 34),\n\t\ttestutil.RuleError(`There can only be one variable named \"x\".`, 3, 16, 3, 28),\n\t\ttestutil.RuleError(`There can only be one variable named \"x\".`, 4, 16, 4, 25),\n\t})\n}\n"
  },
  {
    "path": "rules_variables_are_input_types_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_VariablesAreInputTypes_(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesAreInputTypesRule, `\n      query Foo($a: String, $b: [Boolean!]!, $c: ComplexInput) {\n        field(a: $a, b: $b, c: $c)\n      }\n    `)\n}\nfunc TestValidate_VariablesAreInputTypes_1(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.VariablesAreInputTypesRule, `\n      query Foo($a: Dog, $b: [[CatOrDog!]]!, $c: Pet) {\n        field(a: $a, b: $b, c: $c)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$a\" cannot be non-input type \"Dog\".`, 2, 21),\n\t\ttestutil.RuleError(`Variable \"$b\" cannot be non-input type \"[[CatOrDog!]]!\".`, 2, 30),\n\t\ttestutil.RuleError(`Variable \"$c\" cannot be non-input type \"Pet\".`, 2, 50),\n\t})\n}\n"
  },
  {
    "path": "rules_variables_in_allowed_position_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestValidate_VariablesInAllowedPosition_BooleanToBoolean(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($booleanArg: Boolean)\n      {\n        complicatedArgs {\n          booleanArgField(booleanArg: $booleanArg)\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_BooleanToBooleanWithinFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      fragment booleanArgFrag on ComplicatedArgs {\n        booleanArgField(booleanArg: $booleanArg)\n      }\n      query Query($booleanArg: Boolean)\n      {\n        complicatedArgs {\n          ...booleanArgFrag\n        }\n      }\n    `)\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($booleanArg: Boolean)\n      {\n        complicatedArgs {\n          ...booleanArgFrag\n        }\n      }\n      fragment booleanArgFrag on ComplicatedArgs {\n        booleanArgField(booleanArg: $booleanArg)\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_NonNullableBooleanToBoolean(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($nonNullBooleanArg: Boolean!)\n      {\n        complicatedArgs {\n          booleanArgField(booleanArg: $nonNullBooleanArg)\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_NonNullableBooleanToBooleanWithinFragment(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      fragment booleanArgFrag on ComplicatedArgs {\n        booleanArgField(booleanArg: $nonNullBooleanArg)\n      }\n\n      query Query($nonNullBooleanArg: Boolean!)\n      {\n        complicatedArgs {\n          ...booleanArgFrag\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_IntToNonNullableIntWithDefault(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($intArg: Int = 1)\n      {\n        complicatedArgs {\n          nonNullIntArgField(nonNullIntArg: $intArg)\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_ListOfStringToListOfString(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($stringListVar: [String])\n      {\n        complicatedArgs {\n          stringListArgField(stringListArg: $stringListVar)\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_ListOfNonNullableStringToListOfString(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($stringListVar: [String!])\n      {\n        complicatedArgs {\n          stringListArgField(stringListArg: $stringListVar)\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_StringToListOfStringInItemPosition(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($stringVar: String)\n      {\n        complicatedArgs {\n          stringListArgField(stringListArg: [$stringVar])\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_NonNullableStringToListOfStringInItemPosition(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($stringVar: String!)\n      {\n        complicatedArgs {\n          stringListArgField(stringListArg: [$stringVar])\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_ComplexInputToComplexInput(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($complexVar: ComplexInput)\n      {\n        complicatedArgs {\n          complexArgField(complexArg: $complexVar)\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_ComplexInputToComplexInputInFieldPosition(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($boolVar: Boolean = false)\n      {\n        complicatedArgs {\n          complexArgField(complexArg: {requiredArg: $boolVar})\n        }\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_NonNullableBooleanToNonNullableBooleanInDirective(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($boolVar: Boolean!)\n      {\n        dog @include(if: $boolVar)\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_NonNullableBooleanToNonNullableBooleanInDirectiveInDirectiveWithDefault(t *testing.T) {\n\ttestutil.ExpectPassesRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($boolVar: Boolean = false)\n      {\n        dog @include(if: $boolVar)\n      }\n    `)\n}\nfunc TestValidate_VariablesInAllowedPosition_IntToNonNullableInt(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($intArg: Int) {\n        complicatedArgs {\n          nonNullIntArgField(nonNullIntArg: $intArg)\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$intArg\" of type \"Int\" used in position `+\n\t\t\t`expecting type \"Int!\".`, 2, 19, 4, 45),\n\t})\n}\nfunc TestValidate_VariablesInAllowedPosition_IntToNonNullableIntWithinFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.VariablesInAllowedPositionRule, `\n      fragment nonNullIntArgFieldFrag on ComplicatedArgs {\n        nonNullIntArgField(nonNullIntArg: $intArg)\n      }\n\n      query Query($intArg: Int) {\n        complicatedArgs {\n          ...nonNullIntArgFieldFrag\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$intArg\" of type \"Int\" used in position `+\n\t\t\t`expecting type \"Int!\".`, 6, 19, 3, 43),\n\t})\n}\nfunc TestValidate_VariablesInAllowedPosition_IntToNonNullableIntWithinNestedFragment(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.VariablesInAllowedPositionRule, `\n      fragment outerFrag on ComplicatedArgs {\n        ...nonNullIntArgFieldFrag\n      }\n\n      fragment nonNullIntArgFieldFrag on ComplicatedArgs {\n        nonNullIntArgField(nonNullIntArg: $intArg)\n      }\n\n      query Query($intArg: Int) {\n        complicatedArgs {\n          ...outerFrag\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$intArg\" of type \"Int\" used in position `+\n\t\t\t`expecting type \"Int!\".`, 10, 19, 7, 43),\n\t})\n}\nfunc TestValidate_VariablesInAllowedPosition_StringOverBoolean(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($stringVar: String) {\n        complicatedArgs {\n          booleanArgField(booleanArg: $stringVar)\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$stringVar\" of type \"String\" used in position `+\n\t\t\t`expecting type \"Boolean\".`, 2, 19, 4, 39),\n\t})\n}\nfunc TestValidate_VariablesInAllowedPosition_StringToListOfString(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($stringVar: String) {\n        complicatedArgs {\n          stringListArgField(stringListArg: $stringVar)\n        }\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$stringVar\" of type \"String\" used in position `+\n\t\t\t`expecting type \"[String]\".`, 2, 19, 4, 45),\n\t})\n}\nfunc TestValidate_VariablesInAllowedPosition_BooleanToNonNullableBooleanInDirective(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($boolVar: Boolean) {\n        dog @include(if: $boolVar)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$boolVar\" of type \"Boolean\" used in position `+\n\t\t\t`expecting type \"Boolean!\".`, 2, 19, 3, 26),\n\t})\n}\nfunc TestValidate_VariablesInAllowedPosition_StringToNonNullableBooleanInDirective(t *testing.T) {\n\ttestutil.ExpectFailsRule(t, graphql.VariablesInAllowedPositionRule, `\n      query Query($stringVar: String) {\n        dog @include(if: $stringVar)\n      }\n    `, []gqlerrors.FormattedError{\n\t\ttestutil.RuleError(`Variable \"$stringVar\" of type \"String\" used in position `+\n\t\t\t`expecting type \"Boolean!\".`, 2, 19, 3, 26),\n\t})\n}\n"
  },
  {
    "path": "scalars.go",
    "content": "package graphql\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\n// As per the GraphQL Spec, Integers are only treated as valid when a valid\n// 32-bit signed integer, providing the broadest support across platforms.\n//\n// n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because\n// they are internally represented as IEEE 754 doubles.\nfunc coerceInt(value interface{}) interface{} {\n\tswitch value := value.(type) {\n\tcase bool:\n\t\tif value == true {\n\t\t\treturn 1\n\t\t}\n\t\treturn 0\n\tcase *bool:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\tcase int:\n\t\tif value < int(math.MinInt32) || value > int(math.MaxInt32) {\n\t\t\treturn nil\n\t\t}\n\t\treturn value\n\tcase *int:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\tcase int8:\n\t\treturn int(value)\n\tcase *int8:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(*value)\n\tcase int16:\n\t\treturn int(value)\n\tcase *int16:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(*value)\n\tcase int32:\n\t\treturn int(value)\n\tcase *int32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(*value)\n\tcase int64:\n\t\tif value < int64(math.MinInt32) || value > int64(math.MaxInt32) {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(value)\n\tcase *int64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\tcase uint:\n\t\tif value > math.MaxInt32 {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(value)\n\tcase *uint:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\tcase uint8:\n\t\treturn int(value)\n\tcase *uint8:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(*value)\n\tcase uint16:\n\t\treturn int(value)\n\tcase *uint16:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(*value)\n\tcase uint32:\n\t\tif value > uint32(math.MaxInt32) {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(value)\n\tcase *uint32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\tcase uint64:\n\t\tif value > uint64(math.MaxInt32) {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(value)\n\tcase *uint64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\tcase float32:\n\t\tif value < float32(math.MinInt32) || value > float32(math.MaxInt32) {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(value)\n\tcase *float32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\tcase float64:\n\t\tif value < float64(math.MinInt32) || value > float64(math.MaxInt32) {\n\t\t\treturn nil\n\t\t}\n\t\treturn int(value)\n\tcase *float64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\tcase string:\n\t\tval, err := strconv.ParseFloat(value, 0)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(val)\n\tcase *string:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceInt(*value)\n\t}\n\n\t// If the value cannot be transformed into an int, return nil instead of '0'\n\t// to denote 'no integer found'\n\treturn nil\n}\n\n// Int is the GraphQL Integer type definition.\nvar Int = NewScalar(ScalarConfig{\n\tName: \"Int\",\n\tDescription: \"The `Int` scalar type represents non-fractional signed whole numeric \" +\n\t\t\"values. Int can represent values between -(2^31) and 2^31 - 1. \",\n\tSerialize:  coerceInt,\n\tParseValue: coerceInt,\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\tswitch valueAST := valueAST.(type) {\n\t\tcase *ast.IntValue:\n\t\t\tif intValue, err := strconv.Atoi(valueAST.Value); err == nil {\n\t\t\t\treturn intValue\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t},\n})\n\nfunc coerceFloat(value interface{}) interface{} {\n\tswitch value := value.(type) {\n\tcase bool:\n\t\tif value == true {\n\t\t\treturn 1.0\n\t\t}\n\t\treturn 0.0\n\tcase *bool:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase int:\n\t\treturn float64(value)\n\tcase *int:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase int8:\n\t\treturn float64(value)\n\tcase *int8:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase int16:\n\t\treturn float64(value)\n\tcase *int16:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase int32:\n\t\treturn float64(value)\n\tcase *int32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase int64:\n\t\treturn float64(value)\n\tcase *int64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase uint:\n\t\treturn float64(value)\n\tcase *uint:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase uint8:\n\t\treturn float64(value)\n\tcase *uint8:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase uint16:\n\t\treturn float64(value)\n\tcase *uint16:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase uint32:\n\t\treturn float64(value)\n\tcase *uint32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase uint64:\n\t\treturn float64(value)\n\tcase *uint64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase float32:\n\t\treturn value\n\tcase *float32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase float64:\n\t\treturn value\n\tcase *float64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\tcase string:\n\t\tval, err := strconv.ParseFloat(value, 0)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn val\n\tcase *string:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceFloat(*value)\n\t}\n\n\t// If the value cannot be transformed into an float, return nil instead of '0.0'\n\t// to denote 'no float found'\n\treturn nil\n}\n\n// Float is the GraphQL float type definition.\nvar Float = NewScalar(ScalarConfig{\n\tName: \"Float\",\n\tDescription: \"The `Float` scalar type represents signed double-precision fractional \" +\n\t\t\"values as specified by \" +\n\t\t\"[IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). \",\n\tSerialize:  coerceFloat,\n\tParseValue: coerceFloat,\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\tswitch valueAST := valueAST.(type) {\n\t\tcase *ast.FloatValue:\n\t\t\tif floatValue, err := strconv.ParseFloat(valueAST.Value, 64); err == nil {\n\t\t\t\treturn floatValue\n\t\t\t}\n\t\tcase *ast.IntValue:\n\t\t\tif floatValue, err := strconv.ParseFloat(valueAST.Value, 64); err == nil {\n\t\t\t\treturn floatValue\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t},\n})\n\nfunc coerceString(value interface{}) interface{} {\n\tif v, ok := value.(*string); ok {\n\t\tif v == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn *v\n\t}\n\treturn fmt.Sprintf(\"%v\", value)\n}\n\n// String is the GraphQL string type definition\nvar String = NewScalar(ScalarConfig{\n\tName: \"String\",\n\tDescription: \"The `String` scalar type represents textual data, represented as UTF-8 \" +\n\t\t\"character sequences. The String type is most often used by GraphQL to \" +\n\t\t\"represent free-form human-readable text.\",\n\tSerialize:  coerceString,\n\tParseValue: coerceString,\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\tswitch valueAST := valueAST.(type) {\n\t\tcase *ast.StringValue:\n\t\t\treturn valueAST.Value\n\t\t}\n\t\treturn nil\n\t},\n})\n\nfunc coerceBool(value interface{}) interface{} {\n\tswitch value := value.(type) {\n\tcase bool:\n\t\treturn value\n\tcase *bool:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn *value\n\tcase string:\n\t\tswitch value {\n\t\tcase \"\", \"false\":\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\tcase *string:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase float64:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *float64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase float32:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *float32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase int:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *int:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase int8:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *int8:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase int16:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *int16:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase int32:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *int32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase int64:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *int64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase uint:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *uint:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase uint8:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *uint8:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase uint16:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *uint16:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase uint32:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *uint32:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\tcase uint64:\n\t\tif value != 0 {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\tcase *uint64:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn coerceBool(*value)\n\t}\n\treturn false\n}\n\n// Boolean is the GraphQL boolean type definition\nvar Boolean = NewScalar(ScalarConfig{\n\tName:        \"Boolean\",\n\tDescription: \"The `Boolean` scalar type represents `true` or `false`.\",\n\tSerialize:   coerceBool,\n\tParseValue:  coerceBool,\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\tswitch valueAST := valueAST.(type) {\n\t\tcase *ast.BooleanValue:\n\t\t\treturn valueAST.Value\n\t\t}\n\t\treturn nil\n\t},\n})\n\n// ID is the GraphQL id type definition\nvar ID = NewScalar(ScalarConfig{\n\tName: \"ID\",\n\tDescription: \"The `ID` scalar type represents a unique identifier, often used to \" +\n\t\t\"refetch an object or as key for a cache. The ID type appears in a JSON \" +\n\t\t\"response as a String; however, it is not intended to be human-readable. \" +\n\t\t\"When expected as an input type, any string (such as `\\\"4\\\"`) or integer \" +\n\t\t\"(such as `4`) input value will be accepted as an ID.\",\n\tSerialize:  coerceString,\n\tParseValue: coerceString,\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\tswitch valueAST := valueAST.(type) {\n\t\tcase *ast.IntValue:\n\t\t\treturn valueAST.Value\n\t\tcase *ast.StringValue:\n\t\t\treturn valueAST.Value\n\t\t}\n\t\treturn nil\n\t},\n})\n\nfunc serializeDateTime(value interface{}) interface{} {\n\tswitch value := value.(type) {\n\tcase time.Time:\n\t\tbuff, err := value.MarshalText()\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\treturn string(buff)\n\tcase *time.Time:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn serializeDateTime(*value)\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc unserializeDateTime(value interface{}) interface{} {\n\tswitch value := value.(type) {\n\tcase []byte:\n\t\tt := time.Time{}\n\t\terr := t.UnmarshalText(value)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\treturn t\n\tcase string:\n\t\treturn unserializeDateTime([]byte(value))\n\tcase *string:\n\t\tif value == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn unserializeDateTime([]byte(*value))\n\tcase time.Time:\n\t\treturn value\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nvar DateTime = NewScalar(ScalarConfig{\n\tName: \"DateTime\",\n\tDescription: \"The `DateTime` scalar type represents a DateTime.\" +\n\t\t\" The DateTime is serialized as an RFC 3339 quoted string\",\n\tSerialize:  serializeDateTime,\n\tParseValue: unserializeDateTime,\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\tswitch valueAST := valueAST.(type) {\n\t\tcase *ast.StringValue:\n\t\t\treturn unserializeDateTime(valueAST.Value)\n\t\t}\n\t\treturn nil\n\t},\n})\n"
  },
  {
    "path": "scalars_parse_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\nfunc TestTypeSystem_Scalar_ParseValueOutputDateTime(t *testing.T) {\n\tt1, _ := time.Parse(time.RFC3339, \"2017-07-23T03:46:56.647Z\")\n\ttests := []dateTimeSerializationTest{\n\t\t{nil, nil},\n\t\t{\"\", nil},\n\t\t{(*string)(nil), nil},\n\t\t{\"2017-07-23\", nil},\n\t\t{\"2017-07-23T03:46:56.647Z\", t1},\n\t}\n\tfor _, test := range tests {\n\t\tval := graphql.DateTime.ParseValue(test.Value)\n\t\tif val != test.Expected {\n\t\t\treflectedValue := reflect.ValueOf(test.Value)\n\t\t\tt.Fatalf(\"failed DateTime.ParseValue(%v(%v)), expected: %v, got %v\", reflectedValue.Type(), test.Value, test.Expected, val)\n\t\t}\n\t}\n}\n\nfunc TestTypeSystem_Scalar_ParseLiteralOutputDateTime(t *testing.T) {\n\tt1, _ := time.Parse(time.RFC3339, \"2017-07-23T03:46:56.647Z\")\n\tfor name, testCase := range map[string]struct {\n\t\tLiteral  ast.Value\n\t\tExpected interface{}\n\t}{\n\t\t\"String\": {\n\t\t\tLiteral: &ast.StringValue{\n\t\t\t\tValue: \"2017-07-23T03:46:56.647Z\",\n\t\t\t},\n\t\t\tExpected: t1,\n\t\t},\n\t\t\"NotAString\": {\n\t\t\tLiteral:  &ast.IntValue{},\n\t\t\tExpected: nil,\n\t\t},\n\t} {\n\t\tt.Run(name, func(t *testing.T) {\n\t\t\tparsed := graphql.DateTime.ParseLiteral(testCase.Literal)\n\t\t\tif parsed != testCase.Expected {\n\t\t\t\tt.Fatalf(\"failed DateTime.ParseLiteral(%T(%v)), expected: %v, got %v\", testCase.Literal, testCase.Literal, parsed, testCase.Expected)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "scalars_serialization_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\ntype intSerializationTest struct {\n\tValue    interface{}\n\tExpected interface{}\n}\n\ntype float64SerializationTest struct {\n\tValue    interface{}\n\tExpected interface{}\n}\n\ntype stringSerializationTest struct {\n\tValue    interface{}\n\tExpected string\n}\n\ntype dateTimeSerializationTest struct {\n\tValue    interface{}\n\tExpected interface{}\n}\n\ntype boolSerializationTest struct {\n\tValue    interface{}\n\tExpected bool\n}\n\nfunc TestTypeSystem_Scalar_SerializesOutputInt(t *testing.T) {\n\ttests := []intSerializationTest{\n\t\t{1, 1},\n\t\t{0, 0},\n\t\t{-1, -1},\n\t\t{float32(0.1), 0},\n\t\t{float32(1.1), 1},\n\t\t{float32(-1.1), -1},\n\t\t{float32(1e5), 100000},\n\t\t{float32(math.MaxFloat32), nil},\n\t\t{float64(0.1), 0},\n\t\t{float64(1.1), 1},\n\t\t{float64(-1.1), -1},\n\t\t{float64(1e5), 100000},\n\t\t{float64(math.MaxFloat32), nil},\n\t\t{float64(math.MaxFloat64), nil},\n\t\t// Maybe a safe Go/Javascript `int`, but bigger than 2^32, so not\n\t\t// representable as a GraphQL Int\n\t\t{9876504321, nil},\n\t\t{-9876504321, nil},\n\t\t// Too big to represent as an Int in Go, JavaScript or GraphQL\n\t\t{float64(1e100), nil},\n\t\t{float64(-1e100), nil},\n\t\t{\"-1.1\", -1},\n\t\t{\"one\", nil},\n\t\t{false, 0},\n\t\t{true, 1},\n\t\t{int8(1), 1},\n\t\t{int16(1), 1},\n\t\t{int32(1), 1},\n\t\t{int64(1), 1},\n\t\t{uint(1), 1},\n\t\t// Maybe a safe Go `uint`, but bigger than 2^32, so not\n\t\t// representable as a GraphQL Int\n\t\t{uint(math.MaxInt32 + 1), nil},\n\t\t{uint8(1), 1},\n\t\t{uint16(1), 1},\n\t\t{uint32(1), 1},\n\t\t{uint32(math.MaxUint32), nil},\n\t\t{uint64(1), 1},\n\t\t{uint64(math.MaxInt32), math.MaxInt32},\n\t\t{int64(math.MaxInt32) + int64(1), nil},\n\t\t{int64(math.MinInt32) - int64(1), nil},\n\t\t{uint64(math.MaxInt64) + uint64(1), nil},\n\t\t{byte(127), 127},\n\t\t{'世', int('世')},\n\t\t// testing types that don't match a value in the array.\n\t\t{[]int{}, nil},\n\t}\n\n\tfor i, test := range tests {\n\t\tval := graphql.Int.Serialize(test.Value)\n\t\tif val != test.Expected {\n\t\t\treflectedTestValue := reflect.ValueOf(test.Value)\n\t\t\treflectedExpectedValue := reflect.ValueOf(test.Expected)\n\t\t\treflectedValue := reflect.ValueOf(val)\n\t\t\tt.Fatalf(\"Failed test #%d - Int.Serialize(%v(%v)), expected: %v(%v), got %v(%v)\",\n\t\t\t\ti, reflectedTestValue.Type(), test.Value,\n\t\t\t\treflectedExpectedValue.Type(), test.Expected,\n\t\t\t\treflectedValue.Type(), val,\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunc TestTypeSystem_Scalar_SerializesOutputFloat(t *testing.T) {\n\ttests := []float64SerializationTest{\n\t\t{int(1), 1.0},\n\t\t{int(0), 0.0},\n\t\t{int(-1), -1.0},\n\t\t{float32(0.1), float32(0.1)},\n\t\t{float32(1.1), float32(1.1)},\n\t\t{float32(-1.1), float32(-1.1)},\n\t\t{float64(0.1), float64(0.1)},\n\t\t{float64(1.1), float64(1.1)},\n\t\t{float64(-1.1), float64(-1.1)},\n\t\t{\"-1.1\", -1.1},\n\t\t{\"one\", nil},\n\t\t{false, 0.0},\n\t\t{true, 1.0},\n\t}\n\n\tfor i, test := range tests {\n\t\tval := graphql.Float.Serialize(test.Value)\n\t\tif val != test.Expected {\n\t\t\treflectedTestValue := reflect.ValueOf(test.Value)\n\t\t\treflectedExpectedValue := reflect.ValueOf(test.Expected)\n\t\t\treflectedValue := reflect.ValueOf(val)\n\t\t\tt.Fatalf(\"Failed test #%d - Float.Serialize(%v(%v)), expected: %v(%v), got %v(%v)\",\n\t\t\t\ti, reflectedTestValue.Type(), test.Value,\n\t\t\t\treflectedExpectedValue.Type(), test.Expected,\n\t\t\t\treflectedValue.Type(), val,\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunc TestTypeSystem_Scalar_SerializesOutputStrings(t *testing.T) {\n\ttests := []stringSerializationTest{\n\t\t{\"string\", \"string\"},\n\t\t{int(1), \"1\"},\n\t\t{float32(-1.1), \"-1.1\"},\n\t\t{float64(-1.1), \"-1.1\"},\n\t\t{true, \"true\"},\n\t\t{false, \"false\"},\n\t}\n\n\tfor _, test := range tests {\n\t\tval := graphql.String.Serialize(test.Value)\n\t\tif val != test.Expected {\n\t\t\treflectedValue := reflect.ValueOf(test.Value)\n\t\t\tt.Fatalf(\"Failed String.Serialize(%v(%v)), expected: %v, got %v\", reflectedValue.Type(), test.Value, test.Expected, val)\n\t\t}\n\t}\n}\n\nfunc TestTypeSystem_Scalar_SerializesOutputBoolean(t *testing.T) {\n\ttests := []boolSerializationTest{\n\t\t{\"true\", true},\n\t\t{\"false\", false},\n\t\t{\"string\", true},\n\t\t{\"\", false},\n\t\t{int(1), true},\n\t\t{int(0), false},\n\t\t{true, true},\n\t\t{false, false},\n\t}\n\n\tfor _, test := range tests {\n\t\tval := graphql.Boolean.Serialize(test.Value)\n\t\tif val != test.Expected {\n\t\t\treflectedValue := reflect.ValueOf(test.Value)\n\t\t\tt.Fatalf(\"Failed String.Boolean(%v(%v)), expected: %v, got %v\", reflectedValue.Type(), test.Value, test.Expected, val)\n\t\t}\n\t}\n}\n\nfunc TestTypeSystem_Scalar_SerializeOutputDateTime(t *testing.T) {\n\tnow := time.Now()\n\tnowString, err := now.MarshalText()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\ttests := []dateTimeSerializationTest{\n\t\t{\"string\", nil},\n\t\t{int(1), nil},\n\t\t{float32(-1.1), nil},\n\t\t{float64(-1.1), nil},\n\t\t{true, nil},\n\t\t{false, nil},\n\t\t{now, string(nowString)},\n\t\t{&now, string(nowString)},\n\t}\n\n\tfor _, test := range tests {\n\t\tval := graphql.DateTime.Serialize(test.Value)\n\t\tif val != test.Expected {\n\t\t\treflectedValue := reflect.ValueOf(test.Value)\n\t\t\tt.Fatalf(\"Failed DateTime.Serialize(%v(%v)), expected: %v, got %v\", reflectedValue.Type(), test.Value, test.Expected, val)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "scalars_test.go",
    "content": "package graphql\n\nimport (\n\t\"math\"\n\t\"testing\"\n)\n\nfunc TestCoerceInt(t *testing.T) {\n\ttests := []struct {\n\t\tin   interface{}\n\t\twant interface{}\n\t}{\n\t\t{\n\t\t\tin:   false,\n\t\t\twant: 0,\n\t\t},\n\t\t{\n\t\t\tin:   true,\n\t\t\twant: 1,\n\t\t},\n\t\t{\n\t\t\tin:   boolPtr(false),\n\t\t\twant: 0,\n\t\t},\n\t\t{\n\t\t\tin:   boolPtr(true),\n\t\t\twant: 1,\n\t\t},\n\t\t{\n\t\t\tin:   (*bool)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int(math.MinInt32) - 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int(math.MaxInt32) + 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint(math.MaxInt32) + 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint32(math.MaxInt32) + 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int64(math.MinInt32) - 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int64(math.MaxInt32) + 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint64(math.MaxInt32) + 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\t// need to subtract more than one because of float32 precision\n\t\t\tin:   float32(math.MinInt32) - 1000,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\t// need to add more than one because of float32 precision\n\t\t\tin:   float32(math.MaxInt32) + 1000,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   float64(math.MinInt32) - 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   float64(math.MaxInt32) + 1,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int(math.MinInt32),\n\t\t\twant: int(math.MinInt32),\n\t\t},\n\t\t{\n\t\t\tin:   int(math.MaxInt32),\n\t\t\twant: int(math.MaxInt32),\n\t\t},\n\t\t{\n\t\t\tin:   intPtr(12),\n\t\t\twant: 12,\n\t\t},\n\t\t{\n\t\t\tin:   (*int)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int8(13),\n\t\t\twant: int(13),\n\t\t},\n\t\t{\n\t\t\tin:   int8Ptr(14),\n\t\t\twant: int(14),\n\t\t},\n\t\t{\n\t\t\tin:   (*int8)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int16(15),\n\t\t\twant: int(15),\n\t\t},\n\t\t{\n\t\t\tin:   int16Ptr(16),\n\t\t\twant: int(16),\n\t\t},\n\t\t{\n\t\t\tin:   (*int16)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int32(17),\n\t\t\twant: int(17),\n\t\t},\n\t\t{\n\t\t\tin:   int32Ptr(18),\n\t\t\twant: int(18),\n\t\t},\n\t\t{\n\t\t\tin:   (*int32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int64(19),\n\t\t\twant: int(19),\n\t\t},\n\t\t{\n\t\t\tin:   int64Ptr(20),\n\t\t\twant: int(20),\n\t\t},\n\t\t{\n\t\t\tin:   (*int64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint8(21),\n\t\t\twant: int(21),\n\t\t},\n\t\t{\n\t\t\tin:   uint8Ptr(22),\n\t\t\twant: int(22),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint8)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint16(23),\n\t\t\twant: int(23),\n\t\t},\n\t\t{\n\t\t\tin:   uint16Ptr(24),\n\t\t\twant: int(24),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint16)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint32(25),\n\t\t\twant: int(25),\n\t\t},\n\t\t{\n\t\t\tin:   uint32Ptr(26),\n\t\t\twant: int(26),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint64(27),\n\t\t\twant: int(27),\n\t\t},\n\t\t{\n\t\t\tin:   uint64Ptr(28),\n\t\t\twant: int(28),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uintPtr(29),\n\t\t\twant: int(29),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   float32(30.1),\n\t\t\twant: int(30),\n\t\t},\n\t\t{\n\t\t\tin:   float32Ptr(31.2),\n\t\t\twant: int(31),\n\t\t},\n\t\t{\n\t\t\tin:   (*float32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   float64(32),\n\t\t\twant: int(32),\n\t\t},\n\t\t{\n\t\t\tin:   float64Ptr(33.1),\n\t\t\twant: int(33),\n\t\t},\n\t\t{\n\t\t\tin:   (*float64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   \"34\",\n\t\t\twant: int(34),\n\t\t},\n\t\t{\n\t\t\tin:   stringPtr(\"35\"),\n\t\t\twant: int(35),\n\t\t},\n\t\t{\n\t\t\tin:   (*string)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   \"I'm not a number\",\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   make(map[string]interface{}),\n\t\t\twant: nil,\n\t\t},\n\t}\n\n\tfor i, tt := range tests {\n\t\tif got, want := coerceInt(tt.in), tt.want; got != want {\n\t\t\tt.Errorf(\"%d: in=%v, got=%v, want=%v\", i, tt.in, got, want)\n\t\t}\n\t}\n}\n\nfunc TestCoerceFloat(t *testing.T) {\n\ttests := []struct {\n\t\tin   interface{}\n\t\twant interface{}\n\t}{\n\t\t{\n\t\t\tin:   false,\n\t\t\twant: 0.0,\n\t\t},\n\t\t{\n\t\t\tin:   true,\n\t\t\twant: 1.0,\n\t\t},\n\t\t{\n\t\t\tin:   boolPtr(false),\n\t\t\twant: 0.0,\n\t\t},\n\t\t{\n\t\t\tin:   boolPtr(true),\n\t\t\twant: 1.0,\n\t\t},\n\t\t{\n\t\t\tin:   (*bool)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int(math.MinInt32),\n\t\t\twant: float64(math.MinInt32),\n\t\t},\n\t\t{\n\t\t\tin:   int(math.MaxInt32),\n\t\t\twant: float64(math.MaxInt32),\n\t\t},\n\t\t{\n\t\t\tin:   intPtr(12),\n\t\t\twant: float64(12),\n\t\t},\n\t\t{\n\t\t\tin:   (*int)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int8(13),\n\t\t\twant: float64(13),\n\t\t},\n\t\t{\n\t\t\tin:   int8Ptr(14),\n\t\t\twant: float64(14),\n\t\t},\n\t\t{\n\t\t\tin:   (*int8)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int16(15),\n\t\t\twant: float64(15),\n\t\t},\n\t\t{\n\t\t\tin:   int16Ptr(16),\n\t\t\twant: float64(16),\n\t\t},\n\t\t{\n\t\t\tin:   (*int16)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int32(17),\n\t\t\twant: float64(17),\n\t\t},\n\t\t{\n\t\t\tin:   int32Ptr(18),\n\t\t\twant: float64(18),\n\t\t},\n\t\t{\n\t\t\tin:   (*int32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int64(19),\n\t\t\twant: float64(19),\n\t\t},\n\t\t{\n\t\t\tin:   int64Ptr(20),\n\t\t\twant: float64(20),\n\t\t},\n\t\t{\n\t\t\tin:   (*int64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint8(21),\n\t\t\twant: float64(21),\n\t\t},\n\t\t{\n\t\t\tin:   uint8Ptr(22),\n\t\t\twant: float64(22),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint8)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint16(23),\n\t\t\twant: float64(23),\n\t\t},\n\t\t{\n\t\t\tin:   uint16Ptr(24),\n\t\t\twant: float64(24),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint16)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint32(25),\n\t\t\twant: float64(25),\n\t\t},\n\t\t{\n\t\t\tin:   uint32Ptr(26),\n\t\t\twant: float64(26),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint64(27),\n\t\t\twant: float64(27),\n\t\t},\n\t\t{\n\t\t\tin:   uint64Ptr(28),\n\t\t\twant: float64(28),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uintPtr(29),\n\t\t\twant: float64(29),\n\t\t},\n\t\t{\n\t\t\tin:   (*uint)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   float32(30),\n\t\t\twant: float32(30),\n\t\t},\n\t\t{\n\t\t\tin:   float32Ptr(31),\n\t\t\twant: float32(31),\n\t\t},\n\t\t{\n\t\t\tin:   (*float32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   float64(32),\n\t\t\twant: float64(32),\n\t\t},\n\t\t{\n\t\t\tin:   float64Ptr(33.2),\n\t\t\twant: float64(33.2),\n\t\t},\n\t\t{\n\t\t\tin:   (*float64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   \"34\",\n\t\t\twant: float64(34),\n\t\t},\n\t\t{\n\t\t\tin:   stringPtr(\"35.2\"),\n\t\t\twant: float64(35.2),\n\t\t},\n\t\t{\n\t\t\tin:   (*string)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   \"I'm not a number\",\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   make(map[string]interface{}),\n\t\t\twant: nil,\n\t\t},\n\t}\n\n\tfor i, tt := range tests {\n\t\tif got, want := coerceFloat(tt.in), tt.want; got != want {\n\t\t\tt.Errorf(\"%d: in=%v, got=%v, want=%v\", i, tt.in, got, want)\n\t\t}\n\t}\n}\n\nfunc TestCoerceBool(t *testing.T) {\n\ttests := []struct {\n\t\tin   interface{}\n\t\twant interface{}\n\t}{\n\t\t{\n\t\t\tin:   false,\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   true,\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   boolPtr(false),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   boolPtr(true),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   (*bool)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int(math.MinInt32),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int(math.MaxInt32),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   intPtr(12),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   intPtr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*int)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int8(13),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int8(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   int8Ptr(14),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int8Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*int8)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int16(15),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int16(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   int16Ptr(16),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int16Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*int16)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int32(17),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int32(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   int32Ptr(18),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int32Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*int32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   int64(19),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int64(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   int64Ptr(20),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   int64Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*int64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint8(21),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uint8(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   uint8Ptr(22),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uint8Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*uint8)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint16(23),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uint16(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   uint16Ptr(24),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uint16Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*uint16)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint32(25),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uint32(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   uint32Ptr(26),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uint32Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*uint32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uint64(27),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uint64(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   uint64Ptr(28),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uint64Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*uint64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   uintPtr(29),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   uintPtr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   float32(30),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   float32(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   float32Ptr(31),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   float32Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*float32)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   float64(32),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   float64(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   float64Ptr(33.2),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   float64Ptr(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*float64)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   \"34\",\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   \"false\",\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   stringPtr(\"true\"),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   stringPtr(\"false\"),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   (*string)(nil),\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tin:   \"I'm some random string\",\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tin:   \"\",\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   int8(0),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tin:   make(map[string]interface{}),\n\t\t\twant: false,\n\t\t},\n\t}\n\n\tfor i, tt := range tests {\n\t\tif got, want := coerceBool(tt.in), tt.want; got != want {\n\t\t\tt.Errorf(\"%d: in=%v, got=%v, want=%v\", i, tt.in, got, want)\n\t\t}\n\t}\n}\n\nfunc boolPtr(b bool) *bool {\n\treturn &b\n}\n\nfunc intPtr(n int) *int {\n\treturn &n\n}\n\nfunc int8Ptr(n int8) *int8 {\n\treturn &n\n}\n\nfunc int16Ptr(n int16) *int16 {\n\treturn &n\n}\n\nfunc int32Ptr(n int32) *int32 {\n\treturn &n\n}\n\nfunc int64Ptr(n int64) *int64 {\n\treturn &n\n}\n\nfunc uintPtr(n uint) *uint {\n\treturn &n\n}\n\nfunc uint8Ptr(n uint8) *uint8 {\n\treturn &n\n}\n\nfunc uint16Ptr(n uint16) *uint16 {\n\treturn &n\n}\n\nfunc uint32Ptr(n uint32) *uint32 {\n\treturn &n\n}\n\nfunc uint64Ptr(n uint64) *uint64 {\n\treturn &n\n}\n\nfunc float32Ptr(n float32) *float32 {\n\treturn &n\n}\n\nfunc float64Ptr(n float64) *float64 {\n\treturn &n\n}\n\nfunc stringPtr(s string) *string {\n\treturn &s\n}\n"
  },
  {
    "path": "schema-all-descriptions.graphql",
    "content": "# File: schema-all-descriptions.graphql\n\n\"\"\"single line scalar description\"\"\"\nscalar ScalarSingleLine\n\n\"\"\"\nmulti line\n\nscalar description\n\"\"\"\nscalar ScalarMultiLine\n\n\"\"\"single line object description\"\"\"\ntype ObjectSingleLine {\n  no_description: ID\n\n  \"\"\"single line field description\"\"\"\n  single_line(a: ID, b: ID, c: ID, d: ID): ID\n\n  \"\"\"\n  multi line\n\n  field description\n  \"\"\"\n  multi_line(\n    a: ID\n\n    \"\"\"single line argument description\"\"\"\n    b: ID\n\n    \"\"\"\n    multi line\n\n    field description\n    \"\"\"\n    c: ID\n    d: ID\n  ): ID\n}\n\n\"\"\"\nmulti line\n\nobject description\n\"\"\"\ntype ObjectMultiLine {\n  foo: ID\n}\n\n\"\"\"single line interface description\"\"\"\ninterface InterfaceSingleLine {\n  no_description: ID\n\n  \"\"\"single line field description\"\"\"\n  single_line(a: ID, b: ID, c: ID, d: ID): ID\n\n  \"\"\"\n  multi line\n\n  field description\n  \"\"\"\n  multi_line(\n    a: ID\n\n    \"\"\"single line argument description\"\"\"\n    b: ID\n\n    \"\"\"\n    multi line\n\n    argument description\n    \"\"\"\n    c: ID\n    d: ID\n  ): ID\n}\n\n\"\"\"\nmulti line\n\ninterface description\n\"\"\"\ninterface InterfaceMultiLine {\n  foo: ID\n}\n\n\"\"\"single line union description\"\"\"\nunion UnionSingleLine = String | Int | Float | ID\n\n\"\"\"\nmulti line\n\nunion description\n\"\"\"\nunion UnionSingleLine = String | Int | Float | ID\n\n\"\"\"single line enum description\"\"\"\nenum EnumSingleLine {\n  no_description\n\n  \"\"\"single line enum description\"\"\"\n  single_line\n\n  \"\"\"\n  multi line\n\n  enum description\n  \"\"\"\n  multi_line\n  again_no_description\n}\n\n\"\"\"\nmulti line\n\nenum description\n\"\"\"\nenum EnumMultiLine {\n  foo\n}\n\n\"\"\"single line input description\"\"\"\ninput InputSingleLine {\n  a: ID\n\n  \"\"\"single line argument description\"\"\"\n  b: ID\n  \n  \"\"\"\n  multi line\n\n  argument description\n  \"\"\"\n  c: ID\n  d: ID\n}\n\n\"\"\"\nmulti line\n\ninput description\n\"\"\"\ninput InputMultiLine {\n  foo: ID\n}\n\n\"\"\"single line directive description\"\"\"\ndirective @DirectiveSingleLine(\n  a: ID\n\n  \"\"\"single line argument description\"\"\"\n  b: ID\n\n  \"\"\"\n  multi line\n\n  argument description\n  \"\"\"\n  c: ID\n  d: ID\n) on SCALAR\n\n\"\"\"\nmulti line\n\ndirective description\n\"\"\"\ndirective @DirectiveMultiLine on SCALAR\n"
  },
  {
    "path": "schema-kitchen-sink.graphql",
    "content": "# Filename: schema-kitchen-sink.graphql\n\nschema {\n  query: QueryType\n  mutation: MutationType\n}\n\ntype Foo implements Bar & Baz {\n  one: Type\n  two(argument: InputType!): Type\n  three(argument: InputType, other: String): Int\n  four(argument: String = \"string\"): String\n  five(argument: [String] = [\"string\", \"string\"]): String\n  six(argument: InputType = {key: \"value\"}): Type\n}\n\ntype AnnotatedObject @onObject(arg: \"value\") {\n  annotatedField(arg: Type = \"default\" @onArg): Type @onField\n}\n\ninterface Bar {\n  one: Type\n  four(argument: String = \"string\"): String\n}\n\ninterface AnnotatedInterface @onInterface {\n  annotatedField(arg: Type @onArg): Type @onField\n}\n\nunion Feed = Story | Article | Advert\n\nunion AnnotatedUnion @onUnion = A | B\n\nscalar CustomScalar\n\nscalar AnnotatedScalar @onScalar\n\nenum Site {\n  DESKTOP\n  MOBILE\n}\n\nenum AnnotatedEnum @onEnum {\n  ANNOTATED_VALUE @onEnumValue\n  OTHER_VALUE\n}\n\ninput InputType {\n  key: String!\n  answer: Int = 42\n}\n\ninput AnnotatedInput @onInputObjectType {\n  annotatedField: Type @onField\n}\n\nextend type Foo {\n  seven(argument: [String]): Type\n}\n\nextend type Foo @onType {}\n\ntype NoFields {}\n\ndirective @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\ndirective @include(if: Boolean!)\n  on FIELD\n  | FRAGMENT_SPREAD\n  | INLINE_FRAGMENT\n"
  },
  {
    "path": "schema.go",
    "content": "package graphql\n\ntype SchemaConfig struct {\n\tQuery        *Object\n\tMutation     *Object\n\tSubscription *Object\n\tTypes        []Type\n\tDirectives   []*Directive\n\tExtensions   []Extension\n}\n\ntype TypeMap map[string]Type\n\n// Schema Definition\n// A Schema is created by supplying the root types of each type of operation,\n// query, mutation (optional) and subscription (optional). A schema definition is then supplied to the\n// validator and executor.\n// Example:\n//     myAppSchema, err := NewSchema(SchemaConfig({\n//       Query: MyAppQueryRootType,\n//       Mutation: MyAppMutationRootType,\n//       Subscription: MyAppSubscriptionRootType,\n//     });\n// Note: If an array of `directives` are provided to GraphQLSchema, that will be\n// the exact list of directives represented and allowed. If `directives` is not\n// provided then a default set of the specified directives (e.g. @include and\n// @skip) will be used. If you wish to provide *additional* directives to these\n// specified directives, you must explicitly declare them. Example:\n//\n//     const MyAppSchema = new GraphQLSchema({\n//       ...\n//       directives: specifiedDirectives.concat([ myCustomDirective ]),\n//     })\ntype Schema struct {\n\ttypeMap    TypeMap\n\tdirectives []*Directive\n\n\tqueryType        *Object\n\tmutationType     *Object\n\tsubscriptionType *Object\n\timplementations  map[string][]*Object\n\tpossibleTypeMap  map[string]map[string]bool\n\textensions       []Extension\n}\n\nfunc NewSchema(config SchemaConfig) (Schema, error) {\n\tvar err error\n\n\tschema := Schema{}\n\n\tif err = invariant(config.Query != nil, \"Schema query must be Object Type but got: nil.\"); err != nil {\n\t\treturn schema, err\n\t}\n\n\t// if schema config contains error at creation time, return those errors\n\tif config.Query != nil && config.Query.err != nil {\n\t\treturn schema, config.Query.err\n\t}\n\tif config.Mutation != nil && config.Mutation.err != nil {\n\t\treturn schema, config.Mutation.err\n\t}\n\n\tschema.queryType = config.Query\n\tschema.mutationType = config.Mutation\n\tschema.subscriptionType = config.Subscription\n\n\t// Provide specified directives (e.g. @include and @skip) by default.\n\tschema.directives = config.Directives\n\tif len(schema.directives) == 0 {\n\t\tschema.directives = SpecifiedDirectives\n\t}\n\t// Ensure directive definitions are error-free\n\tfor _, dir := range schema.directives {\n\t\tif dir.err != nil {\n\t\t\treturn schema, dir.err\n\t\t}\n\t}\n\n\t// Build type map now to detect any errors within this schema.\n\ttypeMap := TypeMap{}\n\tinitialTypes := []Type{}\n\tif schema.QueryType() != nil {\n\t\tinitialTypes = append(initialTypes, schema.QueryType())\n\t}\n\tif schema.MutationType() != nil {\n\t\tinitialTypes = append(initialTypes, schema.MutationType())\n\t}\n\tif schema.SubscriptionType() != nil {\n\t\tinitialTypes = append(initialTypes, schema.SubscriptionType())\n\t}\n\tif SchemaType != nil {\n\t\tinitialTypes = append(initialTypes, SchemaType)\n\t}\n\n\t// assume that user will never add a nil object to config\n\tinitialTypes = append(initialTypes, config.Types...)\n\n\tfor _, ttype := range initialTypes {\n\t\tif ttype.Error() != nil {\n\t\t\treturn schema, ttype.Error()\n\t\t}\n\t\tif typeMap, err = typeMapReducer(&schema, typeMap, ttype); err != nil {\n\t\t\treturn schema, err\n\t\t}\n\t}\n\n\tschema.typeMap = typeMap\n\n\t// Keep track of all implementations by interface name.\n\tif schema.implementations == nil {\n\t\tschema.implementations = map[string][]*Object{}\n\t}\n\tfor _, ttype := range schema.typeMap {\n\t\tif ttype, ok := ttype.(*Object); ok {\n\t\t\tfor _, iface := range ttype.Interfaces() {\n\t\t\t\timpls, ok := schema.implementations[iface.Name()]\n\t\t\t\tif impls == nil || !ok {\n\t\t\t\t\timpls = []*Object{}\n\t\t\t\t}\n\t\t\t\timpls = append(impls, ttype)\n\t\t\t\tschema.implementations[iface.Name()] = impls\n\t\t\t}\n\t\t}\n\t}\n\n\t// Enforce correct interface implementations\n\tfor _, ttype := range schema.typeMap {\n\t\tif ttype, ok := ttype.(*Object); ok {\n\t\t\tfor _, iface := range ttype.Interfaces() {\n\t\t\t\terr := assertObjectImplementsInterface(&schema, ttype, iface)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn schema, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add extensions from config\n\tif len(config.Extensions) != 0 {\n\t\tschema.extensions = config.Extensions\n\t}\n\n\treturn schema, nil\n}\n\n//Added Check implementation of interfaces at runtime..\n//Add Implementations at Runtime..\nfunc (gq *Schema) AddImplementation() error {\n\n\t// Keep track of all implementations by interface name.\n\tif gq.implementations == nil {\n\t\tgq.implementations = map[string][]*Object{}\n\t}\n\tfor _, ttype := range gq.typeMap {\n\t\tif ttype, ok := ttype.(*Object); ok {\n\t\t\tfor _, iface := range ttype.Interfaces() {\n\t\t\t\timpls, ok := gq.implementations[iface.Name()]\n\t\t\t\tif impls == nil || !ok {\n\t\t\t\t\timpls = []*Object{}\n\t\t\t\t}\n\t\t\t\timpls = append(impls, ttype)\n\t\t\t\tgq.implementations[iface.Name()] = impls\n\t\t\t}\n\t\t}\n\t}\n\n\t// Enforce correct interface implementations\n\tfor _, ttype := range gq.typeMap {\n\t\tif ttype, ok := ttype.(*Object); ok {\n\t\t\tfor _, iface := range ttype.Interfaces() {\n\t\t\t\terr := assertObjectImplementsInterface(gq, ttype, iface)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n//Edited. To check add Types at RunTime..\n//Append Runtime schema to typeMap\nfunc (gq *Schema) AppendType(objectType Type) error {\n\tif objectType.Error() != nil {\n\t\treturn objectType.Error()\n\t}\n\tvar err error\n\tgq.typeMap, err = typeMapReducer(gq, gq.typeMap, objectType)\n\tif err != nil {\n\t\treturn err\n\t}\n\t//Now Add interface implementation..\n\treturn gq.AddImplementation()\n}\n\nfunc (gq *Schema) QueryType() *Object {\n\treturn gq.queryType\n}\n\nfunc (gq *Schema) MutationType() *Object {\n\treturn gq.mutationType\n}\n\nfunc (gq *Schema) SubscriptionType() *Object {\n\treturn gq.subscriptionType\n}\n\nfunc (gq *Schema) Directives() []*Directive {\n\treturn gq.directives\n}\n\nfunc (gq *Schema) Directive(name string) *Directive {\n\tfor _, directive := range gq.Directives() {\n\t\tif directive.Name == name {\n\t\t\treturn directive\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (gq *Schema) TypeMap() TypeMap {\n\treturn gq.typeMap\n}\n\nfunc (gq *Schema) Type(name string) Type {\n\treturn gq.TypeMap()[name]\n}\n\nfunc (gq *Schema) PossibleTypes(abstractType Abstract) []*Object {\n\tswitch abstractType := abstractType.(type) {\n\tcase *Union:\n\t\treturn abstractType.Types()\n\tcase *Interface:\n\t\tif impls, ok := gq.implementations[abstractType.Name()]; ok {\n\t\t\treturn impls\n\t\t}\n\t}\n\treturn []*Object{}\n}\nfunc (gq *Schema) IsPossibleType(abstractType Abstract, possibleType *Object) bool {\n\tpossibleTypeMap := gq.possibleTypeMap\n\tif possibleTypeMap == nil {\n\t\tpossibleTypeMap = map[string]map[string]bool{}\n\t}\n\n\tif typeMap, ok := possibleTypeMap[abstractType.Name()]; !ok {\n\t\ttypeMap = map[string]bool{}\n\t\tfor _, possibleType := range gq.PossibleTypes(abstractType) {\n\t\t\ttypeMap[possibleType.Name()] = true\n\t\t}\n\t\tpossibleTypeMap[abstractType.Name()] = typeMap\n\t}\n\n\tgq.possibleTypeMap = possibleTypeMap\n\tif typeMap, ok := possibleTypeMap[abstractType.Name()]; ok {\n\t\tisPossible, _ := typeMap[possibleType.Name()]\n\t\treturn isPossible\n\t}\n\treturn false\n}\n\n// AddExtensions can be used to add additional extensions to the schema\nfunc (gq *Schema) AddExtensions(e ...Extension) {\n\tgq.extensions = append(gq.extensions, e...)\n}\n\n// map-reduce\nfunc typeMapReducer(schema *Schema, typeMap TypeMap, objectType Type) (TypeMap, error) {\n\tvar err error\n\tif objectType == nil || objectType.Name() == \"\" {\n\t\treturn typeMap, nil\n\t}\n\n\t// first:\n\tswitch objectType := objectType.(type) {\n\tcase *List:\n\t\tif objectType.OfType != nil {\n\t\t\treturn typeMapReducer(schema, typeMap, objectType.OfType)\n\t\t}\n\tcase *NonNull:\n\t\tif objectType.OfType != nil {\n\t\t\treturn typeMapReducer(schema, typeMap, objectType.OfType)\n\t\t}\n\tcase *Object:\n\t\tif objectType.err != nil {\n\t\t\treturn typeMap, objectType.err\n\t\t}\n\t}\n\n\tif mappedObjectType, ok := typeMap[objectType.Name()]; ok {\n\t\terr = invariantf(\n\t\t\tmappedObjectType == objectType,\n\t\t\t`Schema must contain unique named types but contains multiple types named \"%v\".`, objectType.Name())\n\t\treturn typeMap, err\n\t}\n\ttypeMap[objectType.Name()] = objectType\n\n\t// second:\n\tswitch objectType := objectType.(type) {\n\tcase *Union, *Interface:\n\t\ttypes := schema.PossibleTypes(objectType)\n\t\tif objectType.Error() != nil {\n\t\t\treturn typeMap, objectType.Error()\n\t\t}\n\t\tfor _, innerObjectType := range types {\n\t\t\tif innerObjectType.err != nil {\n\t\t\t\treturn typeMap, innerObjectType.err\n\t\t\t}\n\t\t\tif typeMap, err = typeMapReducer(schema, typeMap, innerObjectType); err != nil {\n\t\t\t\treturn typeMap, err\n\t\t\t}\n\t\t}\n\tcase *Object:\n\t\tinterfaces := objectType.Interfaces()\n\t\tif objectType.err != nil {\n\t\t\treturn typeMap, objectType.err\n\t\t}\n\t\tfor _, innerObjectType := range interfaces {\n\t\t\tif innerObjectType.err != nil {\n\t\t\t\treturn typeMap, innerObjectType.err\n\t\t\t}\n\t\t\tif typeMap, err = typeMapReducer(schema, typeMap, innerObjectType); err != nil {\n\t\t\t\treturn typeMap, err\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch objectType := objectType.(type) {\n\tcase *Object:\n\t\tfieldMap := objectType.Fields()\n\t\tif objectType.err != nil {\n\t\t\treturn typeMap, objectType.err\n\t\t}\n\t\tfor _, field := range fieldMap {\n\t\t\tfor _, arg := range field.Args {\n\t\t\t\ttypeMap, err = typeMapReducer(schema, typeMap, arg.Type)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn typeMap, err\n\t\t\t\t}\n\t\t\t}\n\t\t\ttypeMap, err = typeMapReducer(schema, typeMap, field.Type)\n\t\t\tif err != nil {\n\t\t\t\treturn typeMap, err\n\t\t\t}\n\t\t}\n\tcase *Interface:\n\t\tfieldMap := objectType.Fields()\n\t\tif objectType.err != nil {\n\t\t\treturn typeMap, objectType.err\n\t\t}\n\t\tfor _, field := range fieldMap {\n\t\t\tfor _, arg := range field.Args {\n\t\t\t\ttypeMap, err = typeMapReducer(schema, typeMap, arg.Type)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn typeMap, err\n\t\t\t\t}\n\t\t\t}\n\t\t\ttypeMap, err = typeMapReducer(schema, typeMap, field.Type)\n\t\t\tif err != nil {\n\t\t\t\treturn typeMap, err\n\t\t\t}\n\t\t}\n\tcase *InputObject:\n\t\tfieldMap := objectType.Fields()\n\t\tif objectType.err != nil {\n\t\t\treturn typeMap, objectType.err\n\t\t}\n\t\tfor _, field := range fieldMap {\n\t\t\ttypeMap, err = typeMapReducer(schema, typeMap, field.Type)\n\t\t\tif err != nil {\n\t\t\t\treturn typeMap, err\n\t\t\t}\n\t\t}\n\t}\n\treturn typeMap, nil\n}\n\nfunc assertObjectImplementsInterface(schema *Schema, object *Object, iface *Interface) error {\n\tobjectFieldMap := object.Fields()\n\tifaceFieldMap := iface.Fields()\n\n\t// Assert each interface field is implemented.\n\tfor fieldName := range ifaceFieldMap {\n\t\tobjectField := objectFieldMap[fieldName]\n\t\tifaceField := ifaceFieldMap[fieldName]\n\n\t\t// Assert interface field exists on object.\n\t\terr := invariantf(\n\t\t\tobjectField != nil,\n\t\t\t`\"%v\" expects field \"%v\" but \"%v\" does not `+\n\t\t\t\t`provide it.`, iface, fieldName, object)\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Assert interface field type is satisfied by object field type, by being\n\t\t// a valid subtype. (covariant)\n\t\terr = invariantf(\n\t\t\tisTypeSubTypeOf(schema, objectField.Type, ifaceField.Type),\n\t\t\t`%v.%v expects type \"%v\" but `+\n\t\t\t\t`%v.%v provides type \"%v\".`,\n\t\t\tiface, fieldName, ifaceField.Type,\n\t\t\tobject, fieldName, objectField.Type,\n\t\t)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Assert each interface field arg is implemented.\n\t\tfor _, ifaceArg := range ifaceField.Args {\n\t\t\targName := ifaceArg.PrivateName\n\t\t\tvar objectArg *Argument\n\t\t\tfor _, arg := range objectField.Args {\n\t\t\t\tif arg.PrivateName == argName {\n\t\t\t\t\tobjectArg = arg\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Assert interface field arg exists on object field.\n\t\t\terr = invariantf(\n\t\t\t\tobjectArg != nil,\n\t\t\t\t`%v.%v expects argument \"%v\" but `+\n\t\t\t\t\t`%v.%v does not provide it.`,\n\t\t\t\tiface, fieldName, argName,\n\t\t\t\tobject, fieldName,\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Assert interface field arg type matches object field arg type.\n\t\t\t// (invariant)\n\t\t\terr = invariantf(\n\t\t\t\tisEqualType(ifaceArg.Type, objectArg.Type),\n\t\t\t\t`%v.%v(%v:) expects type \"%v\" `+\n\t\t\t\t\t`but %v.%v(%v:) provides `+\n\t\t\t\t\t`type \"%v\".`,\n\t\t\t\tiface, fieldName, argName, ifaceArg.Type,\n\t\t\t\tobject, fieldName, argName, objectArg.Type,\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\t// Assert additional arguments must not be required.\n\t\tfor _, objectArg := range objectField.Args {\n\t\t\targName := objectArg.PrivateName\n\t\t\tvar ifaceArg *Argument\n\t\t\tfor _, arg := range ifaceField.Args {\n\t\t\t\tif arg.PrivateName == argName {\n\t\t\t\t\tifaceArg = arg\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ifaceArg == nil {\n\t\t\t\t_, ok := objectArg.Type.(*NonNull)\n\t\t\t\terr = invariantf(\n\t\t\t\t\t!ok,\n\t\t\t\t\t`%v.%v(%v:) is of required type `+\n\t\t\t\t\t\t`\"%v\" but is not also provided by the interface %v.%v.`,\n\t\t\t\t\tobject, fieldName, argName,\n\t\t\t\t\tobjectArg.Type, iface, fieldName,\n\t\t\t\t)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc isEqualType(typeA Type, typeB Type) bool {\n\t// Equivalent type is a valid subtype\n\tif typeA == typeB {\n\t\treturn true\n\t}\n\t// If either type is non-null, the other must also be non-null.\n\tif typeA, ok := typeA.(*NonNull); ok {\n\t\tif typeB, ok := typeB.(*NonNull); ok {\n\t\t\treturn isEqualType(typeA.OfType, typeB.OfType)\n\t\t}\n\t}\n\t// If either type is a list, the other must also be a list.\n\tif typeA, ok := typeA.(*List); ok {\n\t\tif typeB, ok := typeB.(*List); ok {\n\t\t\treturn isEqualType(typeA.OfType, typeB.OfType)\n\t\t}\n\t}\n\t// Otherwise the types are not equal.\n\treturn false\n}\n\n// isTypeSubTypeOf Provided a type and a super type, return true if the first type is either\n// equal or a subset of the second super type (covariant).\nfunc isTypeSubTypeOf(schema *Schema, maybeSubType Type, superType Type) bool {\n\t// Equivalent type is a valid subtype\n\tif maybeSubType == superType {\n\t\treturn true\n\t}\n\n\t// If superType is non-null, maybeSubType must also be nullable.\n\tif superType, ok := superType.(*NonNull); ok {\n\t\tif maybeSubType, ok := maybeSubType.(*NonNull); ok {\n\t\t\treturn isTypeSubTypeOf(schema, maybeSubType.OfType, superType.OfType)\n\t\t}\n\t\treturn false\n\t}\n\tif maybeSubType, ok := maybeSubType.(*NonNull); ok {\n\t\t// If superType is nullable, maybeSubType may be non-null.\n\t\treturn isTypeSubTypeOf(schema, maybeSubType.OfType, superType)\n\t}\n\n\t// If superType type is a list, maybeSubType type must also be a list.\n\tif superType, ok := superType.(*List); ok {\n\t\tif maybeSubType, ok := maybeSubType.(*List); ok {\n\t\t\treturn isTypeSubTypeOf(schema, maybeSubType.OfType, superType.OfType)\n\t\t}\n\t\treturn false\n\t} else if _, ok := maybeSubType.(*List); ok {\n\t\t// If superType is not a list, maybeSubType must also be not a list.\n\t\treturn false\n\t}\n\n\t// If superType type is an abstract type, maybeSubType type may be a currently\n\t// possible object type.\n\tif superType, ok := superType.(*Interface); ok {\n\t\tif maybeSubType, ok := maybeSubType.(*Object); ok && schema.IsPossibleType(superType, maybeSubType) {\n\t\t\treturn true\n\t\t}\n\t}\n\tif superType, ok := superType.(*Union); ok {\n\t\tif maybeSubType, ok := maybeSubType.(*Object); ok && schema.IsPossibleType(superType, maybeSubType) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// Otherwise, the child type is not a valid subtype of the parent type.\n\treturn false\n}\n"
  },
  {
    "path": "subscription.go",
    "content": "package graphql\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/parser\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\n// SubscribeParams parameters for subscribing\ntype SubscribeParams struct {\n\tSchema        Schema\n\tRequestString string\n\tRootValue     interface{}\n\t// ContextValue    context.Context\n\tVariableValues  map[string]interface{}\n\tOperationName   string\n\tFieldResolver   FieldResolveFn\n\tFieldSubscriber FieldResolveFn\n}\n\n// Subscribe performs a subscribe operation on the given query and schema\n// To finish a subscription you can simply close the channel from inside the `Subscribe` function\n// currently does not support extensions hooks\nfunc Subscribe(p Params) chan *Result {\n\n\tsource := source.NewSource(&source.Source{\n\t\tBody: []byte(p.RequestString),\n\t\tName: \"GraphQL request\",\n\t})\n\n\t// TODO run extensions hooks\n\n\t// parse the source\n\tAST, err := parser.Parse(parser.ParseParams{Source: source})\n\tif err != nil {\n\n\t\t// merge the errors from extensions and the original error from parser\n\t\treturn sendOneResultAndClose(&Result{\n\t\t\tErrors: gqlerrors.FormatErrors(err),\n\t\t})\n\t}\n\n\t// validate document\n\tvalidationResult := ValidateDocument(&p.Schema, AST, nil)\n\n\tif !validationResult.IsValid {\n\t\t// run validation finish functions for extensions\n\t\treturn sendOneResultAndClose(&Result{\n\t\t\tErrors: validationResult.Errors,\n\t\t})\n\n\t}\n\treturn ExecuteSubscription(ExecuteParams{\n\t\tSchema:        p.Schema,\n\t\tRoot:          p.RootObject,\n\t\tAST:           AST,\n\t\tOperationName: p.OperationName,\n\t\tArgs:          p.VariableValues,\n\t\tContext:       p.Context,\n\t})\n}\n\nfunc sendOneResultAndClose(res *Result) chan *Result {\n\tresultChannel := make(chan *Result, 1)\n\tresultChannel <- res\n\tclose(resultChannel)\n\treturn resultChannel\n}\n\n// ExecuteSubscription is similar to graphql.Execute but returns a channel instead of a Result\n// currently does not support extensions\nfunc ExecuteSubscription(p ExecuteParams) chan *Result {\n\n\tif p.Context == nil {\n\t\tp.Context = context.Background()\n\t}\n\n\tvar mapSourceToResponse = func(payload interface{}) *Result {\n\t\treturn Execute(ExecuteParams{\n\t\t\tSchema:        p.Schema,\n\t\t\tRoot:          payload,\n\t\t\tAST:           p.AST,\n\t\t\tOperationName: p.OperationName,\n\t\t\tArgs:          p.Args,\n\t\t\tContext:       p.Context,\n\t\t})\n\t}\n\tvar resultChannel = make(chan *Result)\n\tgo func() {\n\t\tdefer close(resultChannel)\n\t\tdefer func() {\n\t\t\tif err := recover(); err != nil {\n\t\t\t\te, ok := err.(error)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tresultChannel <- &Result{\n\t\t\t\t\tErrors: gqlerrors.FormatErrors(e),\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn\n\t\t}()\n\n\t\texeContext, err := buildExecutionContext(buildExecutionCtxParams{\n\t\t\tSchema:        p.Schema,\n\t\t\tRoot:          p.Root,\n\t\t\tAST:           p.AST,\n\t\t\tOperationName: p.OperationName,\n\t\t\tArgs:          p.Args,\n\t\t\tContext:       p.Context,\n\t\t})\n\n\t\tif err != nil {\n\t\t\tresultChannel <- &Result{\n\t\t\t\tErrors: gqlerrors.FormatErrors(err),\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\n\t\toperationType, err := getOperationRootType(p.Schema, exeContext.Operation)\n\t\tif err != nil {\n\t\t\tresultChannel <- &Result{\n\t\t\t\tErrors: gqlerrors.FormatErrors(err),\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\n\t\tfields := collectFields(collectFieldsParams{\n\t\t\tExeContext:   exeContext,\n\t\t\tRuntimeType:  operationType,\n\t\t\tSelectionSet: exeContext.Operation.GetSelectionSet(),\n\t\t})\n\n\t\tresponseNames := []string{}\n\t\tfor name := range fields {\n\t\t\tresponseNames = append(responseNames, name)\n\t\t}\n\t\tresponseName := responseNames[0]\n\t\tfieldNodes := fields[responseName]\n\t\tfieldNode := fieldNodes[0]\n\t\tfieldName := fieldNode.Name.Value\n\t\tfieldDef := getFieldDef(p.Schema, operationType, fieldName)\n\n\t\tif fieldDef == nil {\n\t\t\tresultChannel <- &Result{\n\t\t\t\tErrors: gqlerrors.FormatErrors(fmt.Errorf(\"the subscription field %q is not defined\", fieldName)),\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\n\t\tresolveFn := fieldDef.Subscribe\n\n\t\tif resolveFn == nil {\n\t\t\tresultChannel <- &Result{\n\t\t\t\tErrors: gqlerrors.FormatErrors(fmt.Errorf(\"the subscription function %q is not defined\", fieldName)),\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tfieldPath := &ResponsePath{\n\t\t\tKey: responseName,\n\t\t}\n\n\t\targs := getArgumentValues(fieldDef.Args, fieldNode.Arguments, exeContext.VariableValues)\n\t\tinfo := ResolveInfo{\n\t\t\tFieldName:      fieldName,\n\t\t\tFieldASTs:      fieldNodes,\n\t\t\tPath:           fieldPath,\n\t\t\tReturnType:     fieldDef.Type,\n\t\t\tParentType:     operationType,\n\t\t\tSchema:         p.Schema,\n\t\t\tFragments:      exeContext.Fragments,\n\t\t\tRootValue:      exeContext.Root,\n\t\t\tOperation:      exeContext.Operation,\n\t\t\tVariableValues: exeContext.VariableValues,\n\t\t}\n\n\t\tfieldResult, err := resolveFn(ResolveParams{\n\t\t\tSource:  p.Root,\n\t\t\tArgs:    args,\n\t\t\tInfo:    info,\n\t\t\tContext: p.Context,\n\t\t})\n\t\tif err != nil {\n\t\t\tresultChannel <- &Result{\n\t\t\t\tErrors: gqlerrors.FormatErrors(err),\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\n\t\tif fieldResult == nil {\n\t\t\tresultChannel <- &Result{\n\t\t\t\tErrors: gqlerrors.FormatErrors(fmt.Errorf(\"no field result\")),\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\n\t\tswitch fieldResult.(type) {\n\t\tcase chan interface{}:\n\t\t\tsub := fieldResult.(chan interface{})\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase <-p.Context.Done():\n\t\t\t\t\treturn\n\n\t\t\t\tcase res, more := <-sub:\n\t\t\t\t\tif !more {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tresultChannel <- mapSourceToResponse(res)\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\tresultChannel <- mapSourceToResponse(fieldResult)\n\t\t\treturn\n\t\t}\n\t}()\n\n\t// return a result channel\n\treturn resultChannel\n}\n"
  },
  {
    "path": "subscription_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestSchemaSubscribe(t *testing.T) {\n\n\ttestutil.RunSubscribes(t, []*testutil.TestSubscription{\n\t\t{\n\t\t\tName: \"subscribe without resolver\",\n\t\t\tSchema: makeSubscriptionSchema(t, graphql.ObjectConfig{\n\t\t\t\tName: \"Subscription\",\n\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\"sub_without_resolver\": &graphql.Field{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\tSubscribe: makeSubscribeToMapFunction([]map[string]interface{}{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"sub_without_resolver\": \"a\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"sub_without_resolver\": \"b\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"sub_without_resolver\": \"c\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tQuery: `\n\t\t\t\tsubscription {\n\t\t\t\t\tsub_without_resolver\n\t\t\t\t}\n\t\t\t`,\n\t\t\tExpectedResults: []testutil.TestResponse{\n\t\t\t\t{Data: `{ \"sub_without_resolver\": \"a\" }`},\n\t\t\t\t{Data: `{ \"sub_without_resolver\": \"b\" }`},\n\t\t\t\t{Data: `{ \"sub_without_resolver\": \"c\" }`},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"subscribe with resolver\",\n\t\t\tSchema: makeSubscriptionSchema(t, graphql.ObjectConfig{\n\t\t\t\tName: \"Subscription\",\n\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\"sub_with_resolver\": &graphql.Field{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\t\treturn p.Source, nil\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSubscribe: makeSubscribeToStringFunction([]string{\"a\", \"b\", \"c\"}),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tQuery: `\n\t\t\t\tsubscription {\n\t\t\t\t\tsub_with_resolver\n\t\t\t\t}\n\t\t\t`,\n\t\t\tExpectedResults: []testutil.TestResponse{\n\t\t\t\t{Data: `{ \"sub_with_resolver\": \"a\" }`},\n\t\t\t\t{Data: `{ \"sub_with_resolver\": \"b\" }`},\n\t\t\t\t{Data: `{ \"sub_with_resolver\": \"c\" }`},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"receive query validation error\",\n\t\t\tSchema: makeSubscriptionSchema(t, graphql.ObjectConfig{\n\t\t\t\tName: \"Subscription\",\n\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\"sub_without_resolver\": &graphql.Field{\n\t\t\t\t\t\tType:      graphql.String,\n\t\t\t\t\t\tSubscribe: makeSubscribeToStringFunction([]string{\"a\", \"b\", \"c\"}),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tQuery: `\n\t\t\t\tsubscription {\n\t\t\t\t\tsub_without_resolver\n\t\t\t\t\txxx\n\t\t\t\t}\n\t\t\t`,\n\t\t\tExpectedResults: []testutil.TestResponse{\n\t\t\t\t{Errors: []string{\"Cannot query field \\\"xxx\\\" on type \\\"Subscription\\\".\"}},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"panic inside subscribe is recovered\",\n\t\t\tSchema: makeSubscriptionSchema(t, graphql.ObjectConfig{\n\t\t\t\tName: \"Subscription\",\n\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\"should_error\": &graphql.Field{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\tSubscribe: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\t\tpanic(errors.New(\"got a panic error\"))\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tQuery: `\n\t\t\t\tsubscription {\n\t\t\t\t\tshould_error\n\t\t\t\t}\n\t\t\t`,\n\t\t\tExpectedResults: []testutil.TestResponse{\n\t\t\t\t{Errors: []string{\"got a panic error\"}},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"subscribe with resolver changes output\",\n\t\t\tSchema: makeSubscriptionSchema(t, graphql.ObjectConfig{\n\t\t\t\tName: \"Subscription\",\n\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\"sub_with_resolver\": &graphql.Field{\n\t\t\t\t\t\tType:      graphql.String,\n\t\t\t\t\t\tSubscribe: makeSubscribeToStringFunction([]string{\"a\", \"b\", \"c\", \"d\"}),\n\t\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\t\treturn fmt.Sprintf(\"result=%v\", p.Source), nil\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tQuery: `\n\t\t\t\tsubscription {\n\t\t\t\t\tsub_with_resolver\n\t\t\t\t}\n\t\t\t`,\n\t\t\tExpectedResults: []testutil.TestResponse{\n\t\t\t\t{Data: `{ \"sub_with_resolver\": \"result=a\" }`},\n\t\t\t\t{Data: `{ \"sub_with_resolver\": \"result=b\" }`},\n\t\t\t\t{Data: `{ \"sub_with_resolver\": \"result=c\" }`},\n\t\t\t\t{Data: `{ \"sub_with_resolver\": \"result=d\" }`},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"subscribe to a nested object\",\n\t\t\tSchema: makeSubscriptionSchema(t, graphql.ObjectConfig{\n\t\t\t\tName: \"Subscription\",\n\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\"sub_with_object\": &graphql.Field{\n\t\t\t\t\t\tType: graphql.NewObject(graphql.ObjectConfig{\n\t\t\t\t\t\t\tName: \"Obj\",\n\t\t\t\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\t\t\t\"field\": &graphql.Field{\n\t\t\t\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\t\treturn p.Source, nil\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSubscribe: makeSubscribeToMapFunction([]map[string]interface{}{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"field\": \"hello\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"field\": \"bye\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"field\": nil,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tQuery: `\n\t\t\t\tsubscription {\n\t\t\t\t\tsub_with_object {\n\t\t\t\t\t\tfield\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\tExpectedResults: []testutil.TestResponse{\n\t\t\t\t{Data: `{ \"sub_with_object\": { \"field\": \"hello\" } }`},\n\t\t\t\t{Data: `{ \"sub_with_object\": { \"field\": \"bye\" } }`},\n\t\t\t\t{Data: `{ \"sub_with_object\": { \"field\": null } }`},\n\t\t\t},\n\t\t},\n\n\t\t{\n\t\t\tName: \"subscription_resolver_can_error\",\n\t\t\tSchema: makeSubscriptionSchema(t, graphql.ObjectConfig{\n\t\t\t\tName: \"Subscription\",\n\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\"should_error\": &graphql.Field{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t\tSubscribe: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\t\treturn nil, errors.New(\"got a subscribe error\")\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tQuery: `\n\t\t\t\tsubscription {\n\t\t\t\t\tshould_error\n\t\t\t\t}\n\t\t\t`,\n\t\t\tExpectedResults: []testutil.TestResponse{\n\t\t\t\t{\n\t\t\t\t\tErrors: []string{\"got a subscribe error\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"schema_without_subscribe_errors\",\n\t\t\tSchema: makeSubscriptionSchema(t, graphql.ObjectConfig{\n\t\t\t\tName: \"Subscription\",\n\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\"should_error\": &graphql.Field{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tQuery: `\n\t\t\t\tsubscription {\n\t\t\t\t\tshould_error\n\t\t\t\t}\n\t\t\t`,\n\t\t\tExpectedResults: []testutil.TestResponse{\n\t\t\t\t{\n\t\t\t\t\tErrors: []string{\"the subscription function \\\"should_error\\\" is not defined\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc makeSubscribeToStringFunction(elements []string) func(p graphql.ResolveParams) (interface{}, error) {\n\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\tc := make(chan interface{})\n\t\tgo func() {\n\t\t\tfor _, r := range elements {\n\t\t\t\tselect {\n\t\t\t\tcase <-p.Context.Done():\n\t\t\t\t\tclose(c)\n\t\t\t\t\treturn\n\t\t\t\tcase c <- r:\n\t\t\t\t}\n\t\t\t}\n\t\t\tclose(c)\n\t\t}()\n\t\treturn c, nil\n\t}\n}\n\nfunc makeSubscribeToMapFunction(elements []map[string]interface{}) func(p graphql.ResolveParams) (interface{}, error) {\n\treturn func(p graphql.ResolveParams) (interface{}, error) {\n\t\tc := make(chan interface{})\n\t\tgo func() {\n\t\t\tfor _, r := range elements {\n\t\t\t\tselect {\n\t\t\t\tcase <-p.Context.Done():\n\t\t\t\t\tclose(c)\n\t\t\t\t\treturn\n\t\t\t\tcase c <- r:\n\t\t\t\t}\n\t\t\t}\n\t\t\tclose(c)\n\t\t}()\n\t\treturn c, nil\n\t}\n}\n\nfunc makeSubscriptionSchema(t *testing.T, c graphql.ObjectConfig) graphql.Schema {\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery:        dummyQuery,\n\t\tSubscription: graphql.NewObject(c),\n\t})\n\tif err != nil {\n\t\tt.Errorf(\"failed to create schema: %v\", err)\n\t}\n\treturn schema\n}\n\nvar dummyQuery = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Query\",\n\tFields: graphql.Fields{\n\n\t\t\"hello\": &graphql.Field{Type: graphql.String},\n\t},\n})\n"
  },
  {
    "path": "suggested_list_internal_test.go",
    "content": "package graphql\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestSuggestionList_ReturnsResultsWhenInputIsEmpty(t *testing.T) {\n\texpected := []string{\"a\"}\n\tresult := suggestionList(\"\", []string{\"a\"})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Expected %v, got: %v\", expected, result)\n\t}\n}\nfunc TestSuggestionList_ReturnsEmptyArrayWhenThereAreNoOptions(t *testing.T) {\n\texpected := []string{}\n\tresult := suggestionList(\"input\", []string{})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Expected %v, got: %v\", expected, result)\n\t}\n}\nfunc TestSuggestionList_ReturnsOptionsSortedBasedOnSimilarity(t *testing.T) {\n\texpected := []string{\"abc\", \"ab\"}\n\tresult := suggestionList(\"abc\", []string{\"a\", \"ab\", \"abc\"})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Expected %v, got: %v\", expected, result)\n\t}\n}\n"
  },
  {
    "path": "testutil/introspection_query.go",
    "content": "package testutil\n\nvar IntrospectionQuery = `\n  query IntrospectionQuery {\n    __schema {\n      queryType { name }\n      mutationType { name }\n      subscriptionType { name }\n      types {\n        ...FullType\n      }\n      directives {\n        name\n        description\n\t\tlocations\n        args {\n          ...InputValue\n        }\n        # deprecated, but included for coverage till removed\n\t\tonOperation\n        onFragment\n        onField\n      }\n    }\n  }\n\n  fragment FullType on __Type {\n    kind\n    name\n    description\n    fields(includeDeprecated: true) {\n      name\n      description\n      args {\n        ...InputValue\n      }\n      type {\n        ...TypeRef\n      }\n      isDeprecated\n      deprecationReason\n    }\n    inputFields {\n      ...InputValue\n    }\n    interfaces {\n      ...TypeRef\n    }\n    enumValues(includeDeprecated: true) {\n      name\n      description\n      isDeprecated\n      deprecationReason\n    }\n    possibleTypes {\n      ...TypeRef\n    }\n  }\n\n  fragment InputValue on __InputValue {\n    name\n    description\n    type { ...TypeRef }\n    defaultValue\n  }\n\n  fragment TypeRef on __Type {\n    kind\n    name\n    ofType {\n      kind\n      name\n      ofType {\n        kind\n        name\n        ofType {\n          kind\n          name\n          ofType {\n            kind\n            name\n            ofType {\n              kind\n              name\n              ofType {\n                kind\n                name\n                ofType {\n                  kind\n                  name\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n`\n"
  },
  {
    "path": "testutil/rules_test_harness.go",
    "content": "package testutil\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/language/parser\"\n\t\"github.com/graphql-go/graphql/language/source\"\n)\n\nvar TestSchema *graphql.Schema\n\nfunc init() {\n\n\tvar beingInterface = graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"Being\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"surname\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tvar petInterface = graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"Pet\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"surname\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tvar canineInterface = graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"Canine\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"surname\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tvar dogCommandEnum = graphql.NewEnum(graphql.EnumConfig{\n\t\tName: \"DogCommand\",\n\t\tValues: graphql.EnumValueConfigMap{\n\t\t\t\"SIT\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 0,\n\t\t\t},\n\t\t\t\"HEEL\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 1,\n\t\t\t},\n\t\t\t\"DOWN\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 2,\n\t\t\t},\n\t\t},\n\t})\n\tvar dogType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Dog\",\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"surname\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"nickname\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"barkVolume\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t\t\"barks\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t\t\"doesKnowCommand\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"dogCommand\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: dogCommandEnum,\n\t\t\t\t\t},\n\t\t\t\t\t\"nextDogCommand\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: dogCommandEnum,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"isHousetrained\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"atOtherHomes\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType:         graphql.Boolean,\n\t\t\t\t\t\tDefaultValue: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"isAtLocation\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"x\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t\t\"y\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tbeingInterface,\n\t\t\tpetInterface,\n\t\t\tcanineInterface,\n\t\t},\n\t})\n\tvar furColorEnum = graphql.NewEnum(graphql.EnumConfig{\n\t\tName: \"FurColor\",\n\t\tValues: graphql.EnumValueConfigMap{\n\t\t\t\"BROWN\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 0,\n\t\t\t},\n\t\t\t\"BLACK\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 1,\n\t\t\t},\n\t\t\t\"TAN\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 2,\n\t\t\t},\n\t\t\t\"SPOTTED\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 3,\n\t\t\t},\n\t\t},\n\t})\n\n\tvar catType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Cat\",\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"surname\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"nickname\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"meowVolume\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t\t\"meows\": &graphql.Field{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t\t\"furColor\": &graphql.Field{\n\t\t\t\tType: furColorEnum,\n\t\t\t},\n\t\t},\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tbeingInterface,\n\t\t\tpetInterface,\n\t\t},\n\t})\n\tvar catOrDogUnion = graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"CatOrDog\",\n\t\tTypes: []*graphql.Object{\n\t\t\tdogType,\n\t\t\tcatType,\n\t\t},\n\t})\n\tvar intelligentInterface = graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"Intelligent\",\n\t\tFields: graphql.Fields{\n\t\t\t\"iq\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t})\n\n\tvar humanType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Human\",\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tbeingInterface,\n\t\t\tintelligentInterface,\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"surname\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"pets\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(petInterface),\n\t\t\t},\n\t\t\t\"iq\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t})\n\n\thumanType.AddFieldConfig(\"relatives\", &graphql.Field{\n\t\tType: graphql.NewList(humanType),\n\t})\n\n\tvar alienType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Alien\",\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tbeingInterface,\n\t\t\tintelligentInterface,\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"surname\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"iq\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t\t\"numEyes\": &graphql.Field{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t},\n\t})\n\tvar dogOrHumanUnion = graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"DogOrHuman\",\n\t\tTypes: []*graphql.Object{\n\t\t\tdogType,\n\t\t\thumanType,\n\t\t},\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\t// not used for validation\n\t\t\treturn nil\n\t\t},\n\t})\n\tvar humanOrAlienUnion = graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"HumanOrAlien\",\n\t\tTypes: []*graphql.Object{\n\t\t\talienType,\n\t\t\thumanType,\n\t\t},\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\t// not used for validation\n\t\t\treturn nil\n\t\t},\n\t})\n\n\tvar complexInputObject = graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"ComplexInput\",\n\t\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\t\"requiredField\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.NewNonNull(graphql.Boolean),\n\t\t\t},\n\t\t\t\"intField\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.Int,\n\t\t\t},\n\t\t\t\"stringField\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"booleanField\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.Boolean,\n\t\t\t},\n\t\t\t\"stringListField\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.NewList(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\tvar complicatedArgs = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"ComplicatedArgs\",\n\t\t// TODO List\n\t\t// TODO Coercion\n\t\t// TODO NotNulls\n\t\tFields: graphql.Fields{\n\t\t\t\"intArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"intArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Int,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"nonNullIntArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"nonNullIntArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.NewNonNull(graphql.Int),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"stringArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"stringArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"booleanArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"booleanArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Boolean,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"enumArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"enumArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: furColorEnum,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"floatArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"floatArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.Float,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"idArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"idArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.ID,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"stringListArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"stringListArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.NewList(graphql.String),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"complexArgField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"complexArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: complexInputObject,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"multipleReqs\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"req1\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.NewNonNull(graphql.Int),\n\t\t\t\t\t},\n\t\t\t\t\t\"req2\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.NewNonNull(graphql.Int),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"multipleOpts\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"opt1\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType:         graphql.Int,\n\t\t\t\t\t\tDefaultValue: 0,\n\t\t\t\t\t},\n\t\t\t\t\t\"opt2\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType:         graphql.Int,\n\t\t\t\t\t\tDefaultValue: 0,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"multipleOptAndReq\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"req1\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.NewNonNull(graphql.Int),\n\t\t\t\t\t},\n\t\t\t\t\t\"req2\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.NewNonNull(graphql.Int),\n\t\t\t\t\t},\n\t\t\t\t\t\"opt1\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType:         graphql.Int,\n\t\t\t\t\t\tDefaultValue: 0,\n\t\t\t\t\t},\n\t\t\t\t\t\"opt2\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType:         graphql.Int,\n\t\t\t\t\t\tDefaultValue: 0,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tqueryRoot := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"QueryRoot\",\n\t\tFields: graphql.Fields{\n\t\t\t\"human\": &graphql.Field{\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.ID,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tType: humanType,\n\t\t\t},\n\t\t\t\"alien\": &graphql.Field{\n\t\t\t\tType: alienType,\n\t\t\t},\n\t\t\t\"dog\": &graphql.Field{\n\t\t\t\tType: dogType,\n\t\t\t},\n\t\t\t\"cat\": &graphql.Field{\n\t\t\t\tType: catType,\n\t\t\t},\n\t\t\t\"pet\": &graphql.Field{\n\t\t\t\tType: petInterface,\n\t\t\t},\n\t\t\t\"catOrDog\": &graphql.Field{\n\t\t\t\tType: catOrDogUnion,\n\t\t\t},\n\t\t\t\"dogOrHuman\": &graphql.Field{\n\t\t\t\tType: dogOrHumanUnion,\n\t\t\t},\n\t\t\t\"humanOrAlien\": &graphql.Field{\n\t\t\t\tType: humanOrAlienUnion,\n\t\t\t},\n\t\t\t\"complicatedArgs\": &graphql.Field{\n\t\t\t\tType: complicatedArgs,\n\t\t\t},\n\t\t},\n\t})\n\tschema, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryRoot,\n\t\tDirectives: []*graphql.Directive{\n\t\t\tgraphql.IncludeDirective,\n\t\t\tgraphql.SkipDirective,\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onQuery\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationQuery},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onMutation\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationMutation},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onSubscription\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationSubscription},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onField\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationField},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onFragmentDefinition\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationFragmentDefinition},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onFragmentSpread\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationFragmentSpread},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onInlineFragment\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationInlineFragment},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onSchema\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationSchema},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onScalar\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationScalar},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onObject\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationObject},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onFieldDefinition\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationFieldDefinition},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onArgumentDefinition\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationArgumentDefinition},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onInterface\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationInterface},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onUnion\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationUnion},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onEnum\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationEnum},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onEnumValue\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationEnumValue},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onInputObject\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationInputObject},\n\t\t\t}),\n\t\t\tgraphql.NewDirective(graphql.DirectiveConfig{\n\t\t\t\tName:      \"onInputFieldDefinition\",\n\t\t\t\tLocations: []string{graphql.DirectiveLocationInputFieldDefinition},\n\t\t\t}),\n\t\t},\n\t\tTypes: []graphql.Type{\n\t\t\tcatType,\n\t\t\tdogType,\n\t\t\thumanType,\n\t\t\talienType,\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tTestSchema = &schema\n\n}\nfunc expectValidRule(t *testing.T, schema *graphql.Schema, rules []graphql.ValidationRuleFn, queryString string) {\n\tsource := source.NewSource(&source.Source{\n\t\tBody: []byte(queryString),\n\t})\n\tAST, err := parser.Parse(parser.ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tresult := graphql.ValidateDocument(schema, AST, rules)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"Should validate, got %v\", result.Errors)\n\t}\n\tif result.IsValid != true {\n\t\tt.Fatalf(\"IsValid should be true, got %v\", result.IsValid)\n\t}\n\n}\nfunc expectInvalidRule(t *testing.T, schema *graphql.Schema, rules []graphql.ValidationRuleFn, queryString string, expectedErrors []gqlerrors.FormattedError) {\n\tsource := source.NewSource(&source.Source{\n\t\tBody: []byte(queryString),\n\t})\n\tAST, err := parser.Parse(parser.ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tresult := graphql.ValidateDocument(schema, AST, rules)\n\tif len(result.Errors) != len(expectedErrors) {\n\t\tt.Fatalf(\"Should have %v errors, got %v\", len(expectedErrors), len(result.Errors))\n\t}\n\tif result.IsValid != false {\n\t\tt.Fatalf(\"IsValid should be false, got %v\", result.IsValid)\n\t}\n\tfor _, expectedErr := range expectedErrors {\n\t\tfound := false\n\t\tfor _, err := range result.Errors {\n\t\t\tif EqualFormattedError(expectedErr, err) {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif found == false {\n\t\t\tt.Fatalf(\"Unexpected result, Diff: %v\", Diff(expectedErrors, result.Errors))\n\t\t}\n\t}\n\n}\nfunc ExpectPassesRule(t *testing.T, rule graphql.ValidationRuleFn, queryString string) {\n\texpectValidRule(t, TestSchema, []graphql.ValidationRuleFn{rule}, queryString)\n}\nfunc ExpectFailsRule(t *testing.T, rule graphql.ValidationRuleFn, queryString string, expectedErrors []gqlerrors.FormattedError) {\n\texpectInvalidRule(t, TestSchema, []graphql.ValidationRuleFn{rule}, queryString, expectedErrors)\n}\nfunc ExpectFailsRuleWithSchema(t *testing.T, schema *graphql.Schema, rule graphql.ValidationRuleFn, queryString string, expectedErrors []gqlerrors.FormattedError) {\n\texpectInvalidRule(t, schema, []graphql.ValidationRuleFn{rule}, queryString, expectedErrors)\n}\nfunc ExpectPassesRuleWithSchema(t *testing.T, schema *graphql.Schema, rule graphql.ValidationRuleFn, queryString string) {\n\texpectValidRule(t, schema, []graphql.ValidationRuleFn{rule}, queryString)\n}\nfunc RuleError(message string, locs ...int) gqlerrors.FormattedError {\n\tlocations := []location.SourceLocation{}\n\tfor i := 0; i < len(locs); i += 2 {\n\t\tline := locs[i]\n\t\tcol := 0\n\t\tif i+1 < len(locs) {\n\t\t\tcol = locs[i+1]\n\t\t}\n\t\tlocations = append(locations, location.SourceLocation{\n\t\t\tLine:   line,\n\t\t\tColumn: col,\n\t\t})\n\t}\n\treturn gqlerrors.FormattedError{\n\t\tMessage:   message,\n\t\tLocations: locations,\n\t}\n}\n"
  },
  {
    "path": "testutil/subscription.go",
    "content": "package testutil\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n)\n\n// TestResponse models the expected response\ntype TestResponse struct {\n\tData   string\n\tErrors []string\n}\n\n// TestSubscription is a GraphQL test case to be used with RunSubscribe.\ntype TestSubscription struct {\n\tName            string\n\tSchema          graphql.Schema\n\tQuery           string\n\tOperationName   string\n\tVariables       map[string]interface{}\n\tExpectedResults []TestResponse\n}\n\n// RunSubscribes runs the given GraphQL subscription test cases as subtests.\nfunc RunSubscribes(t *testing.T, tests []*TestSubscription) {\n\tfor i, test := range tests {\n\t\tif test.Name == \"\" {\n\t\t\ttest.Name = strconv.Itoa(i + 1)\n\t\t}\n\n\t\tt.Run(test.Name, func(t *testing.T) {\n\t\t\tRunSubscribe(t, test)\n\t\t})\n\t}\n}\n\n// RunSubscribe runs a single GraphQL subscription test case.\nfunc RunSubscribe(t *testing.T, test *TestSubscription) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\tc := graphql.Subscribe(graphql.Params{\n\t\tContext:        ctx,\n\t\tOperationName:  test.OperationName,\n\t\tRequestString:  test.Query,\n\t\tVariableValues: test.Variables,\n\t\tSchema:         test.Schema,\n\t})\n\t// if err != nil {\n\t// \tif err.Error() != test.ExpectedErr.Error() {\n\t// \t\tt.Fatalf(\"unexpected error: got %+v, want %+v\", err, test.ExpectedErr)\n\t// \t}\n\n\t// \treturn\n\t// }\n\n\tvar results []*graphql.Result\n\tfor res := range c {\n\t\tt.Log(pretty(res))\n\t\tresults = append(results, res)\n\t}\n\n\tfor i, expected := range test.ExpectedResults {\n\t\tif len(results)-1 < i {\n\t\t\tt.Error(errors.New(\"not enough results, expected results are more than actual results\"))\n\t\t\treturn\n\t\t}\n\t\tres := results[i]\n\n\t\tvar errs []string\n\t\tfor _, err := range res.Errors {\n\t\t\terrs = append(errs, err.Message)\n\t\t}\n\t\tcheckErrorStrings(t, expected.Errors, errs)\n\t\tif expected.Data == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tgot, err := json.MarshalIndent(res.Data, \"\", \"  \")\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"got: invalid JSON: %s; raw: %s\", err, got)\n\t\t}\n\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\twant, err := formatJSON(expected.Data)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"got: invalid JSON: %s; raw: %s\", err, res.Data)\n\t\t}\n\n\t\tif !bytes.Equal(got, want) {\n\t\t\tt.Logf(\"got:  %s\", got)\n\t\t\tt.Logf(\"want: %s\", want)\n\t\t\tt.Fail()\n\t\t}\n\t}\n}\n\nfunc checkErrorStrings(t *testing.T, expected, actual []string) {\n\texpectedCount, actualCount := len(expected), len(actual)\n\n\tif expectedCount != actualCount {\n\t\tt.Fatalf(\"unexpected number of errors: want `%d`, got `%d`\", expectedCount, actualCount)\n\t}\n\n\tif expectedCount > 0 {\n\t\tfor i, want := range expected {\n\t\t\tgot := actual[i]\n\n\t\t\tif got != want {\n\t\t\t\tt.Fatalf(\"unexpected error: got `%+v`, want `%+v`\", got, want)\n\t\t\t}\n\t\t}\n\n\t\t// Return because we're done checking.\n\t\treturn\n\t}\n\n\tfor _, err := range actual {\n\t\tt.Errorf(\"unexpected error: '%s'\", err)\n\t}\n}\n\nfunc formatJSON(data string) ([]byte, error) {\n\tvar v interface{}\n\tif err := json.Unmarshal([]byte(data), &v); err != nil {\n\t\treturn nil, err\n\t}\n\tformatted, err := json.MarshalIndent(v, \"\", \"  \")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn formatted, nil\n}\n\nfunc pretty(x interface{}) string {\n\tgot, err := json.MarshalIndent(x, \"\", \"  \")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn string(got)\n}\n"
  },
  {
    "path": "testutil/testutil.go",
    "content": "package testutil\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/parser\"\n)\n\nvar (\n\tLuke           StarWarsChar\n\tVader          StarWarsChar\n\tHan            StarWarsChar\n\tLeia           StarWarsChar\n\tTarkin         StarWarsChar\n\tThreepio       StarWarsChar\n\tArtoo          StarWarsChar\n\tHumanData      map[int]StarWarsChar\n\tDroidData      map[int]StarWarsChar\n\tStarWarsSchema graphql.Schema\n\n\thumanType *graphql.Object\n\tdroidType *graphql.Object\n)\n\ntype StarWarsChar struct {\n\tID              string\n\tName            string\n\tFriends         []StarWarsChar\n\tAppearsIn       []int\n\tHomePlanet      string\n\tPrimaryFunction string\n}\n\nfunc init() {\n\tLuke = StarWarsChar{\n\t\tID:         \"1000\",\n\t\tName:       \"Luke Skywalker\",\n\t\tAppearsIn:  []int{4, 5, 6},\n\t\tHomePlanet: \"Tatooine\",\n\t}\n\tVader = StarWarsChar{\n\t\tID:         \"1001\",\n\t\tName:       \"Darth Vader\",\n\t\tAppearsIn:  []int{4, 5, 6},\n\t\tHomePlanet: \"Tatooine\",\n\t}\n\tHan = StarWarsChar{\n\t\tID:        \"1002\",\n\t\tName:      \"Han Solo\",\n\t\tAppearsIn: []int{4, 5, 6},\n\t}\n\tLeia = StarWarsChar{\n\t\tID:         \"1003\",\n\t\tName:       \"Leia Organa\",\n\t\tAppearsIn:  []int{4, 5, 6},\n\t\tHomePlanet: \"Alderaa\",\n\t}\n\tTarkin = StarWarsChar{\n\t\tID:        \"1004\",\n\t\tName:      \"Wilhuff Tarkin\",\n\t\tAppearsIn: []int{4},\n\t}\n\tThreepio = StarWarsChar{\n\t\tID:              \"2000\",\n\t\tName:            \"C-3PO\",\n\t\tAppearsIn:       []int{4, 5, 6},\n\t\tPrimaryFunction: \"Protocol\",\n\t}\n\tArtoo = StarWarsChar{\n\t\tID:              \"2001\",\n\t\tName:            \"R2-D2\",\n\t\tAppearsIn:       []int{4, 5, 6},\n\t\tPrimaryFunction: \"Astromech\",\n\t}\n\tLuke.Friends = append(Luke.Friends, []StarWarsChar{Han, Leia, Threepio, Artoo}...)\n\tVader.Friends = append(Vader.Friends, []StarWarsChar{Tarkin}...)\n\tHan.Friends = append(Han.Friends, []StarWarsChar{Luke, Leia, Artoo}...)\n\tLeia.Friends = append(Leia.Friends, []StarWarsChar{Luke, Han, Threepio, Artoo}...)\n\tTarkin.Friends = append(Tarkin.Friends, []StarWarsChar{Vader}...)\n\tThreepio.Friends = append(Threepio.Friends, []StarWarsChar{Luke, Han, Leia, Artoo}...)\n\tArtoo.Friends = append(Artoo.Friends, []StarWarsChar{Luke, Han, Leia}...)\n\tHumanData = map[int]StarWarsChar{\n\t\t1000: Luke,\n\t\t1001: Vader,\n\t\t1002: Han,\n\t\t1003: Leia,\n\t\t1004: Tarkin,\n\t}\n\tDroidData = map[int]StarWarsChar{\n\t\t2000: Threepio,\n\t\t2001: Artoo,\n\t}\n\n\tepisodeEnum := graphql.NewEnum(graphql.EnumConfig{\n\t\tName:        \"Episode\",\n\t\tDescription: \"One of the films in the Star Wars Trilogy\",\n\t\tValues: graphql.EnumValueConfigMap{\n\t\t\t\"NEWHOPE\": &graphql.EnumValueConfig{\n\t\t\t\tValue:       4,\n\t\t\t\tDescription: \"Released in 1977.\",\n\t\t\t},\n\t\t\t\"EMPIRE\": &graphql.EnumValueConfig{\n\t\t\t\tValue:       5,\n\t\t\t\tDescription: \"Released in 1980.\",\n\t\t\t},\n\t\t\t\"JEDI\": &graphql.EnumValueConfig{\n\t\t\t\tValue:       6,\n\t\t\t\tDescription: \"Released in 1983.\",\n\t\t\t},\n\t\t},\n\t})\n\n\tcharacterInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName:        \"Character\",\n\t\tDescription: \"A character in the Star Wars Trilogy\",\n\t\tFields: graphql.Fields{\n\t\t\t\"id\": &graphql.Field{\n\t\t\t\tType:        graphql.NewNonNull(graphql.String),\n\t\t\t\tDescription: \"The id of the character.\",\n\t\t\t},\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType:        graphql.String,\n\t\t\t\tDescription: \"The name of the character.\",\n\t\t\t},\n\t\t\t\"appearsIn\": &graphql.Field{\n\t\t\t\tType:        graphql.NewList(episodeEnum),\n\t\t\t\tDescription: \"Which movies they appear in.\",\n\t\t\t},\n\t\t},\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\tif character, ok := p.Value.(StarWarsChar); ok {\n\t\t\t\tid, _ := strconv.Atoi(character.ID)\n\t\t\t\thuman := GetHuman(id)\n\t\t\t\tif human.ID != \"\" {\n\t\t\t\t\treturn humanType\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn droidType\n\t\t},\n\t})\n\tcharacterInterface.AddFieldConfig(\"friends\", &graphql.Field{\n\t\tType:        graphql.NewList(characterInterface),\n\t\tDescription: \"The friends of the character, or an empty list if they have none.\",\n\t})\n\n\thumanType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName:        \"Human\",\n\t\tDescription: \"A humanoid creature in the Star Wars universe.\",\n\t\tFields: graphql.Fields{\n\t\t\t\"id\": &graphql.Field{\n\t\t\t\tType:        graphql.NewNonNull(graphql.String),\n\t\t\t\tDescription: \"The id of the human.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif human, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn human.ID, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType:        graphql.String,\n\t\t\t\tDescription: \"The name of the human.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif human, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn human.Name, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"friends\": &graphql.Field{\n\t\t\t\tType:        graphql.NewList(characterInterface),\n\t\t\t\tDescription: \"The friends of the human, or an empty list if they have none.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif human, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn human.Friends, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn []interface{}{}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"appearsIn\": &graphql.Field{\n\t\t\t\tType:        graphql.NewList(episodeEnum),\n\t\t\t\tDescription: \"Which movies they appear in.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif human, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn human.AppearsIn, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"homePlanet\": &graphql.Field{\n\t\t\t\tType:        graphql.String,\n\t\t\t\tDescription: \"The home planet of the human, or null if unknown.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif human, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn human.HomePlanet, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tcharacterInterface,\n\t\t},\n\t})\n\tdroidType = graphql.NewObject(graphql.ObjectConfig{\n\t\tName:        \"Droid\",\n\t\tDescription: \"A mechanical creature in the Star Wars universe.\",\n\t\tFields: graphql.Fields{\n\t\t\t\"id\": &graphql.Field{\n\t\t\t\tType:        graphql.NewNonNull(graphql.String),\n\t\t\t\tDescription: \"The id of the droid.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif droid, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn droid.ID, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType:        graphql.String,\n\t\t\t\tDescription: \"The name of the droid.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif droid, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn droid.Name, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"friends\": &graphql.Field{\n\t\t\t\tType:        graphql.NewList(characterInterface),\n\t\t\t\tDescription: \"The friends of the droid, or an empty list if they have none.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif droid, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\tfriends := []map[string]interface{}{}\n\t\t\t\t\t\tfor _, friend := range droid.Friends {\n\t\t\t\t\t\t\tfriends = append(friends, map[string]interface{}{\n\t\t\t\t\t\t\t\t\"name\": friend.Name,\n\t\t\t\t\t\t\t\t\"id\":   friend.ID,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn droid.Friends, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn []interface{}{}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"appearsIn\": &graphql.Field{\n\t\t\t\tType:        graphql.NewList(episodeEnum),\n\t\t\t\tDescription: \"Which movies they appear in.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif droid, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn droid.AppearsIn, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"primaryFunction\": &graphql.Field{\n\t\t\t\tType:        graphql.String,\n\t\t\t\tDescription: \"The primary function of the droid.\",\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tif droid, ok := p.Source.(StarWarsChar); ok {\n\t\t\t\t\t\treturn droid.PrimaryFunction, nil\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tcharacterInterface,\n\t\t},\n\t})\n\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"hero\": &graphql.Field{\n\t\t\t\tType: characterInterface,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"episode\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tDescription: \"If omitted, returns the hero of the whole saga. If \" +\n\t\t\t\t\t\t\t\"provided, returns the hero of that particular episode.\",\n\t\t\t\t\t\tType: episodeEnum,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn GetHero(p.Args[\"episode\"]), nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"human\": &graphql.Field{\n\t\t\t\tType: humanType,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tDescription: \"id of the human\",\n\t\t\t\t\t\tType:        graphql.NewNonNull(graphql.String),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\tid, err := strconv.Atoi(p.Args[\"id\"].(string))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\treturn GetHuman(id), nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"droid\": &graphql.Field{\n\t\t\t\tType: droidType,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"id\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tDescription: \"id of the droid\",\n\t\t\t\t\t\tType:        graphql.NewNonNull(graphql.String),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\treturn GetDroid(p.Args[\"id\"].(int)), nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tStarWarsSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n}\n\nfunc GetHuman(id int) StarWarsChar {\n\tif human, ok := HumanData[id]; ok {\n\t\treturn human\n\t}\n\treturn StarWarsChar{}\n}\nfunc GetDroid(id int) StarWarsChar {\n\tif droid, ok := DroidData[id]; ok {\n\t\treturn droid\n\t}\n\treturn StarWarsChar{}\n}\nfunc GetHero(episode interface{}) interface{} {\n\tif episode == 5 {\n\t\treturn Luke\n\t}\n\treturn Artoo\n}\n\n// Test helper functions\n\nfunc TestParse(t *testing.T, query string) *ast.Document {\n\tastDoc, err := parser.Parse(parser.ParseParams{\n\t\tSource: query,\n\t\tOptions: parser.ParseOptions{\n\t\t\t// include source, for error reporting\n\t\t\tNoSource: false,\n\t\t},\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Parse failed: %v\", err)\n\t}\n\treturn astDoc\n}\nfunc TestExecute(t *testing.T, ep graphql.ExecuteParams) *graphql.Result {\n\treturn graphql.Execute(ep)\n}\n\nfunc Diff(want, got interface{}) []string {\n\treturn []string{fmt.Sprintf(\"\\ngot: %v\", got), fmt.Sprintf(\"\\nwant: %v\\n\", want)}\n}\n\nfunc ASTToJSON(t *testing.T, a ast.Node) interface{} {\n\tb, err := json.Marshal(a)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to marshal Node %v\", err)\n\t}\n\tvar f interface{}\n\terr = json.Unmarshal(b, &f)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to unmarshal Node %v\", err)\n\t}\n\treturn f\n}\n\nfunc ContainSubsetSlice(super []interface{}, sub []interface{}) bool {\n\tif len(sub) == 0 {\n\t\treturn true\n\t}\nsubLoop:\n\tfor _, subVal := range sub {\n\t\tfound := false\n\tinnerLoop:\n\t\tfor _, superVal := range super {\n\t\t\tif subVal, ok := subVal.(map[string]interface{}); ok {\n\t\t\t\tif superVal, ok := superVal.(map[string]interface{}); ok {\n\t\t\t\t\tif ContainSubset(superVal, subVal) {\n\t\t\t\t\t\tfound = true\n\t\t\t\t\t\tbreak innerLoop\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t}\n\t\t\tif subVal, ok := subVal.([]interface{}); ok {\n\t\t\t\tif superVal, ok := superVal.([]interface{}); ok {\n\t\t\t\t\tif ContainSubsetSlice(superVal, subVal) {\n\t\t\t\t\t\tfound = true\n\t\t\t\t\t\tbreak innerLoop\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif reflect.DeepEqual(superVal, subVal) {\n\t\t\t\tfound = true\n\t\t\t\tbreak innerLoop\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn false\n\t\t}\n\t\tcontinue subLoop\n\t}\n\treturn true\n}\n\nfunc ContainSubset(super map[string]interface{}, sub map[string]interface{}) bool {\n\tif len(sub) == 0 {\n\t\treturn true\n\t}\n\tfor subKey, subVal := range sub {\n\t\tif superVal, ok := super[subKey]; ok {\n\t\t\tswitch superVal := superVal.(type) {\n\t\t\tcase []interface{}:\n\t\t\t\tif subVal, ok := subVal.([]interface{}); ok {\n\t\t\t\t\tif !ContainSubsetSlice(superVal, subVal) {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\tcase map[string]interface{}:\n\t\t\t\tif subVal, ok := subVal.(map[string]interface{}); ok {\n\t\t\t\t\tif !ContainSubset(superVal, subVal) {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif !reflect.DeepEqual(superVal, subVal) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc EqualErrorMessage(expected, result *graphql.Result, i int) bool {\n\treturn expected.Errors[i].Message == result.Errors[i].Message\n}\n\nfunc EqualFormattedError(exp, act gqlerrors.FormattedError) bool {\n\tif exp.Message != act.Message {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(exp.Locations, act.Locations) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(exp.Path, act.Path) {\n\t\treturn false\n\t}\n\tif !reflect.DeepEqual(exp.Extensions, act.Extensions) {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc EqualFormattedErrors(expected, actual []gqlerrors.FormattedError) bool {\n\tif len(expected) != len(actual) {\n\t\treturn false\n\t}\n\tfor i := range expected {\n\t\tif !EqualFormattedError(expected[i], actual[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc EqualResults(expected, result *graphql.Result) bool {\n\tif !reflect.DeepEqual(expected.Data, result.Data) {\n\t\treturn false\n\t}\n\treturn EqualFormattedErrors(expected.Errors, result.Errors)\n}\n"
  },
  {
    "path": "testutil/testutil_test.go",
    "content": "package testutil_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc TestSubsetSlice_Simple(t *testing.T) {\n\n\tsuper := []interface{}{\n\t\t\"1\", \"2\", \"3\",\n\t}\n\tsub := []interface{}{\n\t\t\"3\",\n\t}\n\tif !testutil.ContainSubsetSlice(super, sub) {\n\t\tt.Fatalf(\"expected slice to be subset of super, got false\")\n\t}\n}\nfunc TestSubsetSlice_Simple_Fail(t *testing.T) {\n\n\tsuper := []interface{}{\n\t\t\"1\", \"2\", \"3\",\n\t}\n\tsub := []interface{}{\n\t\t\"4\",\n\t}\n\tif testutil.ContainSubsetSlice(super, sub) {\n\t\tt.Fatalf(\"expected slice to not be subset of super, got true\")\n\t}\n}\nfunc TestSubsetSlice_NestedSlice(t *testing.T) {\n\n\tsuper := []interface{}{\n\t\t[]interface{}{\n\t\t\t\"1\", \"2\", \"3\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"4\", \"5\", \"6\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"7\", \"8\", \"9\",\n\t\t},\n\t}\n\tsub := []interface{}{\n\t\t[]interface{}{\n\t\t\t\"2\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"9\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"5\",\n\t\t},\n\t}\n\tif !testutil.ContainSubsetSlice(super, sub) {\n\t\tt.Fatalf(\"expected slice to be subset of super, got false\")\n\t}\n}\nfunc TestSubsetSlice_NestedSlice_DifferentLength(t *testing.T) {\n\n\tsuper := []interface{}{\n\t\t[]interface{}{\n\t\t\t\"1\", \"2\", \"3\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"4\", \"5\", \"6\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"7\", \"8\", \"9\",\n\t\t},\n\t}\n\tsub := []interface{}{\n\t\t[]interface{}{\n\t\t\t\"3\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"6\",\n\t\t},\n\t}\n\tif !testutil.ContainSubsetSlice(super, sub) {\n\t\tt.Fatalf(\"expected slice to be subset of super, got false\")\n\t}\n}\nfunc TestSubsetSlice_NestedSlice_Fail(t *testing.T) {\n\n\tsuper := []interface{}{\n\t\t[]interface{}{\n\t\t\t\"1\", \"2\", \"3\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"4\", \"5\", \"6\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"7\", \"8\", \"9\",\n\t\t},\n\t}\n\tsub := []interface{}{\n\t\t[]interface{}{\n\t\t\t\"3\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"3\",\n\t\t},\n\t\t[]interface{}{\n\t\t\t\"9\",\n\t\t},\n\t}\n\tif !testutil.ContainSubsetSlice(super, sub) {\n\t\tt.Fatalf(\"expected slice to be subset of super, got false\")\n\t}\n}\n\nfunc TestSubset_Simple(t *testing.T) {\n\n\tsuper := map[string]interface{}{\n\t\t\"a\": \"1\",\n\t\t\"b\": \"2\",\n\t\t\"c\": \"3\",\n\t}\n\tsub := map[string]interface{}{\n\t\t\"c\": \"3\",\n\t}\n\tif !testutil.ContainSubset(super, sub) {\n\t\tt.Fatalf(\"expected map to be subset of super, got false\")\n\t}\n\n}\nfunc TestSubset_Simple_Fail(t *testing.T) {\n\n\tsuper := map[string]interface{}{\n\t\t\"a\": \"1\",\n\t\t\"b\": \"2\",\n\t\t\"c\": \"3\",\n\t}\n\tsub := map[string]interface{}{\n\t\t\"d\": \"3\",\n\t}\n\tif testutil.ContainSubset(super, sub) {\n\t\tt.Fatalf(\"expected map to not be subset of super, got true\")\n\t}\n\n}\nfunc TestSubset_NestedMap(t *testing.T) {\n\n\tsuper := map[string]interface{}{\n\t\t\"a\": \"1\",\n\t\t\"b\": \"2\",\n\t\t\"c\": \"3\",\n\t\t\"d\": map[string]interface{}{\n\t\t\t\"aa\": \"11\",\n\t\t\t\"bb\": \"22\",\n\t\t\t\"cc\": \"33\",\n\t\t},\n\t}\n\tsub := map[string]interface{}{\n\t\t\"c\": \"3\",\n\t\t\"d\": map[string]interface{}{\n\t\t\t\"cc\": \"33\",\n\t\t},\n\t}\n\tif !testutil.ContainSubset(super, sub) {\n\t\tt.Fatalf(\"expected map to be subset of super, got false\")\n\t}\n}\nfunc TestSubset_NestedMap_Fail(t *testing.T) {\n\n\tsuper := map[string]interface{}{\n\t\t\"a\": \"1\",\n\t\t\"b\": \"2\",\n\t\t\"c\": \"3\",\n\t\t\"d\": map[string]interface{}{\n\t\t\t\"aa\": \"11\",\n\t\t\t\"bb\": \"22\",\n\t\t\t\"cc\": \"33\",\n\t\t},\n\t}\n\tsub := map[string]interface{}{\n\t\t\"c\": \"3\",\n\t\t\"d\": map[string]interface{}{\n\t\t\t\"dd\": \"44\",\n\t\t},\n\t}\n\tif testutil.ContainSubset(super, sub) {\n\t\tt.Fatalf(\"expected map to not be subset of super, got true\")\n\t}\n}\nfunc TestSubset_NestedSlice(t *testing.T) {\n\n\tsuper := map[string]interface{}{\n\t\t\"a\": \"1\",\n\t\t\"b\": \"2\",\n\t\t\"c\": \"3\",\n\t\t\"d\": []interface{}{\n\t\t\t\"11\", \"22\",\n\t\t},\n\t}\n\tsub := map[string]interface{}{\n\t\t\"c\": \"3\",\n\t\t\"d\": []interface{}{\n\t\t\t\"11\",\n\t\t},\n\t}\n\tif !testutil.ContainSubset(super, sub) {\n\t\tt.Fatalf(\"expected map to be subset of super, got false\")\n\t}\n}\nfunc TestSubset_ComplexMixed(t *testing.T) {\n\n\tsuper := map[string]interface{}{\n\t\t\"a\": \"1\",\n\t\t\"b\": \"2\",\n\t\t\"c\": \"3\",\n\t\t\"d\": map[string]interface{}{\n\t\t\t\"aa\": \"11\",\n\t\t\t\"bb\": \"22\",\n\t\t\t\"cc\": []interface{}{\n\t\t\t\t\"ttt\", \"rrr\", \"sss\",\n\t\t\t},\n\t\t},\n\t\t\"e\": []interface{}{\n\t\t\t\"111\", \"222\", \"333\",\n\t\t},\n\t\t\"f\": []interface{}{\n\t\t\t[]interface{}{\n\t\t\t\t\"9999\", \"8888\", \"7777\",\n\t\t\t},\n\t\t\t[]interface{}{\n\t\t\t\t\"6666\", \"5555\", \"4444\",\n\t\t\t},\n\t\t},\n\t}\n\tsub := map[string]interface{}{\n\t\t\"c\": \"3\",\n\t\t\"d\": map[string]interface{}{\n\t\t\t\"bb\": \"22\",\n\t\t\t\"cc\": []interface{}{\n\t\t\t\t\"sss\",\n\t\t\t},\n\t\t},\n\t\t\"e\": []interface{}{\n\t\t\t\"111\",\n\t\t},\n\t\t\"f\": []interface{}{\n\t\t\t[]interface{}{\n\t\t\t\t\"8888\", \"9999\",\n\t\t\t},\n\t\t\t[]interface{}{\n\t\t\t\t\"4444\",\n\t\t\t},\n\t\t},\n\t}\n\tif !testutil.ContainSubset(super, sub) {\n\t\tt.Fatalf(\"expected map to be subset of super, got false\")\n\t}\n}\nfunc TestSubset_ComplexMixed_Fail(t *testing.T) {\n\n\tsuper := map[string]interface{}{\n\t\t\"a\": \"1\",\n\t\t\"b\": \"2\",\n\t\t\"c\": \"3\",\n\t\t\"d\": map[string]interface{}{\n\t\t\t\"aa\": \"11\",\n\t\t\t\"bb\": \"22\",\n\t\t\t\"cc\": []interface{}{\n\t\t\t\t\"ttt\", \"rrr\", \"sss\",\n\t\t\t},\n\t\t},\n\t\t\"e\": []interface{}{\n\t\t\t\"111\", \"222\", \"333\",\n\t\t},\n\t\t\"f\": []interface{}{\n\t\t\t[]interface{}{\n\t\t\t\t\"9999\", \"8888\", \"7777\",\n\t\t\t},\n\t\t\t[]interface{}{\n\t\t\t\t\"6666\", \"5555\", \"4444\",\n\t\t\t},\n\t\t},\n\t}\n\tsub := map[string]interface{}{\n\t\t\"c\": \"3\",\n\t\t\"d\": map[string]interface{}{\n\t\t\t\"bb\": \"22\",\n\t\t\t\"cc\": []interface{}{\n\t\t\t\t\"doesnotexist\",\n\t\t\t},\n\t\t},\n\t\t\"e\": []interface{}{\n\t\t\t\"111\",\n\t\t},\n\t\t\"f\": []interface{}{\n\t\t\t[]interface{}{\n\t\t\t\t\"4444\",\n\t\t\t},\n\t\t},\n\t}\n\tif testutil.ContainSubset(super, sub) {\n\t\tt.Fatalf(\"expected map to not be subset of super, got true\")\n\t}\n}\n"
  },
  {
    "path": "type_comparators_internal_test.go",
    "content": "package graphql\n\nimport (\n\t\"testing\"\n)\n\nfunc TestIsEqualType_SameReferenceAreEqual(t *testing.T) {\n\tif !isEqualType(String, String) {\n\t\tt.Fatalf(\"Expected same reference to be equal\")\n\t}\n}\n\nfunc TestIsEqualType_IntAndFloatAreNotEqual(t *testing.T) {\n\tif isEqualType(Int, Float) {\n\t\tt.Fatalf(\"Expected GraphQLInt and GraphQLFloat to not equal\")\n\t}\n}\n\nfunc TestIsEqualType_ListsOfSameTypeAreEqual(t *testing.T) {\n\tif !isEqualType(NewList(Int), NewList(Int)) {\n\t\tt.Fatalf(\"Expected lists of same type are equal\")\n\t}\n}\n\nfunc TestIsEqualType_ListsAreNotEqualToItem(t *testing.T) {\n\tif isEqualType(NewList(Int), Int) {\n\t\tt.Fatalf(\"Expected lists are not equal to item\")\n\t}\n}\n\nfunc TestIsEqualType_NonNullOfSameTypeAreEqual(t *testing.T) {\n\tif !isEqualType(NewNonNull(Int), NewNonNull(Int)) {\n\t\tt.Fatalf(\"Expected non-null of same type are equal\")\n\t}\n}\nfunc TestIsEqualType_NonNullIsNotEqualToNullable(t *testing.T) {\n\tif isEqualType(NewNonNull(Int), Int) {\n\t\tt.Fatalf(\"Expected non-null is not equal to nullable\")\n\t}\n}\n\nfunc testSchemaForIsTypeSubTypeOfTest(t *testing.T, fields Fields) *Schema {\n\tschema, err := NewSchema(SchemaConfig{\n\t\tQuery: NewObject(ObjectConfig{\n\t\t\tName:   \"Query\",\n\t\t\tFields: fields,\n\t\t}),\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"Invalid schema: %v\", err)\n\t}\n\treturn &schema\n}\n\nfunc TestIsTypeSubTypeOf_SameReferenceIsSubtype(t *testing.T) {\n\tschema := testSchemaForIsTypeSubTypeOfTest(t, Fields{\n\t\t\"field\": &Field{Type: String},\n\t})\n\tif !isTypeSubTypeOf(schema, String, String) {\n\t\tt.Fatalf(\"Expected same reference is subtype\")\n\t}\n}\nfunc TestIsTypeSubTypeOf_IntIsNotSubtypeOfFloat(t *testing.T) {\n\tschema := testSchemaForIsTypeSubTypeOfTest(t, Fields{\n\t\t\"field\": &Field{Type: String},\n\t})\n\tif isTypeSubTypeOf(schema, Int, Float) {\n\t\tt.Fatalf(\"Expected int is not subtype of float\")\n\t}\n}\nfunc TestIsTypeSubTypeOf_NonNullIsSubtypeOfNullable(t *testing.T) {\n\tschema := testSchemaForIsTypeSubTypeOfTest(t, Fields{\n\t\t\"field\": &Field{Type: String},\n\t})\n\tif !isTypeSubTypeOf(schema, NewNonNull(Int), Int) {\n\t\tt.Fatalf(\"Expected non-null is subtype of nullable\")\n\t}\n}\nfunc TestIsTypeSubTypeOf_NullableIsNotSubtypeOfNonNull(t *testing.T) {\n\tschema := testSchemaForIsTypeSubTypeOfTest(t, Fields{\n\t\t\"field\": &Field{Type: String},\n\t})\n\tif isTypeSubTypeOf(schema, Int, NewNonNull(Int)) {\n\t\tt.Fatalf(\"Expected nullable is not subtype of non-null\")\n\t}\n}\nfunc TestIsTypeSubTypeOf_ItemIsNotSubTypeOfList(t *testing.T) {\n\tschema := testSchemaForIsTypeSubTypeOfTest(t, Fields{\n\t\t\"field\": &Field{Type: String},\n\t})\n\tif isTypeSubTypeOf(schema, Int, NewList(Int)) {\n\t\tt.Fatalf(\"Expected item is not subtype of list\")\n\t}\n}\nfunc TestIsTypeSubTypeOf_ListIsNotSubtypeOfItem(t *testing.T) {\n\tschema := testSchemaForIsTypeSubTypeOfTest(t, Fields{\n\t\t\"field\": &Field{Type: String},\n\t})\n\tif isTypeSubTypeOf(schema, NewList(Int), Int) {\n\t\tt.Fatalf(\"Expected list is not subtype of item\")\n\t}\n}\n\nfunc TestIsTypeSubTypeOf_MemberIsSubtypeOfUnion(t *testing.T) {\n\tmemberType := NewObject(ObjectConfig{\n\t\tName: \"Object\",\n\t\tIsTypeOf: func(p IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tFields: Fields{\n\t\t\t\"field\": &Field{Type: String},\n\t\t},\n\t})\n\tunionType := NewUnion(UnionConfig{\n\t\tName:  \"Union\",\n\t\tTypes: []*Object{memberType},\n\t})\n\tschema := testSchemaForIsTypeSubTypeOfTest(t, Fields{\n\t\t\"field\": &Field{Type: unionType},\n\t})\n\tif !isTypeSubTypeOf(schema, memberType, unionType) {\n\t\tt.Fatalf(\"Expected member is subtype of union\")\n\t}\n}\n\nfunc TestIsTypeSubTypeOf_ImplementationIsSubtypeOfInterface(t *testing.T) {\n\tifaceType := NewInterface(InterfaceConfig{\n\t\tName: \"Interface\",\n\t\tFields: Fields{\n\t\t\t\"field\": &Field{Type: String},\n\t\t},\n\t})\n\timplType := NewObject(ObjectConfig{\n\t\tName: \"Object\",\n\t\tIsTypeOf: func(p IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tInterfaces: []*Interface{ifaceType},\n\t\tFields: Fields{\n\t\t\t\"field\": &Field{Type: String},\n\t\t},\n\t})\n\tschema := testSchemaForIsTypeSubTypeOfTest(t, Fields{\n\t\t\"field\": &Field{Type: implType},\n\t})\n\tif !isTypeSubTypeOf(schema, implType, ifaceType) {\n\t\tt.Fatalf(\"Expected implementation is subtype of interface\")\n\t}\n}\n"
  },
  {
    "path": "type_info.go",
    "content": "package graphql\n\nimport (\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/kinds\"\n)\n\n// TODO: can move TypeInfo to a utils package if there ever is one\n/**\n * TypeInfo is a utility class which, given a GraphQL schema, can keep track\n * of the current field and type definitions at any point in a GraphQL document\n * AST during a recursive descent by calling `enter(node)` and `leave(node)`.\n */\ntype fieldDefFn func(schema *Schema, parentType Type, fieldAST *ast.Field) *FieldDefinition\n\ntype TypeInfo struct {\n\tschema          *Schema\n\ttypeStack       []Output\n\tparentTypeStack []Composite\n\tinputTypeStack  []Input\n\tfieldDefStack   []*FieldDefinition\n\tdirective       *Directive\n\targument        *Argument\n\tgetFieldDef     fieldDefFn\n}\n\ntype TypeInfoConfig struct {\n\tSchema *Schema\n\n\t// NOTE: this experimental optional second parameter is only needed in order\n\t// to support non-spec-compliant codebases. You should never need to use it.\n\t// It may disappear in the future.\n\tFieldDefFn fieldDefFn\n}\n\nfunc NewTypeInfo(opts *TypeInfoConfig) *TypeInfo {\n\tgetFieldDef := opts.FieldDefFn\n\tif getFieldDef == nil {\n\t\tgetFieldDef = DefaultTypeInfoFieldDef\n\t}\n\treturn &TypeInfo{\n\t\tschema:      opts.Schema,\n\t\tgetFieldDef: getFieldDef,\n\t}\n}\n\nfunc (ti *TypeInfo) Type() Output {\n\tif len(ti.typeStack) > 0 {\n\t\treturn ti.typeStack[len(ti.typeStack)-1]\n\t}\n\treturn nil\n}\n\nfunc (ti *TypeInfo) ParentType() Composite {\n\tif len(ti.parentTypeStack) > 0 {\n\t\treturn ti.parentTypeStack[len(ti.parentTypeStack)-1]\n\t}\n\treturn nil\n}\n\nfunc (ti *TypeInfo) InputType() Input {\n\tif len(ti.inputTypeStack) > 0 {\n\t\treturn ti.inputTypeStack[len(ti.inputTypeStack)-1]\n\t}\n\treturn nil\n}\nfunc (ti *TypeInfo) FieldDef() *FieldDefinition {\n\tif len(ti.fieldDefStack) > 0 {\n\t\treturn ti.fieldDefStack[len(ti.fieldDefStack)-1]\n\t}\n\treturn nil\n}\n\nfunc (ti *TypeInfo) Directive() *Directive {\n\treturn ti.directive\n}\n\nfunc (ti *TypeInfo) Argument() *Argument {\n\treturn ti.argument\n}\n\nfunc (ti *TypeInfo) Enter(node ast.Node) {\n\n\tschema := ti.schema\n\tvar ttype Type\n\tswitch node := node.(type) {\n\tcase *ast.SelectionSet:\n\t\tnamedType := GetNamed(ti.Type())\n\t\tvar compositeType Composite\n\t\tif IsCompositeType(namedType) {\n\t\t\tcompositeType, _ = namedType.(Composite)\n\t\t}\n\t\tti.parentTypeStack = append(ti.parentTypeStack, compositeType)\n\tcase *ast.Field:\n\t\tparentType := ti.ParentType()\n\t\tvar fieldDef *FieldDefinition\n\t\tif parentType != nil {\n\t\t\tfieldDef = ti.getFieldDef(schema, parentType.(Type), node)\n\t\t}\n\t\tti.fieldDefStack = append(ti.fieldDefStack, fieldDef)\n\t\tif fieldDef != nil {\n\t\t\tti.typeStack = append(ti.typeStack, fieldDef.Type)\n\t\t} else {\n\t\t\tti.typeStack = append(ti.typeStack, nil)\n\t\t}\n\tcase *ast.Directive:\n\t\tnameVal := \"\"\n\t\tif node.Name != nil {\n\t\t\tnameVal = node.Name.Value\n\t\t}\n\t\tti.directive = schema.Directive(nameVal)\n\tcase *ast.OperationDefinition:\n\t\tif node.Operation == ast.OperationTypeQuery {\n\t\t\tttype = schema.QueryType()\n\t\t} else if node.Operation == ast.OperationTypeMutation {\n\t\t\tttype = schema.MutationType()\n\t\t} else if node.Operation == ast.OperationTypeSubscription {\n\t\t\tttype = schema.SubscriptionType()\n\t\t}\n\t\tti.typeStack = append(ti.typeStack, ttype)\n\tcase *ast.InlineFragment:\n\t\ttypeConditionAST := node.TypeCondition\n\t\tif typeConditionAST != nil {\n\t\t\tttype, _ = typeFromAST(*schema, node.TypeCondition)\n\t\t\tti.typeStack = append(ti.typeStack, ttype)\n\t\t} else {\n\t\t\tti.typeStack = append(ti.typeStack, ti.Type())\n\t\t}\n\tcase *ast.FragmentDefinition:\n\t\ttypeConditionAST := node.TypeCondition\n\t\tif typeConditionAST != nil {\n\t\t\tttype, _ = typeFromAST(*schema, typeConditionAST)\n\t\t\tti.typeStack = append(ti.typeStack, ttype)\n\t\t} else {\n\t\t\tti.typeStack = append(ti.typeStack, ti.Type())\n\t\t}\n\tcase *ast.VariableDefinition:\n\t\tttype, _ = typeFromAST(*schema, node.Type)\n\t\tti.inputTypeStack = append(ti.inputTypeStack, ttype)\n\tcase *ast.Argument:\n\t\tnameVal := \"\"\n\t\tif node.Name != nil {\n\t\t\tnameVal = node.Name.Value\n\t\t}\n\t\tvar argType Input\n\t\tvar argDef *Argument\n\t\tdirective := ti.Directive()\n\t\tfieldDef := ti.FieldDef()\n\t\tif directive != nil {\n\t\t\tfor _, arg := range directive.Args {\n\t\t\t\tif arg.Name() == nameVal {\n\t\t\t\t\targDef = arg\n\t\t\t\t}\n\t\t\t}\n\t\t} else if fieldDef != nil {\n\t\t\tfor _, arg := range fieldDef.Args {\n\t\t\t\tif arg.Name() == nameVal {\n\t\t\t\t\targDef = arg\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif argDef != nil {\n\t\t\targType = argDef.Type\n\t\t}\n\t\tti.argument = argDef\n\t\tti.inputTypeStack = append(ti.inputTypeStack, argType)\n\tcase *ast.ListValue:\n\t\tlistType := GetNullable(ti.InputType())\n\t\tif list, ok := listType.(*List); ok {\n\t\t\tti.inputTypeStack = append(ti.inputTypeStack, list.OfType)\n\t\t} else {\n\t\t\tti.inputTypeStack = append(ti.inputTypeStack, nil)\n\t\t}\n\tcase *ast.ObjectField:\n\t\tvar fieldType Input\n\t\tobjectType := GetNamed(ti.InputType())\n\n\t\tif objectType, ok := objectType.(*InputObject); ok {\n\t\t\tnameVal := \"\"\n\t\t\tif node.Name != nil {\n\t\t\t\tnameVal = node.Name.Value\n\t\t\t}\n\t\t\tif inputField, ok := objectType.Fields()[nameVal]; ok {\n\t\t\t\tfieldType = inputField.Type\n\t\t\t}\n\t\t}\n\t\tti.inputTypeStack = append(ti.inputTypeStack, fieldType)\n\t}\n}\nfunc (ti *TypeInfo) Leave(node ast.Node) {\n\tkind := node.GetKind()\n\tswitch kind {\n\tcase kinds.SelectionSet:\n\t\t// pop ti.parentTypeStack\n\t\tif len(ti.parentTypeStack) > 0 {\n\t\t\t_, ti.parentTypeStack = ti.parentTypeStack[len(ti.parentTypeStack)-1], ti.parentTypeStack[:len(ti.parentTypeStack)-1]\n\t\t}\n\tcase kinds.Field:\n\t\t// pop ti.fieldDefStack\n\t\tif len(ti.fieldDefStack) > 0 {\n\t\t\t_, ti.fieldDefStack = ti.fieldDefStack[len(ti.fieldDefStack)-1], ti.fieldDefStack[:len(ti.fieldDefStack)-1]\n\t\t}\n\t\t// pop ti.typeStack\n\t\tif len(ti.typeStack) > 0 {\n\t\t\t_, ti.typeStack = ti.typeStack[len(ti.typeStack)-1], ti.typeStack[:len(ti.typeStack)-1]\n\t\t}\n\tcase kinds.Directive:\n\t\tti.directive = nil\n\tcase kinds.OperationDefinition, kinds.InlineFragment, kinds.FragmentDefinition:\n\t\t// pop ti.typeStack\n\t\tif len(ti.typeStack) > 0 {\n\t\t\t_, ti.typeStack = ti.typeStack[len(ti.typeStack)-1], ti.typeStack[:len(ti.typeStack)-1]\n\t\t}\n\tcase kinds.VariableDefinition:\n\t\t// pop ti.inputTypeStack\n\t\tif len(ti.inputTypeStack) > 0 {\n\t\t\t_, ti.inputTypeStack = ti.inputTypeStack[len(ti.inputTypeStack)-1], ti.inputTypeStack[:len(ti.inputTypeStack)-1]\n\t\t}\n\tcase kinds.Argument:\n\t\tti.argument = nil\n\t\t// pop ti.inputTypeStack\n\t\tif len(ti.inputTypeStack) > 0 {\n\t\t\t_, ti.inputTypeStack = ti.inputTypeStack[len(ti.inputTypeStack)-1], ti.inputTypeStack[:len(ti.inputTypeStack)-1]\n\t\t}\n\tcase kinds.ListValue, kinds.ObjectField:\n\t\t// pop ti.inputTypeStack\n\t\tif len(ti.inputTypeStack) > 0 {\n\t\t\t_, ti.inputTypeStack = ti.inputTypeStack[len(ti.inputTypeStack)-1], ti.inputTypeStack[:len(ti.inputTypeStack)-1]\n\t\t}\n\t}\n}\n\n// DefaultTypeInfoFieldDef Not exactly the same as the executor's definition of FieldDef, in this\n// statically evaluated environment we do not always have an Object type,\n// and need to handle Interface and Union types.\nfunc DefaultTypeInfoFieldDef(schema *Schema, parentType Type, fieldAST *ast.Field) *FieldDefinition {\n\tname := \"\"\n\tif fieldAST.Name != nil {\n\t\tname = fieldAST.Name.Value\n\t}\n\tif name == SchemaMetaFieldDef.Name &&\n\t\tschema.QueryType() == parentType {\n\t\treturn SchemaMetaFieldDef\n\t}\n\tif name == TypeMetaFieldDef.Name &&\n\t\tschema.QueryType() == parentType {\n\t\treturn TypeMetaFieldDef\n\t}\n\tif name == TypeNameMetaFieldDef.Name && parentType != nil {\n\t\tif t, ok := parentType.(*Object); ok && t != nil {\n\t\t\treturn TypeNameMetaFieldDef\n\t\t}\n\t\tif t, ok := parentType.(*Interface); ok && t != nil {\n\t\t\treturn TypeNameMetaFieldDef\n\t\t}\n\t\tif t, ok := parentType.(*Union); ok && t != nil {\n\t\t\treturn TypeNameMetaFieldDef\n\t\t}\n\t}\n\n\tif parentType, ok := parentType.(*Object); ok && parentType != nil {\n\t\tfield, _ := parentType.Fields()[name]\n\t\treturn field\n\t}\n\tif parentType, ok := parentType.(*Interface); ok && parentType != nil {\n\t\tfield, _ := parentType.Fields()[name]\n\t\treturn field\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "types.go",
    "content": "package graphql\n\nimport (\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n)\n\n// type Schema interface{}\n\n// Result has the response, errors and extensions from the resolved schema\ntype Result struct {\n\tData       interface{}                `json:\"data\"`\n\tErrors     []gqlerrors.FormattedError `json:\"errors,omitempty\"`\n\tExtensions map[string]interface{}     `json:\"extensions,omitempty\"`\n}\n\n// HasErrors just a simple function to help you decide if the result has errors or not\nfunc (r *Result) HasErrors() bool {\n\treturn len(r.Errors) > 0\n}\n"
  },
  {
    "path": "union_interface_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\ntype testNamedType interface {\n}\ntype testPet interface {\n}\ntype testDog2 struct {\n\tName  string `json:\"name\"`\n\tBarks bool   `json:\"barks\"`\n}\n\ntype testCat2 struct {\n\tName  string `json:\"name\"`\n\tMeows bool   `json:\"meows\"`\n}\n\ntype testPerson struct {\n\tName    string          `json:\"name\"`\n\tPets    []testPet       `json:\"pets\"`\n\tFriends []testNamedType `json:\"friends\"`\n}\n\nvar namedType = graphql.NewInterface(graphql.InterfaceConfig{\n\tName: \"Named\",\n\tFields: graphql.Fields{\n\t\t\"name\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t},\n})\nvar dogType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Dog\",\n\tInterfaces: []*graphql.Interface{\n\t\tnamedType,\n\t},\n\tFields: graphql.Fields{\n\t\t\"name\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"barks\": &graphql.Field{\n\t\t\tType: graphql.Boolean,\n\t\t},\n\t},\n\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t_, ok := p.Value.(*testDog2)\n\t\treturn ok\n\t},\n})\nvar catType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Cat\",\n\tInterfaces: []*graphql.Interface{\n\t\tnamedType,\n\t},\n\tFields: graphql.Fields{\n\t\t\"name\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"meows\": &graphql.Field{\n\t\t\tType: graphql.Boolean,\n\t\t},\n\t},\n\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t_, ok := p.Value.(*testCat2)\n\t\treturn ok\n\t},\n})\nvar petType = graphql.NewUnion(graphql.UnionConfig{\n\tName: \"Pet\",\n\tTypes: []*graphql.Object{\n\t\tdogType, catType,\n\t},\n\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\tif _, ok := p.Value.(*testCat2); ok {\n\t\t\treturn catType\n\t\t}\n\t\tif _, ok := p.Value.(*testDog2); ok {\n\t\t\treturn dogType\n\t\t}\n\t\treturn nil\n\t},\n})\nvar personType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"Person\",\n\tInterfaces: []*graphql.Interface{\n\t\tnamedType,\n\t},\n\tFields: graphql.Fields{\n\t\t\"name\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"pets\": &graphql.Field{\n\t\t\tType: graphql.NewList(petType),\n\t\t},\n\t\t\"friends\": &graphql.Field{\n\t\t\tType: graphql.NewList(namedType),\n\t\t},\n\t},\n\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t_, ok := p.Value.(*testPerson)\n\t\treturn ok\n\t},\n})\n\nvar unionInterfaceTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\tQuery: personType,\n\tTypes: []graphql.Type{petType},\n})\n\nvar garfield = &testCat2{\"Garfield\", false}\nvar odie = &testDog2{\"Odie\", true}\nvar liz = &testPerson{\n\tName: \"Liz\",\n}\nvar john = &testPerson{\n\tName: \"John\",\n\tPets: []testPet{\n\t\tgarfield, odie,\n\t},\n\tFriends: []testNamedType{\n\t\tliz, odie,\n\t},\n}\n\nfunc TestUnionIntersectionTypes_CanIntrospectOnUnionAndIntersectionTypes(t *testing.T) {\n\tdoc := `\n      {\n        Named: __type(name: \"Named\") {\n          kind\n          name\n          fields { name }\n          interfaces { name }\n          possibleTypes { name }\n          enumValues { name }\n          inputFields { name }\n        }\n        Pet: __type(name: \"Pet\") {\n          kind\n          name\n          fields { name }\n          interfaces { name }\n          possibleTypes { name }\n          enumValues { name }\n          inputFields { name }\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"Named\": map[string]interface{}{\n\t\t\t\t\"kind\": \"INTERFACE\",\n\t\t\t\t\"name\": \"Named\",\n\t\t\t\t\"fields\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"name\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"interfaces\": nil,\n\t\t\t\t\"possibleTypes\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"Dog\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"Cat\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"Person\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"enumValues\":  nil,\n\t\t\t\t\"inputFields\": nil,\n\t\t\t},\n\t\t\t\"Pet\": map[string]interface{}{\n\t\t\t\t\"kind\":       \"UNION\",\n\t\t\t\t\"name\":       \"Pet\",\n\t\t\t\t\"fields\":     nil,\n\t\t\t\t\"interfaces\": nil,\n\t\t\t\t\"possibleTypes\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"Dog\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"name\": \"Cat\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"enumValues\":  nil,\n\t\t\t\t\"inputFields\": nil,\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: unionInterfaceTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !testutil.ContainSubset(expected.Data.(map[string]interface{}), result.Data.(map[string]interface{})) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected.Data, result.Data))\n\t}\n}\nfunc TestUnionIntersectionTypes_ExecutesUsingUnionTypes(t *testing.T) {\n\t// NOTE: This is an *invalid* query, but it should be an *executable* query.\n\tdoc := `\n      {\n        __typename\n        name\n        pets {\n          __typename\n          name\n          barks\n          meows\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__typename\": \"Person\",\n\t\t\t\"name\":       \"John\",\n\t\t\t\"pets\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Cat\",\n\t\t\t\t\t\"name\":       \"Garfield\",\n\t\t\t\t\t\"meows\":      false,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Dog\",\n\t\t\t\t\t\"name\":       \"Odie\",\n\t\t\t\t\t\"barks\":      true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: unionInterfaceTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   john,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestUnionIntersectionTypes_ExecutesUnionTypesWithInlineFragments(t *testing.T) {\n\t// This is the valid version of the query in the above test.\n\tdoc := `\n      {\n        __typename\n        name\n        pets {\n          __typename\n          ... on Dog {\n            name\n            barks\n          }\n          ... on Cat {\n            name\n            meows\n          }\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__typename\": \"Person\",\n\t\t\t\"name\":       \"John\",\n\t\t\t\"pets\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Cat\",\n\t\t\t\t\t\"name\":       \"Garfield\",\n\t\t\t\t\t\"meows\":      false,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Dog\",\n\t\t\t\t\t\"name\":       \"Odie\",\n\t\t\t\t\t\"barks\":      true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: unionInterfaceTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   john,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestUnionIntersectionTypes_ExecutesUsingInterfaceTypes(t *testing.T) {\n\n\t// NOTE: This is an *invalid* query, but it should be an *executable* query.\n\tdoc := `\n      {\n        __typename\n        name\n        friends {\n          __typename\n          name\n          barks\n          meows\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__typename\": \"Person\",\n\t\t\t\"name\":       \"John\",\n\t\t\t\"friends\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Person\",\n\t\t\t\t\t\"name\":       \"Liz\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Dog\",\n\t\t\t\t\t\"name\":       \"Odie\",\n\t\t\t\t\t\"barks\":      true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: unionInterfaceTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   john,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestUnionIntersectionTypes_ExecutesInterfaceTypesWithInlineFragments(t *testing.T) {\n\n\t// This is the valid version of the query in the above test.\n\tdoc := `\n      {\n        __typename\n        name\n        friends {\n          __typename\n          name\n          ... on Dog {\n            barks\n          }\n          ... on Cat {\n            meows\n          }\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__typename\": \"Person\",\n\t\t\t\"name\":       \"John\",\n\t\t\t\"friends\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Person\",\n\t\t\t\t\t\"name\":       \"Liz\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Dog\",\n\t\t\t\t\t\"name\":       \"Odie\",\n\t\t\t\t\t\"barks\":      true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: unionInterfaceTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   john,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestUnionIntersectionTypes_AllowsFragmentConditionsToBeAbstractTypes(t *testing.T) {\n\n\tdoc := `\n      {\n        __typename\n        name\n        pets { ...PetFields }\n        friends { ...FriendFields }\n      }\n\n      fragment PetFields on Pet {\n        __typename\n        ... on Dog {\n          name\n          barks\n        }\n        ... on Cat {\n          name\n          meows\n        }\n      }\n\n      fragment FriendFields on Named {\n        __typename\n        name\n        ... on Dog {\n          barks\n        }\n        ... on Cat {\n          meows\n        }\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"__typename\": \"Person\",\n\t\t\t\"name\":       \"John\",\n\t\t\t\"friends\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Person\",\n\t\t\t\t\t\"name\":       \"Liz\",\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Dog\",\n\t\t\t\t\t\"name\":       \"Odie\",\n\t\t\t\t\t\"barks\":      true,\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"pets\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Cat\",\n\t\t\t\t\t\"name\":       \"Garfield\",\n\t\t\t\t\t\"meows\":      false,\n\t\t\t\t},\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"__typename\": \"Dog\",\n\t\t\t\t\t\"name\":       \"Odie\",\n\t\t\t\t\t\"barks\":      true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: unionInterfaceTestSchema,\n\t\tAST:    ast,\n\t\tRoot:   john,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestUnionIntersectionTypes_GetsExecutionInfoInResolver(t *testing.T) {\n\n\tvar encounteredContextValue string\n\tvar encounteredSchema graphql.Schema\n\tvar encounteredRootValue string\n\tvar personType2 *graphql.Object\n\n\tnamedType2 := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"Named\",\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\tencounteredSchema = p.Info.Schema\n\t\t\tencounteredContextValue, _ = p.Context.Value(\"authToken\").(string)\n\t\t\tencounteredRootValue = p.Info.RootValue.(*testPerson).Name\n\t\t\treturn personType2\n\t\t},\n\t})\n\n\tpersonType2 = graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Person\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tnamedType2,\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"name\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"friends\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(namedType2),\n\t\t\t},\n\t\t},\n\t})\n\n\tschema2, _ := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: personType2,\n\t})\n\n\tjohn2 := &testPerson{\n\t\tName: \"John\",\n\t\tFriends: []testNamedType{\n\t\t\tliz,\n\t\t},\n\t}\n\n\tdoc := `{ name, friends { name } }`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"name\": \"John\",\n\t\t\t\"friends\": []interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"name\": \"Liz\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// create context\n\tctx := context.Background()\n\tctx = context.WithValue(ctx, \"authToken\", \"contextStringValue123\")\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema:  schema2,\n\t\tAST:     ast,\n\t\tRoot:    john2,\n\t\tContext: ctx,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n\tif !reflect.DeepEqual(\"contextStringValue123\", encounteredContextValue) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(\"contextStringValue123\", encounteredContextValue))\n\t}\n\tif !reflect.DeepEqual(\"John\", encounteredRootValue) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(\"John\", encounteredRootValue))\n\t}\n\tif !reflect.DeepEqual(schema2, encounteredSchema) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(schema2, encounteredSchema))\n\t}\n}\n\nfunc TestUnionIntersectionTypes_ValueMayBeNilPointer(t *testing.T) {\n\tvar unionInterfaceTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"query\": &graphql.Field{\n\t\t\t\t\tType: graphql.NewObject(graphql.ObjectConfig{\n\t\t\t\t\t\tName: \"query\",\n\t\t\t\t\t\tFields: graphql.Fields{\n\t\t\t\t\t\t\t\"pet\": &graphql.Field{\n\t\t\t\t\t\t\t\tType: petType,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"named\": &graphql.Field{\n\t\t\t\t\t\t\t\tType: namedType,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t\tResolve: func(_ graphql.ResolveParams) (interface{}, error) {\n\t\t\t\t\t\treturn struct {\n\t\t\t\t\t\t\tPet   *testCat2 `graphql:\"pet\"`\n\t\t\t\t\t\t\tNamed *testCat2 `graphql:\"named\"`\n\t\t\t\t\t\t}{nil, nil}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n\tquery := `{\n\t\tquery {\n\t\t\tpet {\n\t\t\t\t__typename\n\t\t\t}\n\t\t\tnamed {\n\t\t\t\t__typename\n\t\t\t\tname\n\t\t\t}\n\t\t}\n\t}`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"query\": map[string]interface{}{\n\t\t\t\t\"pet\":   nil,\n\t\t\t\t\"named\": nil,\n\t\t\t}},\n\t}\n\tresult := g(t, graphql.Params{\n\t\tSchema:        unionInterfaceTestSchema,\n\t\tRequestString: query,\n\t})\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  },
  {
    "path": "util.go",
    "content": "package graphql\n\nimport (\n\t\"encoding\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n)\n\nconst TAG = \"json\"\n\n// can't take recursive slice type\n// e.g\n// type Person struct{\n//\tFriends []Person\n// }\n// it will throw panic stack-overflow\nfunc BindFields(obj interface{}) Fields {\n\tt := reflect.TypeOf(obj)\n\tv := reflect.ValueOf(obj)\n\tfields := make(map[string]*Field)\n\n\tif t.Kind() == reflect.Ptr {\n\t\tt = t.Elem()\n\t\tv = v.Elem()\n\t}\n\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tfield := t.Field(i)\n\n\t\ttag := extractTag(field.Tag)\n\t\tif tag == \"-\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tfieldType := field.Type\n\n\t\tif fieldType.Kind() == reflect.Ptr {\n\t\t\tfieldType = fieldType.Elem()\n\t\t}\n\n\t\tvar graphType Output\n\t\tif fieldType.Kind() == reflect.Struct {\n\t\t\titf := v.Field(i).Interface()\n\t\t\tif _, ok := itf.(encoding.TextMarshaler); ok {\n\t\t\t\tfieldType = reflect.TypeOf(\"\")\n\t\t\t\tgoto nonStruct\n\t\t\t}\n\n\t\t\tstructFields := BindFields(itf)\n\n\t\t\tif tag == \"\" {\n\t\t\t\tfields = appendFields(fields, structFields)\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\tgraphType = NewObject(ObjectConfig{\n\t\t\t\t\tName:   tag,\n\t\t\t\t\tFields: structFields,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\tnonStruct:\n\t\tif tag == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif graphType == nil {\n\t\t\tgraphType = getGraphType(fieldType)\n\t\t}\n\t\tfields[tag] = &Field{\n\t\t\tType: graphType,\n\t\t\tResolve: func(p ResolveParams) (interface{}, error) {\n\t\t\t\treturn extractValue(tag, p.Source), nil\n\t\t\t},\n\t\t}\n\t}\n\treturn fields\n}\n\nfunc getGraphType(tipe reflect.Type) Output {\n\tkind := tipe.Kind()\n\tswitch kind {\n\tcase reflect.String:\n\t\treturn String\n\tcase reflect.Int, reflect.Int8, reflect.Int32, reflect.Int64:\n\t\treturn Int\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn Float\n\tcase reflect.Bool:\n\t\treturn Boolean\n\tcase reflect.Slice:\n\t\treturn getGraphList(tipe)\n\t}\n\treturn String\n}\n\nfunc getGraphList(tipe reflect.Type) *List {\n\tif tipe.Kind() == reflect.Slice {\n\t\tswitch tipe.Elem().Kind() {\n\t\tcase reflect.Int, reflect.Int8, reflect.Int32, reflect.Int64:\n\t\t\treturn NewList(Int)\n\t\tcase reflect.Bool:\n\t\t\treturn NewList(Boolean)\n\t\tcase reflect.Float32, reflect.Float64:\n\t\t\treturn NewList(Float)\n\t\tcase reflect.String:\n\t\t\treturn NewList(String)\n\t\t}\n\t}\n\t// finally bind object\n\tt := reflect.New(tipe.Elem())\n\tname := strings.Replace(fmt.Sprint(tipe.Elem()), \".\", \"_\", -1)\n\tobj := NewObject(ObjectConfig{\n\t\tName:   name,\n\t\tFields: BindFields(t.Elem().Interface()),\n\t})\n\treturn NewList(obj)\n}\n\nfunc appendFields(dest, origin Fields) Fields {\n\tfor key, value := range origin {\n\t\tdest[key] = value\n\t}\n\treturn dest\n}\n\nfunc extractValue(originTag string, obj interface{}) interface{} {\n\tval := reflect.Indirect(reflect.ValueOf(obj))\n\n\tfor j := 0; j < val.NumField(); j++ {\n\t\tfield := val.Type().Field(j)\n\t\tfound := originTag == extractTag(field.Tag)\n\t\tif field.Type.Kind() == reflect.Struct {\n\t\t\titf := val.Field(j).Interface()\n\n\t\t\tif str, ok := itf.(encoding.TextMarshaler); ok && found {\n\t\t\t\tbyt, _ := str.MarshalText()\n\t\t\t\treturn string(byt)\n\t\t\t}\n\n\t\t\tres := extractValue(originTag, itf)\n\t\t\tif res != nil {\n\t\t\t\treturn res\n\t\t\t}\n\t\t}\n\n\t\tif found {\n\t\t\treturn reflect.Indirect(val.Field(j)).Interface()\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc extractTag(tag reflect.StructTag) string {\n\tt := tag.Get(TAG)\n\tif t != \"\" {\n\t\tt = strings.Split(t, \",\")[0]\n\t}\n\treturn t\n}\n\n// lazy way of binding args\nfunc BindArg(obj interface{}, tags ...string) FieldConfigArgument {\n\tv := reflect.Indirect(reflect.ValueOf(obj))\n\tvar config = make(FieldConfigArgument)\n\tfor i := 0; i < v.NumField(); i++ {\n\t\tfield := v.Type().Field(i)\n\n\t\tmytag := extractTag(field.Tag)\n\t\tif inArray(tags, mytag) {\n\t\t\tconfig[mytag] = &ArgumentConfig{\n\t\t\t\tType: getGraphType(field.Type),\n\t\t\t}\n\t\t}\n\t}\n\treturn config\n}\n\nfunc inArray(slice interface{}, item interface{}) bool {\n\ts := reflect.ValueOf(slice)\n\tif s.Kind() != reflect.Slice {\n\t\tpanic(\"inArray() given a non-slice type\")\n\t}\n\n\tfor i := 0; i < s.Len(); i++ {\n\t\tif reflect.DeepEqual(item, s.Index(i).Interface()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "util_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"encoding/json\"\n\t\"log\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\ntype Person struct {\n\tHuman\n\tName    string   `json:\"name\"`\n\tHome    Address  `json:\"home\"`\n\tHobbies []string `json:\"hobbies\"`\n\tFriends []Friend `json:\"friends\"`\n}\n\ntype Human struct {\n\tAlive  bool      `json:\"alive,omitempty\"`\n\tAge    int       `json:\"age\"`\n\tWeight float64   `json:\"weight\"`\n\tDoB    time.Time `json:\"dob\"`\n}\n\ntype Friend struct {\n\tName    string `json:\"name\"`\n\tAddress string `json:\"address\"`\n}\n\ntype Address struct {\n\tStreet string `json:\"street\"`\n\tCity   string `json:\"city\"`\n\tTest   string `json:\",omitempty\"`\n}\n\nvar personSource = Person{\n\tHuman: Human{\n\t\tAge:    24,\n\t\tWeight: 70.1,\n\t\tAlive:  true,\n\t\tDoB:    time.Date(2019, 01, 01, 01, 01, 01, 0, time.UTC),\n\t},\n\tName: \"John Doe\",\n\tHome: Address{\n\t\tStreet: \"Jl. G1\",\n\t\tCity:   \"Jakarta\",\n\t},\n\tFriends: friendSource,\n\tHobbies: []string{\"eat\", \"sleep\", \"code\"},\n}\n\nvar friendSource = []Friend{\n\t{Name: \"Arief\", Address: \"palembang\"},\n\t{Name: \"Al\", Address: \"semarang\"},\n}\n\nfunc TestBindFields(t *testing.T) {\n\t// create person type based on Person struct\n\tpersonType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Person\",\n\t\t// pass empty Person struct to bind all of it's fields\n\t\tFields: graphql.BindFields(Person{}),\n\t})\n\tfields := graphql.Fields{\n\t\t\"person\": &graphql.Field{\n\t\t\tType: personType,\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\treturn personSource, nil\n\t\t\t},\n\t\t},\n\t}\n\trootQuery := graphql.ObjectConfig{Name: \"RootQuery\", Fields: fields}\n\tschemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}\n\tschema, err := graphql.NewSchema(schemaConfig)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create new schema, error: %v\", err)\n\t}\n\n\t// Query\n\tquery := `\n\t\t{\n\t\t\tperson{\n\t\t\t\tname,\n\t\t\t\tdob,\n\t\t\t\thome{street,city},\n\t\t\t\tfriends{name,address},\n\t\t\t\tage,\n\t\t\t\tweight,\n\t\t\t\talive,\n\t\t\t\thobbies\n\t\t\t}\n\t\t}\n\t`\n\tparams := graphql.Params{Schema: schema, RequestString: query}\n\tr := graphql.Do(params)\n\tif len(r.Errors) > 0 {\n\t\tlog.Fatalf(\"failed to execute graphql operation, errors: %+v\", r.Errors)\n\t}\n\n\trJSON, _ := json.Marshal(r)\n\tdata := struct {\n\t\tData struct {\n\t\t\tPerson Person `json:\"person\"`\n\t\t} `json:\"data\"`\n\t}{}\n\terr = json.Unmarshal(rJSON, &data)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to unmarshal. error: %v\", err)\n\t}\n\n\tnewPerson := data.Data.Person\n\tif !reflect.DeepEqual(newPerson, personSource) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(personSource, newPerson))\n\t}\n}\n\nfunc TestBindArg(t *testing.T) {\n\tvar friendObj = graphql.NewObject(graphql.ObjectConfig{\n\t\tName:   \"friend\",\n\t\tFields: graphql.BindFields(Friend{}),\n\t})\n\n\tfields := graphql.Fields{\n\t\t\"friend\": &graphql.Field{\n\t\t\tType: friendObj,\n\t\t\t//it can be added more than one since it's a slice\n\t\t\tArgs: graphql.BindArg(Friend{}, \"name\"),\n\t\t\tResolve: func(p graphql.ResolveParams) (interface{}, error) {\n\t\t\t\tif name, ok := p.Args[\"name\"].(string); ok {\n\t\t\t\t\tfor _, friend := range friendSource {\n\t\t\t\t\t\tif friend.Name == name {\n\t\t\t\t\t\t\treturn friend, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn nil, nil\n\t\t\t},\n\t\t},\n\t}\n\trootQuery := graphql.ObjectConfig{Name: \"RootQuery\", Fields: fields}\n\tschemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}\n\tschema, err := graphql.NewSchema(schemaConfig)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create new schema, error: %v\", err)\n\t}\n\n\t// Query\n\tquery := `\n\t\t{\n\t\t\tfriend(name:\"Arief\"){\n\t\t\t\taddress\n\t\t\t}\n\t\t}\n\t`\n\tparams := graphql.Params{Schema: schema, RequestString: query}\n\tr := graphql.Do(params)\n\tif len(r.Errors) > 0 {\n\t\tlog.Fatalf(\"failed to execute graphql operation, errors: %+v\", r.Errors)\n\t}\n\n\trJSON, _ := json.Marshal(r)\n\n\tdata := struct {\n\t\tData struct {\n\t\t\tFriend Friend `json:\"friend\"`\n\t\t} `json:\"data\"`\n\t}{}\n\terr = json.Unmarshal(rJSON, &data)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to unmarshal. error: %v\", err)\n\t}\n\n\texpectedAddress := \"palembang\"\n\tnewFriend := data.Data.Friend\n\tif newFriend.Address != expectedAddress {\n\t\tt.Fatalf(\"Unexpected result, expected address to be %s but got %s\", expectedAddress, newFriend.Address)\n\t}\n}\n"
  },
  {
    "path": "validation_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n)\n\nvar someScalarType = graphql.NewScalar(graphql.ScalarConfig{\n\tName: \"SomeScalar\",\n\tSerialize: func(value interface{}) interface{} {\n\t\treturn nil\n\t},\n\tParseValue: func(value interface{}) interface{} {\n\t\treturn nil\n\t},\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\treturn nil\n\t},\n})\nvar someObjectType = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"SomeObject\",\n\tFields: graphql.Fields{\n\t\t\"f\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t},\n})\nvar objectWithIsTypeOf = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"ObjectWithIsTypeOf\",\n\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\treturn true\n\t},\n\tFields: graphql.Fields{\n\t\t\"f\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t},\n})\nvar someUnionType = graphql.NewUnion(graphql.UnionConfig{\n\tName: \"SomeUnion\",\n\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\treturn nil\n\t},\n\tTypes: []*graphql.Object{\n\t\tsomeObjectType,\n\t},\n})\nvar someInterfaceType = graphql.NewInterface(graphql.InterfaceConfig{\n\tName: \"SomeInterface\",\n\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\treturn nil\n\t},\n\tFields: graphql.Fields{\n\t\t\"f\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t},\n\t},\n})\nvar someEnumType = graphql.NewEnum(graphql.EnumConfig{\n\tName: \"SomeEnum\",\n\tValues: graphql.EnumValueConfigMap{\n\t\t\"ONLY\": &graphql.EnumValueConfig{},\n\t},\n})\nvar someInputObject = graphql.NewInputObject(graphql.InputObjectConfig{\n\tName: \"SomeInputObject\",\n\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\"f\": &graphql.InputObjectFieldConfig{\n\t\t\tType:         graphql.String,\n\t\t\tDefaultValue: \"Hello\",\n\t\t},\n\t},\n})\n\nfunc withModifiers(ttypes []graphql.Type) []graphql.Type {\n\tres := ttypes\n\tfor _, ttype := range ttypes {\n\t\tres = append(res, graphql.NewList(ttype))\n\t}\n\tfor _, ttype := range ttypes {\n\t\tres = append(res, graphql.NewNonNull(ttype))\n\t}\n\tfor _, ttype := range ttypes {\n\t\tres = append(res, graphql.NewNonNull(graphql.NewList(ttype)))\n\t}\n\treturn res\n}\n\nvar outputTypes = withModifiers([]graphql.Type{\n\tgraphql.String,\n\tsomeScalarType,\n\tsomeEnumType,\n\tsomeObjectType,\n\tsomeUnionType,\n\tsomeInterfaceType,\n})\nvar inputTypes = withModifiers([]graphql.Type{\n\tgraphql.String,\n\tsomeScalarType,\n\tsomeEnumType,\n\tsomeInputObject,\n})\n\nfunc schemaWithFieldType(ttype graphql.Output) (graphql.Schema, error) {\n\treturn graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: ttype,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tTypes: []graphql.Type{ttype},\n\t})\n}\nfunc schemaWithInputObject(ttype graphql.Input) (graphql.Schema, error) {\n\treturn graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\t\"args\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: ttype,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n}\nfunc schemaWithObjectFieldOfType(fieldType graphql.Input) (graphql.Schema, error) {\n\n\tbadObjectType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"BadObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"badField\": &graphql.Field{\n\t\t\t\tType: fieldType,\n\t\t\t},\n\t\t},\n\t})\n\treturn graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: badObjectType,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n}\nfunc schemaWithObjectImplementingType(implementedType *graphql.Interface) (graphql.Schema, error) {\n\n\tbadObjectType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"BadObject\",\n\t\tInterfaces: []*graphql.Interface{implementedType},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\treturn graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: badObjectType,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t\tTypes: []graphql.Type{badObjectType},\n\t})\n}\nfunc schemaWithUnionOfType(ttype *graphql.Object) (graphql.Schema, error) {\n\n\tbadObjectType := graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"BadUnion\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tTypes: []*graphql.Object{ttype},\n\t})\n\treturn graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: badObjectType,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n}\nfunc schemaWithInterfaceFieldOfType(ttype graphql.Type) (graphql.Schema, error) {\n\n\tbadInterfaceType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"BadInterface\",\n\t\tFields: graphql.Fields{\n\t\t\t\"badField\": &graphql.Field{\n\t\t\t\tType: ttype,\n\t\t\t},\n\t\t},\n\t})\n\treturn graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: badInterfaceType,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n}\nfunc schemaWithArgOfType(ttype graphql.Type) (graphql.Schema, error) {\n\n\tbadObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"BadObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"badField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"badArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: ttype,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\treturn graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: badObject,\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n}\nfunc schemaWithInputFieldOfType(ttype graphql.Type) (graphql.Schema, error) {\n\n\tbadInputObject := graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"BadInputObject\",\n\t\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\t\"badField\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: ttype,\n\t\t\t},\n\t\t},\n\t})\n\treturn graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: graphql.NewObject(graphql.ObjectConfig{\n\t\t\tName: \"Query\",\n\t\t\tFields: graphql.Fields{\n\t\t\t\t\"f\": &graphql.Field{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\t\"badArg\": &graphql.ArgumentConfig{\n\t\t\t\t\t\t\tType: badInputObject,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t})\n}\n\nfunc TestTypeSystem_SchemaMustHaveObjectRootTypes_AcceptsASchemaWhoseQueryTypeIsAnObjectType(t *testing.T) {\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: someObjectType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_SchemaMustHaveObjectRootTypes_AcceptsASchemaWhoseQueryAndMutationTypesAreObjectType(t *testing.T) {\n\tmutationObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Mutation\",\n\t\tFields: graphql.Fields{\n\t\t\t\"edit\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery:    someObjectType,\n\t\tMutation: mutationObject,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_SchemaMustHaveObjectRootTypes_AcceptsASchemaWhoseQueryAndSubscriptionTypesAreObjectType(t *testing.T) {\n\tsubscriptionType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Subscription\",\n\t\tFields: graphql.Fields{\n\t\t\t\"subscribe\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery:    someObjectType,\n\t\tMutation: subscriptionType,\n\t})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_SchemaMustHaveObjectRootTypes_RejectsASchemaWithoutAQueryType(t *testing.T) {\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{})\n\texpectedError := \"Schema query must be Object Type but got: nil.\"\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_SchemaMustContainUniquelyNamedTypes_RejectsASchemaWhichRedefinesABuiltInType(t *testing.T) {\n\n\tfakeString := graphql.NewScalar(graphql.ScalarConfig{\n\t\tName: \"String\",\n\t\tSerialize: func(value interface{}) interface{} {\n\t\t\treturn nil\n\t\t},\n\t})\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"normal\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t\t\"fake\": &graphql.Field{\n\t\t\t\tType: fakeString,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\texpectedError := `Schema must contain unique named types but contains multiple types named \"String\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_SchemaMustContainUniquelyNamedTypes_RejectsASchemaWhichDefinesAnObjectTypeTwice(t *testing.T) {\n\n\ta := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SameName\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tb := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SameName\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"a\": &graphql.Field{\n\t\t\t\tType: a,\n\t\t\t},\n\t\t\t\"b\": &graphql.Field{\n\t\t\t\tType: b,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t})\n\texpectedError := `Schema must contain unique named types but contains multiple types named \"SameName\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_SchemaMustContainUniquelyNamedTypes_RejectsASchemaWhichHaveSameNamedObjectsImplementingAnInterface(t *testing.T) {\n\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tFirstBadObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"BadObject\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tanotherInterface,\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tSecondBadObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"BadObject\",\n\t\tInterfaces: []*graphql.Interface{\n\t\t\tanotherInterface,\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tqueryType := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"Query\",\n\t\tFields: graphql.Fields{\n\t\t\t\"iface\": &graphql.Field{\n\t\t\t\tType: anotherInterface,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := graphql.NewSchema(graphql.SchemaConfig{\n\t\tQuery: queryType,\n\t\tTypes: []graphql.Type{FirstBadObject, SecondBadObject},\n\t})\n\texpectedError := `Schema must contain unique named types but contains multiple types named \"BadObject\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectsMustHaveFields_AcceptsAnObjectTypeWithFieldsObject(t *testing.T) {\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustHaveFields_RejectsAnObjectTypeWithMissingFields(t *testing.T) {\n\tbadObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t})\n\t_, err := schemaWithFieldType(badObject)\n\texpectedError := `SomeObject fields must be an object with field names as keys or a function which return such an object.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustHaveFields_RejectsAnObjectTypeWithIncorrectlyNamedFields(t *testing.T) {\n\tbadObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"bad-name-with-dashes\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(badObject)\n\texpectedError := `Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"bad-name-with-dashes\" does not.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustHaveFields_RejectsAnObjectTypeWithEmptyFields(t *testing.T) {\n\tbadObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:   \"SomeObject\",\n\t\tFields: graphql.Fields{},\n\t})\n\t_, err := schemaWithFieldType(badObject)\n\texpectedError := `SomeObject fields must be an object with field names as keys or a function which return such an object.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_FieldsArgsMustBeProperlyNamed_AcceptsFieldArgsWithValidNames(t *testing.T) {\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"goodField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"goodArgs\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_FieldsArgsMustBeProperlyNamed_RejectsFieldArgWithInvalidNames(t *testing.T) {\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"badField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"bad-name-with-dashes\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}))\n\texpectedError := `Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but \"bad-name-with-dashes\" does not.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_FieldsArgsMustBeObjects_AcceptsAnObjectTypeWithFieldArgs(t *testing.T) {\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t\tFields: graphql.Fields{\n\t\t\t\"goodField\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"goodArgs\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectInterfacesMustBeArray_AcceptsAnObjectTypeWithArrayInterfaces(t *testing.T) {\n\tanotherInterfaceType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"SomeObject\",\n\t\tInterfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {\n\t\t\treturn []*graphql.Interface{anotherInterfaceType}\n\t\t}),\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectInterfacesMustBeArray_AcceptsAnObjectTypeWithInterfacesAsFunctionReturningAnArray(t *testing.T) {\n\tanotherInterfaceType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"SomeObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterfaceType},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTypeSystem_UnionTypesMustBeArray_AcceptsAUnionTypeWithArrayTypes(t *testing.T) {\n\t_, err := schemaWithFieldType(graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"SomeUnion\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tTypes: []*graphql.Object{\n\t\t\tsomeObjectType,\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_UnionTypesMustBeArray_RejectsAUnionTypeWithoutTypes(t *testing.T) {\n\t_, err := schemaWithFieldType(graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"SomeUnion\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t}))\n\texpectedError := \"Must provide Array of types for Union SomeUnion.\"\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_UnionTypesMustBeArray_RejectsAUnionTypeWithEmptyTypes(t *testing.T) {\n\t_, err := schemaWithFieldType(graphql.NewUnion(graphql.UnionConfig{\n\t\tName: \"SomeUnion\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tTypes: []*graphql.Object{},\n\t}))\n\texpectedError := \"Must provide Array of types for Union SomeUnion.\"\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_InputObjectsMustHaveFields_AcceptsAnInputObjectTypeWithFields(t *testing.T) {\n\t_, err := schemaWithInputObject(graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"SomeInputObject\",\n\t\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\t\"f\": &graphql.InputObjectFieldConfig{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTypeSystem_InputObjectsMustHaveFields_AcceptsAnInputObjectTypeWithAFieldFunction(t *testing.T) {\n\t_, err := schemaWithInputObject(graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"SomeInputObject\",\n\t\tFields: (graphql.InputObjectConfigFieldMapThunk)(func() graphql.InputObjectConfigFieldMap {\n\t\t\treturn graphql.InputObjectConfigFieldMap{\n\t\t\t\t\"f\": &graphql.InputObjectFieldConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t}\n\t\t}),\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTypeSystem_InputObjectsMustHaveFields_RejectsAnInputObjectTypeWithMissingFields(t *testing.T) {\n\t_, err := schemaWithInputObject(graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName: \"SomeInputObject\",\n\t}))\n\texpectedError := \"SomeInputObject fields must be an object with field names as keys or a function which return such an object.\"\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_InputObjectsMustHaveFields_RejectsAnInputObjectTypeWithEmptyFields(t *testing.T) {\n\t_, err := schemaWithInputObject(graphql.NewInputObject(graphql.InputObjectConfig{\n\t\tName:   \"SomeInputObject\",\n\t\tFields: graphql.InputObjectConfigFieldMap{},\n\t}))\n\texpectedError := \"SomeInputObject fields must be an object with field names as keys or a function which return such an object.\"\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectTypesMustBeAssertable_AcceptsAnObjectTypeWithAnIsTypeOfFunction(t *testing.T) {\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"AnotherObject\",\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTypeSystem_InterfaceTypesMustBeResolvable_AcceptsAnInterfaceTypeDefiningResolveType(t *testing.T) {\n\n\tanotherInterfaceType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"SomeObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterfaceType},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_InterfaceTypesMustBeResolvable_AcceptsAnInterfaceWithImplementingTypeDefiningIsTypeOf(t *testing.T) {\n\n\tanotherInterfaceType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"SomeObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterfaceType},\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTypeSystem_InterfaceTypesMustBeResolvable_AcceptsAnInterfaceTypeDefiningResolveTypeWithImplementingTypeDefiningIsTypeOf(t *testing.T) {\n\n\tanotherInterfaceType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"SomeObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterfaceType},\n\t\tIsTypeOf: func(p graphql.IsTypeOfParams) bool {\n\t\t\treturn true\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTypeSystem_UnionTypesMustBeResolvable_AcceptsAUnionTypeDefiningResolveType(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewUnion(graphql.UnionConfig{\n\t\tName:  \"SomeUnion\",\n\t\tTypes: []*graphql.Object{someObjectType},\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_UnionTypesMustBeResolvable_AcceptsAUnionOfObjectTypesDefiningIsTypeOf(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewUnion(graphql.UnionConfig{\n\t\tName:  \"SomeUnion\",\n\t\tTypes: []*graphql.Object{objectWithIsTypeOf},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_UnionTypesMustBeResolvable_AcceptsAUnionTypeDefiningResolveTypeOfObjectTypesDefiningIsTypeOf(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewUnion(graphql.UnionConfig{\n\t\tName:  \"SomeUnion\",\n\t\tTypes: []*graphql.Object{objectWithIsTypeOf},\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_UnionTypesMustBeResolvable_RejectsAUnionTypeNotDefiningResolveTypeOfObjectTypesNotDefiningIsTypeOf(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewUnion(graphql.UnionConfig{\n\t\tName:  \"SomeUnion\",\n\t\tTypes: []*graphql.Object{someObjectType},\n\t}))\n\texpectedError := `Union Type SomeUnion does not provide a \"resolveType\" function and ` +\n\t\t`possible Type SomeObject does not provide a \"isTypeOf\" function. ` +\n\t\t`There is no way to resolve this possible type during execution.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ScalarTypesMustBeSerializable_AcceptsAScalarTypeDefiningSerialize(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewScalar(graphql.ScalarConfig{\n\t\tName: \"SomeScalar\",\n\t\tSerialize: func(value interface{}) interface{} {\n\t\t\treturn nil\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_ScalarTypesMustBeSerializable_RejectsAScalarTypeNotDefiningSerialize(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewScalar(graphql.ScalarConfig{\n\t\tName: \"SomeScalar\",\n\t}))\n\texpectedError := `SomeScalar must provide \"serialize\" function. If this custom Scalar ` +\n\t\t`is also used as an input type, ensure \"parseValue\" and \"parseLiteral\" ` +\n\t\t`functions are also provided.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_ScalarTypesMustBeSerializable_AcceptsAScalarTypeDefiningParseValueAndParseLiteral(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewScalar(graphql.ScalarConfig{\n\t\tName: \"SomeScalar\",\n\t\tSerialize: func(value interface{}) interface{} {\n\t\t\treturn nil\n\t\t},\n\t\tParseValue: func(value interface{}) interface{} {\n\t\t\treturn nil\n\t\t},\n\t\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\t\treturn nil\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_ScalarTypesMustBeSerializable_RejectsAScalarTypeDefiningParseValueButNotParseLiteral(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewScalar(graphql.ScalarConfig{\n\t\tName: \"SomeScalar\",\n\t\tSerialize: func(value interface{}) interface{} {\n\t\t\treturn nil\n\t\t},\n\t\tParseValue: func(value interface{}) interface{} {\n\t\t\treturn nil\n\t\t},\n\t}))\n\texpectedError := `SomeScalar must provide both \"parseValue\" and \"parseLiteral\" functions.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_ScalarTypesMustBeSerializable_RejectsAScalarTypeDefiningParseLiteralButNotParseValue(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewScalar(graphql.ScalarConfig{\n\t\tName: \"SomeScalar\",\n\t\tSerialize: func(value interface{}) interface{} {\n\t\t\treturn nil\n\t\t},\n\t\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\t\treturn nil\n\t\t},\n\t}))\n\texpectedError := `SomeScalar must provide both \"parseValue\" and \"parseLiteral\" functions.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_EnumTypesMustBeWellDefined_AcceptsAWellDefinedEnumTypeWithEmptyValueDefinition(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewEnum(graphql.EnumConfig{\n\t\tName: \"SomeEnum\",\n\t\tValues: graphql.EnumValueConfigMap{\n\t\t\t\"FOO\": &graphql.EnumValueConfig{},\n\t\t\t\"BAR\": &graphql.EnumValueConfig{},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_EnumTypesMustBeWellDefined_AcceptsAWellDefinedEnumTypeWithInternalValueDefinition(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewEnum(graphql.EnumConfig{\n\t\tName: \"SomeEnum\",\n\t\tValues: graphql.EnumValueConfigMap{\n\t\t\t\"FOO\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 10,\n\t\t\t},\n\t\t\t\"BAR\": &graphql.EnumValueConfig{\n\t\t\t\tValue: 20,\n\t\t\t},\n\t\t},\n\t}))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\nfunc TestTypeSystem_EnumTypesMustBeWellDefined_RejectsAnEnumTypeWithoutValues(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewEnum(graphql.EnumConfig{\n\t\tName: \"SomeEnum\",\n\t}))\n\texpectedError := `SomeEnum values must be an object with value names as keys.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_EnumTypesMustBeWellDefined_RejectsAnEnumTypeWithEmptyValues(t *testing.T) {\n\n\t_, err := schemaWithFieldType(graphql.NewEnum(graphql.EnumConfig{\n\t\tName:   \"SomeEnum\",\n\t\tValues: graphql.EnumValueConfigMap{},\n\t}))\n\texpectedError := `SomeEnum values must be an object with value names as keys.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectFieldsMustHaveOutputTypes_AcceptAnOutputTypeAsAnObjectFieldType(t *testing.T) {\n\tfor _, ttype := range outputTypes {\n\t\t_, err := schemaWithObjectFieldOfType(ttype)\n\t\tif err != nil {\n\t\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, ttype)\n\t\t}\n\t}\n}\nfunc TestTypeSystem_ObjectFieldsMustHaveOutputTypes_RejectsAnEmptyObjectFieldType(t *testing.T) {\n\t_, err := schemaWithObjectFieldOfType(nil)\n\texpectedError := `BadObject.badField field type must be Output Type but got: <nil>.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectsCanOnlyImplementInterfaces_AcceptsAnObjectImplementingAnInterface(t *testing.T) {\n\tanotherInterfaceType := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"f\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectImplementingType(anotherInterfaceType)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v\"`, err)\n\t}\n}\nfunc TestTypeSystem_ObjectsCanOnlyImplementInterfaces_RejectsAnObjectImplementingANonInterfaceType(t *testing.T) {\n\t_, err := schemaWithObjectImplementingType(nil)\n\texpectedError := `BadObject may only implement Interface types, it cannot implement: <nil>.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_UnionsMustRepresentObjectTypes_AcceptsAUnionOfAnObjectType(t *testing.T) {\n\t_, err := schemaWithUnionOfType(someObjectType)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v\"`, err)\n\t}\n}\nfunc TestTypeSystem_UnionsMustRepresentObjectTypes_RejectsAUnionOfNonObjectTypes(t *testing.T) {\n\t_, err := schemaWithUnionOfType(nil)\n\texpectedError := `BadUnion may only contain Object types, it cannot contain: <nil>.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_InterfaceFieldsMustHaveOutputTypes_AcceptsAnOutputTypeAsAnInterfaceFieldType(t *testing.T) {\n\tfor _, ttype := range outputTypes {\n\t\t_, err := schemaWithInterfaceFieldOfType(ttype)\n\t\tif err != nil {\n\t\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, ttype)\n\t\t}\n\t}\n}\nfunc TestTypeSystem_InterfaceFieldsMustHaveOutputTypes_RejectsAnEmptyInterfaceFieldType(t *testing.T) {\n\t_, err := schemaWithInterfaceFieldOfType(nil)\n\texpectedError := `BadInterface.badField field type must be Output Type but got: <nil>.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_FieldArgumentsMustHaveInputTypes_AcceptsAnInputTypeAsFieldArgType(t *testing.T) {\n\tfor _, ttype := range inputTypes {\n\t\t_, err := schemaWithArgOfType(ttype)\n\t\tif err != nil {\n\t\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, ttype)\n\t\t}\n\t}\n}\nfunc TestTypeSystem_FieldArgumentsMustHaveInputTypes_RejectsAnEmptyFieldArgType(t *testing.T) {\n\t_, err := schemaWithArgOfType(nil)\n\texpectedError := `BadObject.badField(badArg:) argument type must be Input Type but got: <nil>.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_InputObjectFieldsMustHaveInputTypes_AcceptsAnInputTypeAsInputFieldType(t *testing.T) {\n\tfor _, ttype := range inputTypes {\n\t\t_, err := schemaWithInputFieldOfType(ttype)\n\t\tif err != nil {\n\t\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, ttype)\n\t\t}\n\t}\n}\nfunc TestTypeSystem_InputObjectFieldsMustHaveInputTypes_RejectsAnEmptyInputFieldType(t *testing.T) {\n\t_, err := schemaWithInputFieldOfType(nil)\n\texpectedError := `BadInputObject.badField field type must be Input Type but got: <nil>.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ListMustAcceptGraphQLTypes_AcceptsAnTypeAsItemTypeOfList(t *testing.T) {\n\ttestTypes := withModifiers([]graphql.Type{\n\t\tgraphql.String,\n\t\tsomeScalarType,\n\t\tsomeEnumType,\n\t\tsomeObjectType,\n\t\tsomeUnionType,\n\t\tsomeInterfaceType,\n\t})\n\tfor _, ttype := range testTypes {\n\t\tresult := graphql.NewList(ttype)\n\t\tif result.Error() != nil {\n\t\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, result.Error(), ttype)\n\t\t}\n\t}\n}\nfunc TestTypeSystem_ListMustAcceptGraphQLTypes_RejectsANilTypeAsItemTypeOfList(t *testing.T) {\n\tresult := graphql.NewList(nil)\n\texpectedError := `Can only create List of a Type but got: <nil>.`\n\tif result.Error() == nil || result.Error().Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, result.Error())\n\t}\n}\n\nfunc TestTypeSystem_NonNullMustAcceptGraphQLTypes_AcceptsAnTypeAsNullableTypeOfNonNull(t *testing.T) {\n\tnullableTypes := []graphql.Type{\n\t\tgraphql.String,\n\t\tsomeScalarType,\n\t\tsomeObjectType,\n\t\tsomeUnionType,\n\t\tsomeInterfaceType,\n\t\tsomeEnumType,\n\t\tsomeInputObject,\n\t\tgraphql.NewList(graphql.String),\n\t\tgraphql.NewList(graphql.NewNonNull(graphql.String)),\n\t}\n\tfor _, ttype := range nullableTypes {\n\t\tresult := graphql.NewNonNull(ttype)\n\t\tif result.Error() != nil {\n\t\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, result.Error(), ttype)\n\t\t}\n\t}\n}\nfunc TestTypeSystem_NonNullMustAcceptGraphQLTypes_RejectsNilAsNonNullableType(t *testing.T) {\n\tresult := graphql.NewNonNull(nil)\n\texpectedError := `Can only create NonNull of a Nullable Type but got: <nil>.`\n\tif result.Error() == nil || result.Error().Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, result.Error())\n\t}\n}\n\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWhichImplementsAnInterface(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, anotherObject)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWhichImplementsAnInterfaceAlongWithMoreFields(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"anotherfield\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, anotherObject)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWhichImpementsAnInterfaceFieldAlongWithAdditionalOptionalArguments(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t\t\"anotherInput\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, anotherObject)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectWhichImplementsAnInterfaceFieldAlongWithAdditionalRequiredArguments(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t\t\"anotherInput\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\texpectedError := `AnotherObject.field(anotherInput:) is of required type \"String!\" but is not also provided by the interface AnotherInterface.field.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectMissingAnInterfaceField(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"anotherfield\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\texpectedError := `\"AnotherInterface\" expects field \"field\" but \"AnotherObject\" does not provide it.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectWithAnIncorrectlyTypedInterfaceField(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: someScalarType,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\texpectedError := `AnotherInterface.field expects type \"String\" but AnotherObject.field provides type \"SomeScalar\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectWithADifferentlyTypeInterfaceField(t *testing.T) {\n\n\ttypeA := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"A\",\n\t\tFields: graphql.Fields{\n\t\t\t\"foo\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\ttypeB := graphql.NewObject(graphql.ObjectConfig{\n\t\tName: \"B\",\n\t\tFields: graphql.Fields{\n\t\t\t\"foo\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: typeA,\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: typeB,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\texpectedError := `AnotherInterface.field expects type \"A\" but AnotherObject.field provides type \"B\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWithASubtypedInterfaceField_Interface(t *testing.T) {\n\tvar anotherInterface *graphql.Interface\n\tanotherInterface = graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: (graphql.FieldsThunk)(func() graphql.Fields {\n\t\t\treturn graphql.Fields{\n\t\t\t\t\"field\": &graphql.Field{\n\t\t\t\t\tType: anotherInterface,\n\t\t\t\t},\n\t\t\t}\n\t\t}),\n\t})\n\tvar anotherObject *graphql.Object\n\tanotherObject = graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: (graphql.FieldsThunk)(func() graphql.Fields {\n\t\t\treturn graphql.Fields{\n\t\t\t\t\"field\": &graphql.Field{\n\t\t\t\t\tType: anotherObject,\n\t\t\t\t},\n\t\t\t}\n\t\t}),\n\t})\n\t_, err := schemaWithFieldType(anotherObject)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, anotherObject)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWithASubtypedInterfaceField_Union(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: someUnionType,\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: someObjectType,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(anotherObject)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, anotherObject)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectMissingAnInterfaceArgument(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\texpectedError := `AnotherInterface.field expects argument \"input\" but AnotherObject.field does not provide it.`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectWithAnIncorrectlyTypedInterfaceArgument(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: graphql.String,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\t\tType: someScalarType,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\texpectedError := `AnotherInterface.field(input:) expects type \"String\" but AnotherObject.field(input:) provides type \"SomeScalar\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWithAnEquivalentlyModifiedInterfaceField(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.NewList(graphql.String)),\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.NewList(graphql.String)),\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithObjectFieldOfType(anotherObject)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, anotherObject)\n\t}\n}\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectWithANonListInterfaceFieldListType(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(anotherObject)\n\texpectedError := `AnotherInterface.field expects type \"[String]\" but AnotherObject.field provides type \"String\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectWithAListInterfaceFieldNonListType(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.NewList(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(anotherObject)\n\texpectedError := `AnotherInterface.field expects type \"String\" but AnotherObject.field provides type \"[String]\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_AcceptsAnObjectWithSubsetNonNullInterfaceFieldType(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(anotherObject)\n\tif err != nil {\n\t\tt.Fatalf(`unexpected error: %v for type \"%v\"`, err, anotherObject)\n\t}\n}\n\nfunc TestTypeSystem_ObjectsMustAdhereToInterfaceTheyImplement_RejectsAnObjectWithASupersetNullableInterfaceFieldType(t *testing.T) {\n\tanotherInterface := graphql.NewInterface(graphql.InterfaceConfig{\n\t\tName: \"AnotherInterface\",\n\t\tResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {\n\t\t\treturn nil\n\t\t},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t},\n\t\t},\n\t})\n\tanotherObject := graphql.NewObject(graphql.ObjectConfig{\n\t\tName:       \"AnotherObject\",\n\t\tInterfaces: []*graphql.Interface{anotherInterface},\n\t\tFields: graphql.Fields{\n\t\t\t\"field\": &graphql.Field{\n\t\t\t\tType: graphql.String,\n\t\t\t},\n\t\t},\n\t})\n\t_, err := schemaWithFieldType(anotherObject)\n\texpectedError := `AnotherInterface.field expects type \"String!\" but AnotherObject.field provides type \"String\".`\n\tif err == nil || err.Error() != expectedError {\n\t\tt.Fatalf(\"Expected error: %v, got %v\", expectedError, err)\n\t}\n}\n"
  },
  {
    "path": "validator.go",
    "content": "package graphql\n\nimport (\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/kinds\"\n\t\"github.com/graphql-go/graphql/language/visitor\"\n)\n\ntype ValidationResult struct {\n\tIsValid bool\n\tErrors  []gqlerrors.FormattedError\n}\n\n/**\n * Implements the \"Validation\" section of the spec.\n *\n * Validation runs synchronously, returning an array of encountered errors, or\n * an empty array if no errors were encountered and the document is valid.\n *\n * A list of specific validation rules may be provided. If not provided, the\n * default list of rules defined by the GraphQL specification will be used.\n *\n * Each validation rules is a function which returns a visitor\n * (see the language/visitor API). Visitor methods are expected to return\n * GraphQLErrors, or Arrays of GraphQLErrors when invalid.\n */\n\nfunc ValidateDocument(schema *Schema, astDoc *ast.Document, rules []ValidationRuleFn) (vr ValidationResult) {\n\tif len(rules) == 0 {\n\t\trules = SpecifiedRules\n\t}\n\n\tif schema == nil {\n\t\tvr.Errors = append(vr.Errors, gqlerrors.NewFormattedError(\"Must provide schema\"))\n\t\treturn vr\n\t}\n\tif astDoc == nil {\n\t\tvr.Errors = append(vr.Errors, gqlerrors.NewFormattedError(\"Must provide document\"))\n\t\treturn vr\n\t}\n\n\ttypeInfo := NewTypeInfo(&TypeInfoConfig{\n\t\tSchema: schema,\n\t})\n\tvr.Errors = VisitUsingRules(schema, typeInfo, astDoc, rules)\n\tif len(vr.Errors) == 0 {\n\t\tvr.IsValid = true\n\t}\n\treturn vr\n}\n\n// VisitUsingRules This uses a specialized visitor which runs multiple visitors in parallel,\n// while maintaining the visitor skip and break API.\n//\n// @internal\n// Had to expose it to unit test experimental customizable validation feature,\n// but not meant for public consumption\nfunc VisitUsingRules(schema *Schema, typeInfo *TypeInfo, astDoc *ast.Document, rules []ValidationRuleFn) []gqlerrors.FormattedError {\n\n\tcontext := NewValidationContext(schema, astDoc, typeInfo)\n\tvisitors := []*visitor.VisitorOptions{}\n\n\tfor _, rule := range rules {\n\t\tinstance := rule(context)\n\t\tvisitors = append(visitors, instance.VisitorOpts)\n\t}\n\n\t// Visit the whole document with each instance of all provided rules.\n\tvisitor.Visit(astDoc, visitor.VisitWithTypeInfo(typeInfo, visitor.VisitInParallel(visitors...)), nil)\n\treturn context.Errors()\n}\n\ntype HasSelectionSet interface {\n\tGetKind() string\n\tGetLoc() *ast.Location\n\tGetSelectionSet() *ast.SelectionSet\n}\n\nvar _ HasSelectionSet = (*ast.OperationDefinition)(nil)\nvar _ HasSelectionSet = (*ast.FragmentDefinition)(nil)\n\ntype VariableUsage struct {\n\tNode *ast.Variable\n\tType Input\n}\n\ntype ValidationContext struct {\n\tschema                         *Schema\n\tastDoc                         *ast.Document\n\ttypeInfo                       *TypeInfo\n\terrors                         []gqlerrors.FormattedError\n\tfragments                      map[string]*ast.FragmentDefinition\n\tvariableUsages                 map[HasSelectionSet][]*VariableUsage\n\trecursiveVariableUsages        map[*ast.OperationDefinition][]*VariableUsage\n\trecursivelyReferencedFragments map[*ast.OperationDefinition][]*ast.FragmentDefinition\n\tfragmentSpreads                map[*ast.SelectionSet][]*ast.FragmentSpread\n}\n\nfunc NewValidationContext(schema *Schema, astDoc *ast.Document, typeInfo *TypeInfo) *ValidationContext {\n\treturn &ValidationContext{\n\t\tschema:                         schema,\n\t\tastDoc:                         astDoc,\n\t\ttypeInfo:                       typeInfo,\n\t\tfragments:                      map[string]*ast.FragmentDefinition{},\n\t\tvariableUsages:                 map[HasSelectionSet][]*VariableUsage{},\n\t\trecursiveVariableUsages:        map[*ast.OperationDefinition][]*VariableUsage{},\n\t\trecursivelyReferencedFragments: map[*ast.OperationDefinition][]*ast.FragmentDefinition{},\n\t\tfragmentSpreads:                map[*ast.SelectionSet][]*ast.FragmentSpread{},\n\t}\n}\n\nfunc (ctx *ValidationContext) ReportError(err error) {\n\tformattedErr := gqlerrors.FormatError(err)\n\tctx.errors = append(ctx.errors, formattedErr)\n}\nfunc (ctx *ValidationContext) Errors() []gqlerrors.FormattedError {\n\treturn ctx.errors\n}\n\nfunc (ctx *ValidationContext) Schema() *Schema {\n\treturn ctx.schema\n}\nfunc (ctx *ValidationContext) Document() *ast.Document {\n\treturn ctx.astDoc\n}\nfunc (ctx *ValidationContext) Fragment(name string) *ast.FragmentDefinition {\n\tif len(ctx.fragments) == 0 {\n\t\tif ctx.Document() == nil {\n\t\t\treturn nil\n\t\t}\n\t\tdefs := ctx.Document().Definitions\n\t\tfragments := map[string]*ast.FragmentDefinition{}\n\t\tfor _, def := range defs {\n\t\t\tif def, ok := def.(*ast.FragmentDefinition); ok {\n\t\t\t\tdefName := \"\"\n\t\t\t\tif def.Name != nil {\n\t\t\t\t\tdefName = def.Name.Value\n\t\t\t\t}\n\t\t\t\tfragments[defName] = def\n\t\t\t}\n\t\t}\n\t\tctx.fragments = fragments\n\t}\n\tf, _ := ctx.fragments[name]\n\treturn f\n}\nfunc (ctx *ValidationContext) FragmentSpreads(node *ast.SelectionSet) []*ast.FragmentSpread {\n\tif spreads, ok := ctx.fragmentSpreads[node]; ok && spreads != nil {\n\t\treturn spreads\n\t}\n\n\tspreads := []*ast.FragmentSpread{}\n\tsetsToVisit := []*ast.SelectionSet{node}\n\n\tfor {\n\t\tif len(setsToVisit) == 0 {\n\t\t\tbreak\n\t\t}\n\t\tvar set *ast.SelectionSet\n\t\t// pop\n\t\tset, setsToVisit = setsToVisit[len(setsToVisit)-1], setsToVisit[:len(setsToVisit)-1]\n\t\tif set.Selections != nil {\n\t\t\tfor _, selection := range set.Selections {\n\t\t\t\tswitch selection := selection.(type) {\n\t\t\t\tcase *ast.FragmentSpread:\n\t\t\t\t\tspreads = append(spreads, selection)\n\t\t\t\tcase *ast.Field:\n\t\t\t\t\tif selection.SelectionSet != nil {\n\t\t\t\t\t\tsetsToVisit = append(setsToVisit, selection.SelectionSet)\n\t\t\t\t\t}\n\t\t\t\tcase *ast.InlineFragment:\n\t\t\t\t\tif selection.SelectionSet != nil {\n\t\t\t\t\t\tsetsToVisit = append(setsToVisit, selection.SelectionSet)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tctx.fragmentSpreads[node] = spreads\n\t}\n\treturn spreads\n}\n\nfunc (ctx *ValidationContext) RecursivelyReferencedFragments(operation *ast.OperationDefinition) []*ast.FragmentDefinition {\n\tif fragments, ok := ctx.recursivelyReferencedFragments[operation]; ok && fragments != nil {\n\t\treturn fragments\n\t}\n\n\tfragments := []*ast.FragmentDefinition{}\n\tcollectedNames := map[string]bool{}\n\tnodesToVisit := []*ast.SelectionSet{operation.SelectionSet}\n\n\tfor {\n\t\tif len(nodesToVisit) == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tvar node *ast.SelectionSet\n\n\t\tnode, nodesToVisit = nodesToVisit[len(nodesToVisit)-1], nodesToVisit[:len(nodesToVisit)-1]\n\t\tspreads := ctx.FragmentSpreads(node)\n\t\tfor _, spread := range spreads {\n\t\t\tfragName := \"\"\n\t\t\tif spread.Name != nil {\n\t\t\t\tfragName = spread.Name.Value\n\t\t\t}\n\t\t\tif res, ok := collectedNames[fragName]; !ok || !res {\n\t\t\t\tcollectedNames[fragName] = true\n\t\t\t\tfragment := ctx.Fragment(fragName)\n\t\t\t\tif fragment != nil {\n\t\t\t\t\tfragments = append(fragments, fragment)\n\t\t\t\t\tnodesToVisit = append(nodesToVisit, fragment.SelectionSet)\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\tctx.recursivelyReferencedFragments[operation] = fragments\n\treturn fragments\n}\nfunc (ctx *ValidationContext) VariableUsages(node HasSelectionSet) []*VariableUsage {\n\tif usages, ok := ctx.variableUsages[node]; ok && usages != nil {\n\t\treturn usages\n\t}\n\tusages := []*VariableUsage{}\n\ttypeInfo := NewTypeInfo(&TypeInfoConfig{\n\t\tSchema: ctx.schema,\n\t})\n\n\tvisitor.Visit(node, visitor.VisitWithTypeInfo(typeInfo, &visitor.VisitorOptions{\n\t\tKindFuncMap: map[string]visitor.NamedVisitFuncs{\n\t\t\tkinds.VariableDefinition: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\treturn visitor.ActionSkip, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\tkinds.Variable: {\n\t\t\t\tKind: func(p visitor.VisitFuncParams) (string, interface{}) {\n\t\t\t\t\tif node, ok := p.Node.(*ast.Variable); ok && node != nil {\n\t\t\t\t\t\tusages = append(usages, &VariableUsage{\n\t\t\t\t\t\t\tNode: node,\n\t\t\t\t\t\t\tType: typeInfo.InputType(),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\treturn visitor.ActionNoChange, nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}), nil)\n\n\tctx.variableUsages[node] = usages\n\treturn usages\n}\nfunc (ctx *ValidationContext) RecursiveVariableUsages(operation *ast.OperationDefinition) []*VariableUsage {\n\tif usages, ok := ctx.recursiveVariableUsages[operation]; ok && usages != nil {\n\t\treturn usages\n\t}\n\tusages := ctx.VariableUsages(operation)\n\n\tfragments := ctx.RecursivelyReferencedFragments(operation)\n\tfor _, fragment := range fragments {\n\t\tfragmentUsages := ctx.VariableUsages(fragment)\n\t\tusages = append(usages, fragmentUsages...)\n\t}\n\n\tctx.recursiveVariableUsages[operation] = usages\n\treturn usages\n}\nfunc (ctx *ValidationContext) Type() Output {\n\treturn ctx.typeInfo.Type()\n}\nfunc (ctx *ValidationContext) ParentType() Composite {\n\treturn ctx.typeInfo.ParentType()\n}\nfunc (ctx *ValidationContext) InputType() Input {\n\treturn ctx.typeInfo.InputType()\n}\nfunc (ctx *ValidationContext) FieldDef() *FieldDefinition {\n\treturn ctx.typeInfo.FieldDef()\n}\nfunc (ctx *ValidationContext) Directive() *Directive {\n\treturn ctx.typeInfo.Directive()\n}\nfunc (ctx *ValidationContext) Argument() *Argument {\n\treturn ctx.typeInfo.Argument()\n}\n"
  },
  {
    "path": "validator_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/language/parser\"\n\t\"github.com/graphql-go/graphql/language/source\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nfunc expectValid(t *testing.T, schema *graphql.Schema, queryString string) {\n\tsource := source.NewSource(&source.Source{\n\t\tBody: []byte(queryString),\n\t\tName: \"GraphQL request\",\n\t})\n\tAST, err := parser.Parse(parser.ParseParams{Source: source})\n\tif err != nil {\n\t\tt.Fatalf(\"Unexpected error: %v\", err)\n\t}\n\tvalidationResult := graphql.ValidateDocument(schema, AST, nil)\n\n\tif !validationResult.IsValid || len(validationResult.Errors) > 0 {\n\t\tt.Fatalf(\"Unexpected error: %v\", validationResult.Errors)\n\t}\n\n}\n\nfunc TestValidator_SupportsFullValidation_ValidatesQueries(t *testing.T) {\n\n\texpectValid(t, testutil.TestSchema, `\n      query {\n        catOrDog {\n          ... on Cat {\n            furColor\n          }\n          ... on Dog {\n            isHousetrained\n          }\n        }\n      }\n    `)\n}\n\n// NOTE: experimental\nfunc TestValidator_SupportsFullValidation_ValidatesUsingACustomTypeInfo(t *testing.T) {\n\n\t// This TypeInfo will never return a valid field.\n\ttypeInfo := graphql.NewTypeInfo(&graphql.TypeInfoConfig{\n\t\tSchema: testutil.TestSchema,\n\t\tFieldDefFn: func(schema *graphql.Schema, parentType graphql.Type, fieldAST *ast.Field) *graphql.FieldDefinition {\n\t\t\treturn nil\n\t\t},\n\t})\n\n\tast := testutil.TestParse(t, `\n\t  query {\n        catOrDog {\n          ... on Cat {\n            furColor\n          }\n          ... on Dog {\n            isHousetrained\n          }\n        }\n      }\n\t`)\n\n\terrors := graphql.VisitUsingRules(testutil.TestSchema, typeInfo, ast, graphql.SpecifiedRules)\n\n\texpectedErrors := []gqlerrors.FormattedError{\n\t\t{\n\t\t\tMessage: `Cannot query field \"catOrDog\" on type \"QueryRoot\". Did you mean \"catOrDog\"?`,\n\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t{Line: 3, Column: 9},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tMessage: `Cannot query field \"furColor\" on type \"Cat\". Did you mean \"furColor\"?`,\n\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t{Line: 5, Column: 13},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tMessage: `Cannot query field \"isHousetrained\" on type \"Dog\". Did you mean \"isHousetrained\"?`,\n\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t{Line: 8, Column: 13},\n\t\t\t},\n\t\t},\n\t}\n\tif !testutil.EqualFormattedErrors(expectedErrors, errors) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expectedErrors, errors))\n\t}\n}\n"
  },
  {
    "path": "values.go",
    "content": "package graphql\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/kinds\"\n\t\"github.com/graphql-go/graphql/language/printer\"\n)\n\n// Prepares an object map of variableValues of the correct type based on the\n// provided variable definitions and arbitrary input. If the input cannot be\n// parsed to match the variable definitions, a GraphQLError will be returned.\nfunc getVariableValues(\n\tschema Schema,\n\tdefinitionASTs []*ast.VariableDefinition,\n\tinputs map[string]interface{}) (map[string]interface{}, error) {\n\tvalues := map[string]interface{}{}\n\tfor _, defAST := range definitionASTs {\n\t\tif defAST == nil || defAST.Variable == nil || defAST.Variable.Name == nil {\n\t\t\tcontinue\n\t\t}\n\t\tvarName := defAST.Variable.Name.Value\n\t\tif varValue, err := getVariableValue(schema, defAST, inputs[varName]); err != nil {\n\t\t\treturn values, err\n\t\t} else {\n\t\t\tvalues[varName] = varValue\n\t\t}\n\t}\n\treturn values, nil\n}\n\n// Prepares an object map of argument values given a list of argument\n// definitions and list of argument AST nodes.\nfunc getArgumentValues(\n\targDefs []*Argument, argASTs []*ast.Argument,\n\tvariableValues map[string]interface{}) map[string]interface{} {\n\n\targASTMap := map[string]*ast.Argument{}\n\tfor _, argAST := range argASTs {\n\t\tif argAST.Name != nil {\n\t\t\targASTMap[argAST.Name.Value] = argAST\n\t\t}\n\t}\n\tresults := map[string]interface{}{}\n\tfor _, argDef := range argDefs {\n\t\tvar (\n\t\t\ttmp   interface{}\n\t\t\tvalue ast.Value\n\t\t)\n\t\tif tmpValue, ok := argASTMap[argDef.PrivateName]; ok {\n\t\t\tvalue = tmpValue.Value\n\t\t}\n\t\tif tmp = valueFromAST(value, argDef.Type, variableValues); isNullish(tmp) {\n\t\t\ttmp = argDef.DefaultValue\n\t\t}\n\t\tif !isNullish(tmp) {\n\t\t\tresults[argDef.PrivateName] = tmp\n\t\t}\n\t}\n\treturn results\n}\n\n// Given a variable definition, and any value of input, return a value which\n// adheres to the variable definition, or throw an error.\nfunc getVariableValue(schema Schema, definitionAST *ast.VariableDefinition, input interface{}) (interface{}, error) {\n\tttype, err := typeFromAST(schema, definitionAST.Type)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvariable := definitionAST.Variable\n\n\tif ttype == nil || !IsInputType(ttype) {\n\t\treturn \"\", gqlerrors.NewError(\n\t\t\tfmt.Sprintf(`Variable \"$%v\" expected value of type `+\n\t\t\t\t`\"%v\" which cannot be used as an input type.`, variable.Name.Value, printer.Print(definitionAST.Type)),\n\t\t\t[]ast.Node{definitionAST},\n\t\t\t\"\",\n\t\t\tnil,\n\t\t\t[]int{},\n\t\t\tnil,\n\t\t)\n\t}\n\n\tisValid, messages := isValidInputValue(input, ttype)\n\tif isValid {\n\t\tif isNullish(input) {\n\t\t\tif definitionAST.DefaultValue != nil {\n\t\t\t\treturn valueFromAST(definitionAST.DefaultValue, ttype, nil), nil\n\t\t\t}\n\t\t}\n\t\treturn coerceValue(ttype, input), nil\n\t}\n\tif isNullish(input) {\n\t\treturn \"\", gqlerrors.NewError(\n\t\t\tfmt.Sprintf(`Variable \"$%v\" of required type `+\n\t\t\t\t`\"%v\" was not provided.`, variable.Name.Value, printer.Print(definitionAST.Type)),\n\t\t\t[]ast.Node{definitionAST},\n\t\t\t\"\",\n\t\t\tnil,\n\t\t\t[]int{},\n\t\t\tnil,\n\t\t)\n\t}\n\t// convert input interface into string for error message\n\tbts, _ := json.Marshal(input)\n\tvar (\n\t\tinputStr = string(bts)\n\t\tmsg      string\n\t)\n\tif len(messages) > 0 {\n\t\tmsg = \"\\n\" + strings.Join(messages, \"\\n\")\n\t}\n\n\treturn \"\", gqlerrors.NewError(\n\t\tfmt.Sprintf(`Variable \"$%v\" got invalid value `+\n\t\t\t`%v.%v`, variable.Name.Value, inputStr, msg),\n\t\t[]ast.Node{definitionAST},\n\t\t\"\",\n\t\tnil,\n\t\t[]int{},\n\t\tnil,\n\t)\n}\n\n// Given a type and any value, return a runtime value coerced to match the type.\nfunc coerceValue(ttype Input, value interface{}) interface{} {\n\tif isNullish(value) {\n\t\treturn nil\n\t}\n\tswitch ttype := ttype.(type) {\n\tcase *NonNull:\n\t\treturn coerceValue(ttype.OfType, value)\n\tcase *List:\n\t\tvar values = []interface{}{}\n\t\tvalType := reflect.ValueOf(value)\n\t\tif valType.Kind() == reflect.Slice {\n\t\t\tfor i := 0; i < valType.Len(); i++ {\n\t\t\t\tval := valType.Index(i).Interface()\n\t\t\t\tvalues = append(values, coerceValue(ttype.OfType, val))\n\t\t\t}\n\t\t\treturn values\n\t\t}\n\t\treturn append(values, coerceValue(ttype.OfType, value))\n\tcase *InputObject:\n\t\tvar obj = map[string]interface{}{}\n\t\tvalueMap, _ := value.(map[string]interface{})\n\t\tif valueMap == nil {\n\t\t\tvalueMap = map[string]interface{}{}\n\t\t}\n\n\t\tfor name, field := range ttype.Fields() {\n\t\t\tfieldValue := coerceValue(field.Type, valueMap[name])\n\t\t\tif isNullish(fieldValue) {\n\t\t\t\tfieldValue = field.DefaultValue\n\t\t\t}\n\t\t\tif !isNullish(fieldValue) {\n\t\t\t\tobj[name] = fieldValue\n\t\t\t}\n\t\t}\n\t\treturn obj\n\tcase *Scalar:\n\t\tif parsed := ttype.ParseValue(value); !isNullish(parsed) {\n\t\t\treturn parsed\n\t\t}\n\tcase *Enum:\n\t\tif parsed := ttype.ParseValue(value); !isNullish(parsed) {\n\t\t\treturn parsed\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// graphql-js/src/utilities.js`\n// TODO: figure out where to organize utils\n// TODO: change to *Schema\nfunc typeFromAST(schema Schema, inputTypeAST ast.Type) (Type, error) {\n\tswitch inputTypeAST := inputTypeAST.(type) {\n\tcase *ast.List:\n\t\tinnerType, err := typeFromAST(schema, inputTypeAST.Type)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn NewList(innerType), nil\n\tcase *ast.NonNull:\n\t\tinnerType, err := typeFromAST(schema, inputTypeAST.Type)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn NewNonNull(innerType), nil\n\tcase *ast.Named:\n\t\tnameValue := \"\"\n\t\tif inputTypeAST.Name != nil {\n\t\t\tnameValue = inputTypeAST.Name.Value\n\t\t}\n\t\tttype := schema.Type(nameValue)\n\t\treturn ttype, nil\n\tdefault:\n\t\treturn nil, invariant(inputTypeAST.GetKind() == kinds.Named, \"Must be a named type.\")\n\t}\n}\n\n// isValidInputValue alias isValidJSValue\n// Given a value and a GraphQL type, determine if the value will be\n// accepted for that type. This is primarily useful for validating the\n// runtime values of query variables.\nfunc isValidInputValue(value interface{}, ttype Input) (bool, []string) {\n\tif isNullish(value) {\n\t\tif ttype, ok := ttype.(*NonNull); ok {\n\t\t\tif ttype.OfType.Name() != \"\" {\n\t\t\t\treturn false, []string{fmt.Sprintf(`Expected \"%v!\", found null.`, ttype.OfType.Name())}\n\t\t\t}\n\t\t\treturn false, []string{\"Expected non-null value, found null.\"}\n\t\t}\n\t\treturn true, nil\n\t}\n\tswitch ttype := ttype.(type) {\n\tcase *NonNull:\n\t\treturn isValidInputValue(value, ttype.OfType)\n\tcase *List:\n\t\tvalType := reflect.ValueOf(value)\n\t\tif valType.Kind() == reflect.Ptr {\n\t\t\tvalType = valType.Elem()\n\t\t}\n\t\tif valType.Kind() == reflect.Slice {\n\t\t\tmessagesReduce := []string{}\n\t\t\tfor i := 0; i < valType.Len(); i++ {\n\t\t\t\tval := valType.Index(i).Interface()\n\t\t\t\t_, messages := isValidInputValue(val, ttype.OfType)\n\t\t\t\tfor idx, message := range messages {\n\t\t\t\t\tmessagesReduce = append(messagesReduce, fmt.Sprintf(`In element #%v: %v`, idx+1, message))\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (len(messagesReduce) == 0), messagesReduce\n\t\t}\n\t\treturn isValidInputValue(value, ttype.OfType)\n\n\tcase *InputObject:\n\t\tmessagesReduce := []string{}\n\n\t\tvalueMap, ok := value.(map[string]interface{})\n\t\tif !ok {\n\t\t\treturn false, []string{fmt.Sprintf(`Expected \"%v\", found not an object.`, ttype.Name())}\n\t\t}\n\t\tfields := ttype.Fields()\n\n\t\t// to ensure stable order of field evaluation\n\t\tfieldNames := []string{}\n\t\tvalueMapFieldNames := []string{}\n\n\t\tfor fieldName := range fields {\n\t\t\tfieldNames = append(fieldNames, fieldName)\n\t\t}\n\t\tsort.Strings(fieldNames)\n\n\t\tfor fieldName := range valueMap {\n\t\t\tvalueMapFieldNames = append(valueMapFieldNames, fieldName)\n\t\t}\n\t\tsort.Strings(valueMapFieldNames)\n\n\t\t// Ensure every provided field is defined.\n\t\tfor _, fieldName := range valueMapFieldNames {\n\t\t\tif _, ok := fields[fieldName]; !ok {\n\t\t\t\tmessagesReduce = append(messagesReduce, fmt.Sprintf(`In field \"%v\": Unknown field.`, fieldName))\n\t\t\t}\n\t\t}\n\n\t\t// Ensure every defined field is valid.\n\t\tfor _, fieldName := range fieldNames {\n\t\t\t_, messages := isValidInputValue(valueMap[fieldName], fields[fieldName].Type)\n\t\t\tif messages != nil {\n\t\t\t\tfor _, message := range messages {\n\t\t\t\t\tmessagesReduce = append(messagesReduce, fmt.Sprintf(`In field \"%v\": %v`, fieldName, message))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn (len(messagesReduce) == 0), messagesReduce\n\tcase *Scalar:\n\t\tif parsedVal := ttype.ParseValue(value); isNullish(parsedVal) {\n\t\t\treturn false, []string{fmt.Sprintf(`Expected type \"%v\", found \"%v\".`, ttype.Name(), value)}\n\t\t}\n\tcase *Enum:\n\t\tif parsedVal := ttype.ParseValue(value); isNullish(parsedVal) {\n\t\t\treturn false, []string{fmt.Sprintf(`Expected type \"%v\", found \"%v\".`, ttype.Name(), value)}\n\t\t}\n\t}\n\n\treturn true, nil\n}\n\n// Returns true if a value is null, undefined, or NaN.\nfunc isNullish(src interface{}) bool {\n\tif src == nil {\n\t\treturn true\n\t}\n\tvalue := reflect.ValueOf(src)\n\tif value.Kind() == reflect.Ptr {\n\t\tif value.IsNil() {\n\t\t\treturn true\n\t\t}\n\t\tvalue = value.Elem()\n\t}\n\tswitch value.Kind() {\n\tcase reflect.String:\n\t\t// if src is ptr type and len(string)=0, it returns false\n\t\tif !value.IsValid() {\n\t\t\treturn true\n\t\t}\n\tcase reflect.Int:\n\t\treturn math.IsNaN(float64(value.Int()))\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn math.IsNaN(float64(value.Float()))\n\t}\n\treturn false\n}\n\n// Returns true if src is a slice or an array\nfunc isIterable(src interface{}) bool {\n\tif src == nil {\n\t\treturn false\n\t}\n\tt := reflect.TypeOf(src)\n\tif t.Kind() == reflect.Ptr {\n\t\tt = t.Elem()\n\t}\n\treturn t.Kind() == reflect.Slice || t.Kind() == reflect.Array\n}\n\n/**\n * Produces a value given a GraphQL Value AST.\n *\n * A GraphQL type must be provided, which will be used to interpret different\n * GraphQL Value literals.\n *\n * | GraphQL Value        | JSON Value    |\n * | -------------------- | ------------- |\n * | Input Object         | Object        |\n * | List                 | Array         |\n * | Boolean              | Boolean       |\n * | String / Enum Value  | String        |\n * | Int / Float          | Number        |\n *\n */\nfunc valueFromAST(valueAST ast.Value, ttype Input, variables map[string]interface{}) interface{} {\n\tif valueAST == nil {\n\t\treturn nil\n\t}\n\t// precedence: value > type\n\tif valueAST, ok := valueAST.(*ast.Variable); ok {\n\t\tif valueAST.Name == nil || variables == nil {\n\t\t\treturn nil\n\t\t}\n\t\t// Note: we're not doing any checking that this variable is correct. We're\n\t\t// assuming that this query has been validated and the variable usage here\n\t\t// is of the correct type.\n\t\treturn variables[valueAST.Name.Value]\n\t}\n\tswitch ttype := ttype.(type) {\n\tcase *NonNull:\n\t\treturn valueFromAST(valueAST, ttype.OfType, variables)\n\tcase *List:\n\t\tvalues := []interface{}{}\n\t\tif valueAST, ok := valueAST.(*ast.ListValue); ok {\n\t\t\tfor _, itemAST := range valueAST.Values {\n\t\t\t\tvalues = append(values, valueFromAST(itemAST, ttype.OfType, variables))\n\t\t\t}\n\t\t\treturn values\n\t\t}\n\t\treturn append(values, valueFromAST(valueAST, ttype.OfType, variables))\n\tcase *InputObject:\n\t\tvar (\n\t\t\tok bool\n\t\t\tov *ast.ObjectValue\n\t\t\tof *ast.ObjectField\n\t\t)\n\t\tif ov, ok = valueAST.(*ast.ObjectValue); !ok {\n\t\t\treturn nil\n\t\t}\n\t\tfieldASTs := map[string]*ast.ObjectField{}\n\t\tfor _, of = range ov.Fields {\n\t\t\tif of == nil || of.Name == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfieldASTs[of.Name.Value] = of\n\t\t}\n\t\tobj := map[string]interface{}{}\n\t\tfor name, field := range ttype.Fields() {\n\t\t\tvar value interface{}\n\t\t\tif of, ok = fieldASTs[name]; ok {\n\t\t\t\tvalue = valueFromAST(of.Value, field.Type, variables)\n\t\t\t} else {\n\t\t\t\tvalue = field.DefaultValue\n\t\t\t}\n\t\t\tif !isNullish(value) {\n\t\t\t\tobj[name] = value\n\t\t\t}\n\t\t}\n\t\treturn obj\n\tcase *Scalar:\n\t\treturn ttype.ParseLiteral(valueAST)\n\tcase *Enum:\n\t\treturn ttype.ParseLiteral(valueAST)\n\t}\n\n\treturn nil\n}\n\nfunc invariant(condition bool, message string) error {\n\tif !condition {\n\t\treturn gqlerrors.NewFormattedError(message)\n\t}\n\treturn nil\n}\n\nfunc invariantf(condition bool, format string, a ...interface{}) error {\n\tif !condition {\n\t\treturn gqlerrors.NewFormattedError(fmt.Sprintf(format, a...))\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "values_test.go",
    "content": "package graphql\n\nimport \"testing\"\n\nfunc TestIsIterable(t *testing.T) {\n\tif !isIterable([]int{}) {\n\t\tt.Fatal(\"expected isIterable to return true for a slice, got false\")\n\t}\n\tif !isIterable([]int{}) {\n\t\tt.Fatal(\"expected isIterable to return true for an array, got false\")\n\t}\n\tif isIterable(1) {\n\t\tt.Fatal(\"expected isIterable to return false for an int, got true\")\n\t}\n\tif isIterable(nil) {\n\t\tt.Fatal(\"expected isIterable to return false for nil, got true\")\n\t}\n}\n"
  },
  {
    "path": "variables_test.go",
    "content": "package graphql_test\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/graphql-go/graphql\"\n\t\"github.com/graphql-go/graphql/gqlerrors\"\n\t\"github.com/graphql-go/graphql/language/ast\"\n\t\"github.com/graphql-go/graphql/language/location\"\n\t\"github.com/graphql-go/graphql/testutil\"\n)\n\nvar testComplexScalar *graphql.Scalar = graphql.NewScalar(graphql.ScalarConfig{\n\tName: \"ComplexScalar\",\n\tSerialize: func(value interface{}) interface{} {\n\t\tif value == \"DeserializedValue\" {\n\t\t\treturn \"SerializedValue\"\n\t\t}\n\t\treturn nil\n\t},\n\tParseValue: func(value interface{}) interface{} {\n\t\tif value == \"SerializedValue\" {\n\t\t\treturn \"DeserializedValue\"\n\t\t}\n\t\treturn nil\n\t},\n\tParseLiteral: func(valueAST ast.Value) interface{} {\n\t\tastValue := valueAST.GetValue()\n\t\tif astValue, ok := astValue.(string); ok && astValue == \"SerializedValue\" {\n\t\t\treturn \"DeserializedValue\"\n\t\t}\n\t\treturn nil\n\t},\n})\n\nvar testInputObject *graphql.InputObject = graphql.NewInputObject(graphql.InputObjectConfig{\n\tName: \"TestInputObject\",\n\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\"a\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.String,\n\t\t},\n\t\t\"b\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.NewList(graphql.String),\n\t\t},\n\t\t\"c\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t},\n\t\t\"d\": &graphql.InputObjectFieldConfig{\n\t\t\tType: testComplexScalar,\n\t\t},\n\t},\n})\n\nvar testNestedInputObject *graphql.InputObject = graphql.NewInputObject(graphql.InputObjectConfig{\n\tName: \"TestNestedInputObject\",\n\tFields: graphql.InputObjectConfigFieldMap{\n\t\t\"na\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.NewNonNull(testInputObject),\n\t\t},\n\t\t\"nb\": &graphql.InputObjectFieldConfig{\n\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t},\n\t},\n})\n\nfunc inputResolved(p graphql.ResolveParams) (interface{}, error) {\n\tinput, ok := p.Args[\"input\"]\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\tb, err := json.Marshal(input)\n\tif err != nil {\n\t\treturn nil, nil\n\t}\n\treturn string(b), nil\n}\n\nvar testType *graphql.Object = graphql.NewObject(graphql.ObjectConfig{\n\tName: \"TestType\",\n\tFields: graphql.Fields{\n\t\t\"fieldWithObjectInput\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: testInputObject,\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t\t\"fieldWithNullableStringInput\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.String,\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t\t\"fieldWithNonNullableStringInput\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.String),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t\t\"fieldWithDefaultArgumentValue\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType:         graphql.String,\n\t\t\t\t\tDefaultValue: \"Hello World\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t\t\"fieldWithNestedInputObject\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType:         testNestedInputObject,\n\t\t\t\t\tDefaultValue: \"Hello World\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t\t\"list\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewList(graphql.String),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t\t\"nnList\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.NewList(graphql.String)),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t\t\"listNN\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewList(graphql.NewNonNull(graphql.String)),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t\t\"nnListNN\": &graphql.Field{\n\t\t\tType: graphql.String,\n\t\t\tArgs: graphql.FieldConfigArgument{\n\t\t\t\t\"input\": &graphql.ArgumentConfig{\n\t\t\t\t\tType: graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.String))),\n\t\t\t\t},\n\t\t\t},\n\t\t\tResolve: inputResolved,\n\t\t},\n\t},\n})\n\nvar variablesTestSchema, _ = graphql.NewSchema(graphql.SchemaConfig{\n\tQuery: testType,\n})\n\nfunc TestVariables_ObjectsAndNullability_UsingInlineStructs_ExecutesWithComplexInput(t *testing.T) {\n\tdoc := `\n        {\n          fieldWithObjectInput(input: {a: \"foo\", b: [\"bar\"], c: \"baz\"})\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithObjectInput\": `{\"a\":\"foo\",\"b\":[\"bar\"],\"c\":\"baz\"}`,\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingInlineStructs_ProperlyParsesSingleValueToList(t *testing.T) {\n\tdoc := `\n        {\n          fieldWithObjectInput(input: {a: \"foo\", b: \"bar\", c: \"baz\"})\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithObjectInput\": `{\"a\":\"foo\",\"b\":[\"bar\"],\"c\":\"baz\"}`,\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingInlineStructs_DoesNotUseIncorrectValue(t *testing.T) {\n\tdoc := `\n        {\n          fieldWithObjectInput(input: [\"foo\", \"bar\", \"baz\"])\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithObjectInput\": nil,\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingInlineStructs_ProperlyRunsParseLiteralOnComplexScalarTypes(t *testing.T) {\n\tdoc := `\n        {\n          fieldWithObjectInput(input: {a: \"foo\", d: \"SerializedValue\"})\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithObjectInput\": `{\"a\":\"foo\",\"d\":\"DeserializedValue\"}`,\n\t\t},\n\t}\n\t// parse query\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc testVariables_ObjectsAndNullability_UsingVariables_GetAST(t *testing.T) *ast.Document {\n\tdoc := `\n        query q($input: TestInputObject) {\n          fieldWithObjectInput(input: $input)\n        }\n\t`\n\treturn testutil.TestParse(t, doc)\n}\nfunc TestVariables_ObjectsAndNullability_UsingVariables_ExecutesWithComplexInput(t *testing.T) {\n\n\tparams := map[string]interface{}{\n\t\t\"input\": map[string]interface{}{\n\t\t\t\"a\": \"foo\",\n\t\t\t\"b\": []interface{}{\"bar\"},\n\t\t\t\"c\": \"baz\",\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithObjectInput\": `{\"a\":\"foo\",\"b\":[\"bar\"],\"c\":\"baz\"}`,\n\t\t},\n\t}\n\n\tast := testVariables_ObjectsAndNullability_UsingVariables_GetAST(t)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestVariables_ObjectsAndNullability_UsingVariables_UsesDefaultValueWhenNotProvided(t *testing.T) {\n\n\tdoc := `\n\t  query q($input: TestInputObject = {a: \"foo\", b: [\"bar\"], c: \"baz\"}) {\n\t\tfieldWithObjectInput(input: $input)\n\t  }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithObjectInput\": `{\"a\":\"foo\",\"b\":[\"bar\"],\"c\":\"baz\"}`,\n\t\t},\n\t}\n\n\twithDefaultsAST := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    withDefaultsAST,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingVariables_ProperlyParsesSingleValueToList(t *testing.T) {\n\tparams := map[string]interface{}{\n\t\t\"input\": map[string]interface{}{\n\t\t\t\"a\": \"foo\",\n\t\t\t\"b\": \"bar\",\n\t\t\t\"c\": \"baz\",\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithObjectInput\": `{\"a\":\"foo\",\"b\":[\"bar\"],\"c\":\"baz\"}`,\n\t\t},\n\t}\n\n\tast := testVariables_ObjectsAndNullability_UsingVariables_GetAST(t)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingVariables_ExecutesWithComplexScalarInput(t *testing.T) {\n\tparams := map[string]interface{}{\n\t\t\"input\": map[string]interface{}{\n\t\t\t\"c\": \"foo\",\n\t\t\t\"d\": \"SerializedValue\",\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithObjectInput\": `{\"c\":\"foo\",\"d\":\"DeserializedValue\"}`,\n\t\t},\n\t}\n\n\tast := testVariables_ObjectsAndNullability_UsingVariables_GetAST(t)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingVariables_ErrorsOnNullForNestedNonNull(t *testing.T) {\n\tparams := map[string]interface{}{\n\t\t\"input\": map[string]interface{}{\n\t\t\t\"a\": \"foo\",\n\t\t\t\"b\": \"bar\",\n\t\t\t\"c\": nil,\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" got invalid value {\"a\":\"foo\",\"b\":\"bar\",\"c\":null}.` +\n\t\t\t\t\t\"\\nIn field \\\"c\\\": Expected \\\"String!\\\", found null.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tast := testVariables_ObjectsAndNullability_UsingVariables_GetAST(t)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingVariables_ErrorsOnIncorrectType(t *testing.T) {\n\tparams := map[string]interface{}{\n\t\t\"input\": \"foo bar\",\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: \"Variable \\\"$input\\\" got invalid value \\\"foo bar\\\".\\nExpected \\\"TestInputObject\\\", found not an object.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tast := testVariables_ObjectsAndNullability_UsingVariables_GetAST(t)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingVariables_ErrorsOnOmissionOfNestedNonNull(t *testing.T) {\n\tparams := map[string]interface{}{\n\t\t\"input\": map[string]interface{}{\n\t\t\t\"a\": \"foo\",\n\t\t\t\"b\": \"bar\",\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" got invalid value {\"a\":\"foo\",\"b\":\"bar\"}.` +\n\t\t\t\t\t\"\\nIn field \\\"c\\\": Expected \\\"String!\\\", found null.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tast := testVariables_ObjectsAndNullability_UsingVariables_GetAST(t)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingVariables_ErrorsOnDeepNestedErrorsAndWithManyErrors(t *testing.T) {\n\tparams := map[string]interface{}{\n\t\t\"input\": map[string]interface{}{\n\t\t\t\"na\": map[string]interface{}{\n\t\t\t\t\"a\": \"foo\",\n\t\t\t},\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" got invalid value {\"na\":{\"a\":\"foo\"}}.` +\n\t\t\t\t\t\"\\nIn field \\\"na\\\": In field \\\"c\\\": Expected \\\"String!\\\", found null.\" +\n\t\t\t\t\t\"\\nIn field \\\"nb\\\": Expected \\\"String!\\\", found null.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 19,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tdoc := `\n          query q($input: TestNestedInputObject) {\n            fieldWithNestedObjectInput(input: $input)\n          }\n        `\n\n\tnestedAST := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    nestedAST,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ObjectsAndNullability_UsingVariables_ErrorsOnAdditionOfUnknownInputField(t *testing.T) {\n\tparams := map[string]interface{}{\n\t\t\"input\": map[string]interface{}{\n\t\t\t\"a\":     \"foo\",\n\t\t\t\"b\":     \"bar\",\n\t\t\t\"c\":     \"baz\",\n\t\t\t\"extra\": \"dog\",\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" got invalid value {\"a\":\"foo\",\"b\":\"bar\",\"c\":\"baz\",\"extra\":\"dog\"}.` +\n\t\t\t\t\t\"\\nIn field \\\"extra\\\": Unknown field.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tast := testVariables_ObjectsAndNullability_UsingVariables_GetAST(t)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestVariables_NullableScalars_AllowsNullableInputsToBeOmitted(t *testing.T) {\n\tdoc := `\n      {\n        fieldWithNullableStringInput\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNullableStringInput\": nil,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NullableScalars_AllowsNullableInputsToBeOmittedInAVariable(t *testing.T) {\n\tdoc := `\n      query SetsNullable($value: String) {\n        fieldWithNullableStringInput(input: $value)\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNullableStringInput\": nil,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NullableScalars_AllowsNullableInputsToBeOmittedInAnUnlistedVariable(t *testing.T) {\n\tdoc := `\n      query SetsNullable {\n        fieldWithNullableStringInput(input: $value)\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNullableStringInput\": nil,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NullableScalars_AllowsNullableInputsToBeSetToNullInAVariable(t *testing.T) {\n\tdoc := `\n      query SetsNullable($value: String) {\n        fieldWithNullableStringInput(input: $value)\n      }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"value\": nil,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNullableStringInput\": nil,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NullableScalars_AllowsNullableInputsToBeSetToAValueInAVariable(t *testing.T) {\n\tdoc := `\n      query SetsNullable($value: String) {\n        fieldWithNullableStringInput(input: $value)\n      }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"value\": \"a\",\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNullableStringInput\": `\"a\"`,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NullableScalars_AllowsNullableInputsToBeSetToAValueDirectly(t *testing.T) {\n\tdoc := `\n      {\n        fieldWithNullableStringInput(input: \"a\")\n      }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNullableStringInput\": `\"a\"`,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestVariables_NonNullableScalars_DoesNotAllowNonNullableInputsToBeOmittedInAVariable(t *testing.T) {\n\n\tdoc := `\n        query SetsNonNullable($value: String!) {\n          fieldWithNonNullableStringInput(input: $value)\n        }\n\t`\n\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$value\" of required type \"String!\" was not provided.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 31,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NonNullableScalars_DoesNotAllowNonNullableInputsToBeSetToNullInAVariable(t *testing.T) {\n\tdoc := `\n        query SetsNonNullable($value: String!) {\n          fieldWithNonNullableStringInput(input: $value)\n        }\n\t`\n\n\tparams := map[string]interface{}{\n\t\t\"value\": nil,\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$value\" of required type \"String!\" was not provided.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 31,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NonNullableScalars_AllowsNonNullableInputsToBeSetToAValueInAVariable(t *testing.T) {\n\tdoc := `\n        query SetsNonNullable($value: String!) {\n          fieldWithNonNullableStringInput(input: $value)\n        }\n\t`\n\n\tparams := map[string]interface{}{\n\t\t\"value\": \"a\",\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNonNullableStringInput\": `\"a\"`,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NonNullableScalars_AllowsNonNullableInputsToBeSetToAValueDirectly(t *testing.T) {\n\tdoc := `\n      {\n        fieldWithNonNullableStringInput(input: \"a\")\n      }\n\t`\n\n\tparams := map[string]interface{}{\n\t\t\"value\": \"a\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNonNullableStringInput\": `\"a\"`,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_NonNullableScalars_PassesAlongNullForNonNullableInputsIfExplicitlySetInTheQuery(t *testing.T) {\n\tdoc := `\n      {\n        fieldWithNonNullableStringInput\n      }\n\t`\n\n\tparams := map[string]interface{}{\n\t\t\"value\": \"a\",\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithNonNullableStringInput\": nil,\n\t\t},\n\t}\n\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestVariables_ListsAndNullability_AllowsListsToBeNull(t *testing.T) {\n\tdoc := `\n        query q($input: [String]) {\n          list(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": nil,\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"list\": nil,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_AllowsListsToContainValues(t *testing.T) {\n\tdoc := `\n        query q($input: [String]) {\n          list(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": []interface{}{\"A\"},\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"list\": `[\"A\"]`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_AllowsListsToContainNull(t *testing.T) {\n\tdoc := `\n        query q($input: [String]) {\n          list(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": []interface{}{\"A\", nil, \"B\"},\n\t}\n\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"list\": `[\"A\",null,\"B\"]`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_DoesNotAllowNonNullListsToBeNull(t *testing.T) {\n\tdoc := `\n        query q($input: [String]!) {\n          nnList(input: $input)\n        }\n\t`\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" of required type \"[String]!\" was not provided.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_AllowsNonNullListsToContainValues(t *testing.T) {\n\tdoc := `\n        query q($input: [String]!) {\n          nnList(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": []interface{}{\"A\"},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nnList\": `[\"A\"]`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_AllowsNonNullListsToContainNull(t *testing.T) {\n\tdoc := `\n        query q($input: [String]!) {\n          nnList(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": []interface{}{\"A\", nil, \"B\"},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nnList\": `[\"A\",null,\"B\"]`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_AllowsListsOfNonNullsToBeNull(t *testing.T) {\n\tdoc := `\n        query q($input: [String!]) {\n          listNN(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": nil,\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"listNN\": nil,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_AllowsListsOfNonNullsToContainValues(t *testing.T) {\n\tdoc := `\n        query q($input: [String!]) {\n          listNN(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": []interface{}{\"A\"},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"listNN\": `[\"A\"]`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) > 0 {\n\t\tt.Fatalf(\"wrong result, unexpected errors: %v\", result.Errors)\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_DoesNotAllowListOfNonNullsToContainNull(t *testing.T) {\n\tdoc := `\n        query q($input: [String!]) {\n          listNN(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": []interface{}{\"A\", nil, \"B\"},\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" got invalid value ` +\n\t\t\t\t\t`[\"A\",null,\"B\"].` +\n\t\t\t\t\t\"\\nIn element #1: Expected \\\"String!\\\", found null.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_DoesNotAllowNonNullListOfNonNullsToBeNull(t *testing.T) {\n\tdoc := `\n        query q($input: [String!]!) {\n          nnListNN(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": nil,\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" of required type \"[String!]!\" was not provided.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_AllowsNonNullListsOfNonNulsToContainValues(t *testing.T) {\n\tdoc := `\n        query q($input: [String!]!) {\n          nnListNN(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": []interface{}{\"A\"},\n\t}\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"nnListNN\": `[\"A\"]`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_DoesNotAllowNonNullListOfNonNullsToContainNull(t *testing.T) {\n\tdoc := `\n        query q($input: [String!]!) {\n          nnListNN(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": []interface{}{\"A\", nil, \"B\"},\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" got invalid value ` +\n\t\t\t\t\t`[\"A\",null,\"B\"].` +\n\t\t\t\t\t\"\\nIn element #1: Expected \\\"String!\\\", found null.\",\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_DoesNotAllowInvalidTypesToBeUsedAsValues(t *testing.T) {\n\tdoc := `\n        query q($input: TestType!) {\n          fieldWithObjectInput(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": map[string]interface{}{\n\t\t\t\"list\": []interface{}{\"A\", \"B\"},\n\t\t},\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" expected value of type \"TestType!\" which cannot be used as an input type.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_ListsAndNullability_DoesNotAllowUnknownTypesToBeUsedAsValues(t *testing.T) {\n\tdoc := `\n        query q($input: UnknownType!) {\n          fieldWithObjectInput(input: $input)\n        }\n\t`\n\tparams := map[string]interface{}{\n\t\t\"input\": \"whoknows\",\n\t}\n\texpected := &graphql.Result{\n\t\tData: nil,\n\t\tErrors: []gqlerrors.FormattedError{\n\t\t\t{\n\t\t\t\tMessage: `Variable \"$input\" expected value of type \"UnknownType!\" which cannot be used as an input type.`,\n\t\t\t\tLocations: []location.SourceLocation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLine: 2, Column: 17,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t\tArgs:   params,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif !testutil.EqualResults(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n\nfunc TestVariables_UsesArgumentDefaultValues_WhenNoArgumentProvided(t *testing.T) {\n\tdoc := `\n\t{\n      fieldWithDefaultArgumentValue\n    }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithDefaultArgumentValue\": `\"Hello World\"`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_UsesArgumentDefaultValues_WhenNullableVariableProvided(t *testing.T) {\n\tdoc := `\n\tquery optionalVariable($optional: String) {\n        fieldWithDefaultArgumentValue(input: $optional)\n    }\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithDefaultArgumentValue\": `\"Hello World\"`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\nfunc TestVariables_UsesArgumentDefaultValues_WhenArgumentProvidedCannotBeParsed(t *testing.T) {\n\tdoc := `\n\t{\n\t\tfieldWithDefaultArgumentValue(input: WRONG_TYPE)\n\t}\n\t`\n\texpected := &graphql.Result{\n\t\tData: map[string]interface{}{\n\t\t\t\"fieldWithDefaultArgumentValue\": `\"Hello World\"`,\n\t\t},\n\t}\n\tast := testutil.TestParse(t, doc)\n\n\t// execute\n\tep := graphql.ExecuteParams{\n\t\tSchema: variablesTestSchema,\n\t\tAST:    ast,\n\t}\n\tresult := testutil.TestExecute(t, ep)\n\tif len(result.Errors) != len(expected.Errors) {\n\t\tt.Fatalf(\"Unexpected errors, Diff: %v\", testutil.Diff(expected.Errors, result.Errors))\n\t}\n\tif !reflect.DeepEqual(expected, result) {\n\t\tt.Fatalf(\"Unexpected result, Diff: %v\", testutil.Diff(expected, result))\n\t}\n}\n"
  }
]