Skip to content

Commit

Permalink
Update gqlparser and gqlgen dependencies (#282)
Browse files Browse the repository at this point in the history
This updates both gqlparser and gqlgen dependencies. This was prompted
by an error report in gqlparser.

gqlparser also preserves comments now, so some test cases might need
tweaking here.

Per @tduong2049 in vektah/gqlparser#269 

### What happened?
> I am using [genqlient](https://github.com/Khan/genqlient/) to generate
GraphQL operations into Go code. It uses gqlparser to validate a
provided graph before generating code.
> In this case, I am using a supergraph composed from multiple subgraphs
via Rover CLI.

> Prior to
[v2.5.2](https://github.com/vektah/gqlparser/releases/tag/v2.5.2),
gqlparser parses the supergraph and returns no errors.
> Upon upgrading to v2.5.2+, I get the following error when running `go
run github.com/Khan/genqlient`:
> `invalid schema: Argument extension for directive join__type cannot be
null.`

> Possibly related to #258?

### What did you expect?
No parsing errors when running: `go run github.com/Khan/genqlient` on a
supergraph.
However, a validation error is returned when parsing `@join__type`
directives.

### Minimal graphql.schema and models to reproduce
```
type AircraftManufacturer
  @join__type(graph: AIRCRAFT, key: "uuid")
{
  uuid: ID!
  name: String!
}
```


Signed-off-by: Steve Coffman <steve@khanacademy.org>

---------

Signed-off-by: Steve Coffman <steve@khanacademy.org>
  • Loading branch information
StevenACoffman committed Jul 16, 2023
1 parent 34447eb commit 0581754
Show file tree
Hide file tree
Showing 44 changed files with 2,151 additions and 1,093 deletions.
1 change: 1 addition & 0 deletions example/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion generate/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package generate
import (
"path/filepath"
"sort"
"strings"
"testing"

"github.com/vektah/gqlparser/v2/ast"
Expand Down Expand Up @@ -57,7 +58,8 @@ func TestParse(t *testing.T) {
t.Run(ext, func(t *testing.T) {
queries := getTestQueries(t, ext)

got, want := ast.Dump(graphqlQueries), ast.Dump(queries)
got, want := ast.Dump(graphqlQueries), removeComments(ast.Dump(queries))

if got != want {
// TODO: nice diffing
t.Errorf("got:\n%v\nwant:\n%v\n", got, want)
Expand All @@ -66,6 +68,18 @@ func TestParse(t *testing.T) {
}
}

func removeComments(gotWithComments string) string {
var gots []string
for _, s := range strings.Split(gotWithComments, "\n") {
if strings.Contains(s, `Comment:`) {
continue
}
gots = append(gots, s)
}
got := strings.Join(gots, "\n")
return got
}

// TestParseErrors tests that query-extraction from different language source files
// produces appropriate errors if your query is invalid.
func TestParseErrors(t *testing.T) {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "ComplexInlineFragments",
"query": "\nquery ComplexInlineFragments {\n\troot {\n\t\tid\n\t\t... on Topic {\n\t\t\tschoolGrade\n\t\t}\n\t\t... on Content {\n\t\t\tname\n\t\t}\n\t}\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\t... on Article {\n\t\t\ttext\n\t\t}\n\t\t... on Content {\n\t\t\tname\n\t\t}\n\t\t... on HasDuration {\n\t\t\tduration\n\t\t}\n\t}\n\trepeatedStuff: randomItem {\n\t\t__typename\n\t\tid\n\t\tid\n\t\turl\n\t\totherId: id\n\t\t... on Article {\n\t\t\tname\n\t\t\ttext\n\t\t\totherName: name\n\t\t}\n\t\t... on Content {\n\t\t\tid\n\t\t\tname\n\t\t\totherName: name\n\t\t}\n\t\t... on HasDuration {\n\t\t\tduration\n\t\t}\n\t}\n\tconflictingStuff: randomItem {\n\t\t__typename\n\t\t... on Article {\n\t\t\tthumbnail {\n\t\t\t\tid\n\t\t\t\tthumbnailUrl\n\t\t\t}\n\t\t}\n\t\t... on Video {\n\t\t\tthumbnail {\n\t\t\t\tid\n\t\t\t\ttimestampSec\n\t\t\t}\n\t\t}\n\t}\n\tnestedStuff: randomItem {\n\t\t__typename\n\t\t... on Topic {\n\t\t\tchildren {\n\t\t\t\t__typename\n\t\t\t\tid\n\t\t\t\t... on Article {\n\t\t\t\t\ttext\n\t\t\t\t\tparent {\n\t\t\t\t\t\t... on Content {\n\t\t\t\t\t\t\tname\n\t\t\t\t\t\t\tparent {\n\t\t\t\t\t\t\t\t... on Topic {\n\t\t\t\t\t\t\t\t\tchildren {\n\t\t\t\t\t\t\t\t\t\t__typename\n\t\t\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t\t\t\tname\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",
"query": "\n# We test all the spread cases from docs/DESIGN.md, see there for more context\n# on each, as well as various other nonsense. But for abstract-in-abstract\n# spreads, we can't test cases (4b) and (4c), where I implements J or vice\n# versa, because gqlparser doesn't support interfaces that implement other\n# interfaces yet.\nquery ComplexInlineFragments {\n\troot {\n\t\tid\n\t\t... on Topic {\n\t\t\tschoolGrade\n\t\t}\n\t\t# (1) object spread in object scope\n\t\t... on Content {\n\t\t\tname\n\t\t}\n\t}\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\t... on Article {\n\t\t\ttext\n\t\t}\n\t\t# (2) object spread in abstract scope\n\t\t... on Content {\n\t\t\tname\n\t\t}\n\t\t# (4a) abstract spread in abstract scope, I == J\n\t\t... on HasDuration {\n\t\t\tduration\n\t\t}\n\t}\n\trepeatedStuff: randomItem {\n\t\t__typename\n\t\tid\n\t\tid\n\t\turl\n\t\totherId: id\n\t\t... on Article {\n\t\t\tname\n\t\t\ttext\n\t\t\totherName: name\n\t\t}\n\t\t... on Content {\n\t\t\tid\n\t\t\tname\n\t\t\totherName: name\n\t\t}\n\t\t... on HasDuration {\n\t\t\tduration\n\t\t}\n\t}\n\tconflictingStuff: randomItem {\n\t\t__typename\n\t\t# These two have different types! Naming gets complicated. Note GraphQL\n\t\t# says [1] that you can only have such naming conflicts when the fields are\n\t\t# both on object-typed spreads (reasonable, so they can never collide) and\n\t\t# they are of \"shapes that can be merged\", e.g. both nullable objects,\n\t\t# which seems very strange to me but is the most interesting case for us\n\t\t# anyway (since where we could have trouble is naming the result types).\n\t\t# [1] https://spec.graphql.org/draft/#SameResponseShape()\n\t\t# TODO(benkraft): This actually generates the wrong thing right now (the\n\t\t# two thumbnail types get the same name, and one clobbers the other). Fix\n\t\t# in a follow-up commit.\n\t\t... on Article {\n\t\t\tthumbnail {\n\t\t\t\tid\n\t\t\t\tthumbnailUrl\n\t\t\t}\n\t\t}\n\t\t... on Video {\n\t\t\tthumbnail {\n\t\t\t\tid\n\t\t\t\ttimestampSec\n\t\t\t}\n\t\t}\n\t}\n\tnestedStuff: randomItem {\n\t\t__typename\n\t\t... on Topic {\n\t\t\tchildren {\n\t\t\t\t__typename\n\t\t\t\tid\n\t\t\t\t... on Article {\n\t\t\t\t\ttext\n\t\t\t\t\tparent {\n\t\t\t\t\t\t... on Content {\n\t\t\t\t\t\t\tname\n\t\t\t\t\t\t\tparent {\n\t\t\t\t\t\t\t\t... on Topic {\n\t\t\t\t\t\t\t\t\tchildren {\n\t\t\t\t\t\t\t\t\t\t__typename\n\t\t\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t\t\t\tname\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",
"sourceLocation": "testdata/queries/ComplexInlineFragments.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "ComplexNamedFragments",
"query": "\nquery ComplexNamedFragments {\n\t... on Query {\n\t\t... QueryFragment\n\t}\n}\nfragment QueryFragment on Query {\n\t... InnerQueryFragment\n}\nfragment InnerQueryFragment on Query {\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t\t... VideoFields\n\t\t... ContentFields\n\t}\n\trandomLeaf {\n\t\t__typename\n\t\t... VideoFields\n\t\t... MoreVideoFields\n\t\t... ContentFields\n\t}\n\totherLeaf: randomLeaf {\n\t\t__typename\n\t\t... on Video {\n\t\t\t... MoreVideoFields\n\t\t\t... ContentFields\n\t\t}\n\t\t... ContentFields\n\t}\n}\nfragment VideoFields on Video {\n\tid\n\tname\n\turl\n\tduration\n\tthumbnail {\n\t\tid\n\t}\n\t... ContentFields\n}\nfragment ContentFields on Content {\n\tname\n\turl\n}\nfragment MoreVideoFields on Video {\n\tid\n\tparent {\n\t\tname\n\t\turl\n\t\t... ContentFields\n\t\tchildren {\n\t\t\t__typename\n\t\t\t... VideoFields\n\t\t}\n\t}\n}\n",
"query": "\nquery ComplexNamedFragments {\n\t... on Query {\n\t\t... QueryFragment\n\t}\n}\nfragment QueryFragment on Query {\n\t... InnerQueryFragment\n}\nfragment InnerQueryFragment on Query {\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t\t... VideoFields\n\t\t... ContentFields\n\t}\n\trandomLeaf {\n\t\t__typename\n\t\t... VideoFields\n\t\t... MoreVideoFields\n\t\t... ContentFields\n\t}\n\totherLeaf: randomLeaf {\n\t\t__typename\n\t\t... on Video {\n\t\t\t... MoreVideoFields\n\t\t\t... ContentFields\n\t\t}\n\t\t... ContentFields\n\t}\n}\nfragment VideoFields on Video {\n\tid\n\tname\n\turl\n\tduration\n\tthumbnail {\n\t\tid\n\t}\n\t... ContentFields\n}\nfragment ContentFields on Content {\n\tname\n\turl\n}\n# @genqlient(pointer: true)\nfragment MoreVideoFields on Video {\n\tid\n\tparent {\n\t\tname\n\t\turl\n\t\t... ContentFields\n\t\t# @genqlient(pointer: false)\n\t\tchildren {\n\t\t\t__typename\n\t\t\t... VideoFields\n\t\t}\n\t}\n}\n",
"sourceLocation": "testdata/queries/ComplexNamedFragments.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "CustomMarshalSlice",
"query": "\nquery CustomMarshalSlice ($datesss: [[[Date!]!]!]!, $datesssp: [[[Date!]!]!]!) {\n\tacceptsListOfListOfListsOfDates(datesss: $datesss)\n\twithPointer: acceptsListOfListOfListsOfDates(datesss: $datesssp)\n}\n",
"query": "\nquery CustomMarshalSlice ($datesss: [[[Date!]!]!]!, # @genqlient(pointer: true)\n$datesssp: [[[Date!]!]!]!) {\n\tacceptsListOfListOfListsOfDates(datesss: $datesss)\n\twithPointer: acceptsListOfListOfListsOfDates(datesss: $datesssp)\n}\n",
"sourceLocation": "testdata/queries/CustomMarshalSlice.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "ComplexNamedFragments",
"query": "\nquery ComplexNamedFragments {\n\t... QueryFragment\n}\nfragment QueryFragment on Query {\n\t... InnerQueryFragment\n}\nfragment InnerQueryFragment on Query {\n\trandomVideo {\n\t\t... VideoFields\n\t}\n\trandomItem {\n\t\t__typename\n\t\t... ContentFields\n\t}\n\totherVideo: randomVideo {\n\t\t... ContentFields\n\t}\n}\nfragment VideoFields on Video {\n\tid\n\tparent {\n\t\tvideoChildren {\n\t\t\t... ChildVideoFields\n\t\t}\n\t}\n}\nfragment ContentFields on Content {\n\tname\n\turl\n}\nfragment ChildVideoFields on Video {\n\tid\n\tname\n}\n",
"query": "\n# @genqlient(flatten: true)\nquery ComplexNamedFragments {\n\t... QueryFragment\n}\n# @genqlient(flatten: true)\nfragment QueryFragment on Query {\n\t... InnerQueryFragment\n}\nfragment InnerQueryFragment on Query {\n\t# @genqlient(flatten: true)\n\trandomVideo {\n\t\t... VideoFields\n\t}\n\t# @genqlient(flatten: true)\n\trandomItem {\n\t\t__typename\n\t\t... ContentFields\n\t}\n\t# @genqlient(flatten: true)\n\totherVideo: randomVideo {\n\t\t... ContentFields\n\t}\n}\nfragment VideoFields on Video {\n\tid\n\tparent {\n\t\t# @genqlient(flatten: true)\n\t\tvideoChildren {\n\t\t\t... ChildVideoFields\n\t\t}\n\t}\n}\nfragment ContentFields on Content {\n\tname\n\turl\n}\nfragment ChildVideoFields on Video {\n\tid\n\tname\n}\n",
"sourceLocation": "testdata/queries/Flatten.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "GetPokemon",
"query": "\nquery GetPokemon ($where: getPokemonBoolExp!) {\n\tgetPokemon(where: $where) {\n\t\tspecies\n\t\tlevel\n\t}\n}\n",
"query": "\n# @genqlient(pointer: true)\nquery GetPokemon ($where: getPokemonBoolExp!) {\n\tgetPokemon(where: $where) {\n\t\tspecies\n\t\tlevel\n\t}\n}\n",
"sourceLocation": "testdata/queries/Hasura.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "InterfaceListField",
"query": "\nquery InterfaceListField {\n\troot {\n\t\tid\n\t\tname\n\t\tchildren {\n\t\t\t__typename\n\t\t\tid\n\t\t\tname\n\t\t}\n\t}\n\twithPointer: root {\n\t\tid\n\t\tname\n\t\tchildren {\n\t\t\t__typename\n\t\t\tid\n\t\t\tname\n\t\t}\n\t}\n}\n",
"query": "\nquery InterfaceListField {\n\troot {\n\t\tid\n\t\tname\n\t\tchildren {\n\t\t\t__typename\n\t\t\tid\n\t\t\tname\n\t\t}\n\t}\n\t# @genqlient(pointer: true)\n\twithPointer: root {\n\t\tid\n\t\tname\n\t\tchildren {\n\t\t\t__typename\n\t\t\tid\n\t\t\tname\n\t\t}\n\t}\n}\n",
"sourceLocation": "testdata/queries/InterfaceListField.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "InterfaceListOfListOfListsField",
"query": "\nquery InterfaceListOfListOfListsField {\n\tlistOfListsOfListsOfContent {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n\twithPointer: listOfListsOfListsOfContent {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n}\n",
"query": "\nquery InterfaceListOfListOfListsField {\n\tlistOfListsOfListsOfContent {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n\t# @genqlient(pointer: true)\n\twithPointer: listOfListsOfListsOfContent {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n}\n",
"sourceLocation": "testdata/queries/InterfaceListOfListsOfListsField.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "InterfaceNoFragmentsQuery",
"query": "\nquery InterfaceNoFragmentsQuery {\n\troot {\n\t\tid\n\t\tname\n\t}\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n\trandomItemWithTypeName: randomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n\twithPointer: randomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n}\n",
"query": "\nquery InterfaceNoFragmentsQuery {\n\troot {\n\t\tid\n\t\tname\n\t}\n\t# (make sure sibling fields work)\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n\trandomItemWithTypeName: randomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n\t# @genqlient(pointer: true)\n\twithPointer: randomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t}\n}\n",
"sourceLocation": "testdata/queries/InterfaceNoFragments.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "MultipleDirectives",
"query": "\nquery MultipleDirectives ($query: UserQueryInput, $queries: [UserQueryInput]) {\n\tuser(query: $query) {\n\t\tid\n\t}\n\tusers(query: $queries) {\n\t\tid\n\t}\n}\n",
"query": "\n# @genqlient(typename: \"MyMultipleDirectivesResponse\")\n# @genqlient(omitempty: true)\n# @genqlient(pointer: true)\nquery MultipleDirectives (# @genqlient(pointer: false)\n# @genqlient(typename: \"MyInput\")\n$query: UserQueryInput, $queries: [UserQueryInput]) {\n\tuser(query: $query) {\n\t\tid\n\t}\n\tusers(query: $queries) {\n\t\tid\n\t}\n}\n",
"sourceLocation": "testdata/queries/MultipleDirectives.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"operations": [
{
"operationName": "OmitEmptyQuery",
"query": "\nquery OmitEmptyQuery ($query: UserQueryInput, $queries: [UserQueryInput], $dt: DateTime, $tz: String, $tzNoOmitEmpty: String) {\n\tuser(query: $query) {\n\t\tid\n\t}\n\tusers(query: $queries) {\n\t\tid\n\t}\n\tmaybeConvert(dt: $dt, tz: $tz)\n\tconvert2: maybeConvert(dt: $dt, tz: $tzNoOmitEmpty)\n}\n",
"query": "\n# @genqlient(omitempty: true)\n# @genqlient(for: \"UserQueryInput.id\", omitempty: false)\nquery OmitEmptyQuery ($query: UserQueryInput, $queries: [UserQueryInput], $dt: DateTime, $tz: String, # @genqlient(omitempty: false)\n$tzNoOmitEmpty: String) {\n\tuser(query: $query) {\n\t\tid\n\t}\n\tusers(query: $queries) {\n\t\tid\n\t}\n\tmaybeConvert(dt: $dt, tz: $tz)\n\tconvert2: maybeConvert(dt: $dt, tz: $tzNoOmitEmpty)\n}\n",
"sourceLocation": "testdata/queries/Omitempty.graphql"
}
]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0581754

Please sign in to comment.