Skip to content

Commit

Permalink
internal/jsonutil: support directives directly after name
Browse files Browse the repository at this point in the history
Also consider "@" when looking for the end of the field name, since
GraphQL directives can follow a field name immediately without any
arguments or aliases being involved. For example:

	query {
		me {
			firstName
			lastName @include(if: $expandedInfo)
		}
	}

The strings.Index check for "@" is the third separator we look for.
There's no reason to look separately, since we just want the first
field name separator.

Add test covering a GraphQL directive that immediately follows the
field name.

Co-authored-by: Dmitri Shuralyov <dmitri@shuralyov.com>
GitHub-Pull-Request: shurcooL#94
  • Loading branch information
2 people authored and hgiasac committed Apr 8, 2023
1 parent fa10f16 commit a465542
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
7 changes: 3 additions & 4 deletions pkg/jsonutil/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,9 @@ func keyHasGraphQLName(value, name string) bool {
// GraphQL fragment. It doesn't have a name.
return false
}
if i := strings.Index(value, "("); i != -1 {
value = value[:i]
}
if i := strings.Index(value, ":"); i != -1 {
// Cut off anything that follows the field name,
// such as field arguments, aliases, directives.
if i := strings.IndexAny(value, "(:@"); i != -1 {
value = value[:i]
}
return strings.TrimSpace(value) == name
Expand Down
34 changes: 34 additions & 0 deletions pkg/jsonutil/graphql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"
"time"

"github.com/hasura/go-graphql-client"
"github.com/hasura/go-graphql-client/pkg/jsonutil"
)

Expand Down Expand Up @@ -449,6 +450,39 @@ func TestUnmarshalGraphQL_multipleValuesInOrderedMap(t *testing.T) {
}
}

func TestUnmarshalGraphQL_directives(t *testing.T) {
/*
query {
me {
name @include(if: true)
height @skip(if: false)
}
}
*/
type query struct {
Me struct {
Name graphql.String `graphql:"name @include(if: true)"`
Height graphql.Float `graphql:"height @skip(if: false)"`
}
}
var got query
err := jsonutil.UnmarshalGraphQL([]byte(`{
"me": {
"name": "Luke Skywalker",
"height": 1.72
}
}`), &got)
if err != nil {
t.Fatal(err)
}
var want query
want.Me.Name = "Luke Skywalker"
want.Me.Height = 1.72
if !reflect.DeepEqual(got, want) {
t.Error("not equal")
}
}

func TestUnmarshalGraphQL_union(t *testing.T) {
/*
{
Expand Down

0 comments on commit a465542

Please sign in to comment.