From 463228c9fcc95f7977b236549980979551bfc4bd Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Mon, 26 Mar 2018 22:10:35 +1100 Subject: [PATCH] Remove missing field warning and add test for scalar resolvers fixes #63 --- codegen/util.go | 4 --- example/scalars/generated.go | 45 +++++++++++++++++++++++++++++++++- example/scalars/resolvers.go | 8 ++++++ example/scalars/scalar_test.go | 20 +++++++++++---- example/scalars/schema.graphql | 2 ++ 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/codegen/util.go b/codegen/util.go index f7ecc618fe..bad467ee46 100644 --- a/codegen/util.go +++ b/codegen/util.go @@ -194,10 +194,6 @@ func bindObject(t types.Type, object *Object, imports Imports) { } continue } - - if field.IsScalar { - fmt.Fprintf(os.Stderr, "unable to bind %s.%s to anything, %s has no suitable fields or methods\n", object.GQLType, field.GQLName, namedType.String()) - } } } diff --git a/example/scalars/generated.go b/example/scalars/generated.go index 8fbd8fe9d6..ea002bfe4d 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -26,6 +26,9 @@ func MakeExecutableSchema(resolvers Resolvers, opts ...ExecutableOption) graphql type Resolvers interface { Query_user(ctx context.Context, id string) (*User, error) Query_search(ctx context.Context, input SearchArgs) ([]User, error) + + User_primitiveResolver(ctx context.Context, obj *User) (string, error) + User_customResolver(ctx context.Context, obj *User) (Point, error) } type ExecutableOption func(*executableSchema) @@ -227,6 +230,10 @@ func (ec *executionContext) _User(sel []query.Selection, obj *User) graphql.Mars out.Values[i] = ec._User_location(field, obj) case "isBanned": out.Values[i] = ec._User_isBanned(field, obj) + case "primitiveResolver": + out.Values[i] = ec._User_primitiveResolver(field, obj) + case "customResolver": + out.Values[i] = ec._User_customResolver(field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -260,6 +267,42 @@ func (ec *executionContext) _User_isBanned(field graphql.CollectedField, obj *Us return graphql.MarshalBoolean(bool(res)) } +func (ec *executionContext) _User_primitiveResolver(field graphql.CollectedField, obj *User) graphql.Marshaler { + return graphql.Defer(func() (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + userErr := ec.recover(r) + ec.Error(userErr) + ret = graphql.Null + } + }() + res, err := ec.resolvers.User_primitiveResolver(ec.ctx, obj) + if err != nil { + ec.Error(err) + return graphql.Null + } + return graphql.MarshalString(res) + }) +} + +func (ec *executionContext) _User_customResolver(field graphql.CollectedField, obj *User) graphql.Marshaler { + return graphql.Defer(func() (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + userErr := ec.recover(r) + ec.Error(userErr) + ret = graphql.Null + } + }() + res, err := ec.resolvers.User_customResolver(ec.ctx, obj) + if err != nil { + ec.Error(err) + return graphql.Null + } + return res + }) +} + var __DirectiveImplementors = []string{"__Directive"} // nolint: gocyclo, errcheck, gas, goconst @@ -794,7 +837,7 @@ func UnmarshalSearchArgs(v interface{}) (SearchArgs, error) { return it, nil } -var parsedSchema = schema.MustParse("type Query {\n user(id: ID!): User\n search(input: SearchArgs = {location: \"37,144\"}): [User!]!\n}\n\ntype User {\n id: ID!\n name: String!\n created: Timestamp\n location: Point\n isBanned: Boolean!\n}\n\ninput SearchArgs {\n location: Point\n createdAfter: Timestamp\n isBanned: Boolean\n}\n\nscalar Timestamp\nscalar Point\n") +var parsedSchema = schema.MustParse("type Query {\n user(id: ID!): User\n search(input: SearchArgs = {location: \"37,144\"}): [User!]!\n}\n\ntype User {\n id: ID!\n name: String!\n created: Timestamp\n location: Point\n isBanned: Boolean!\n primitiveResolver: String!\n customResolver: Point!\n}\n\ninput SearchArgs {\n location: Point\n createdAfter: Timestamp\n isBanned: Boolean\n}\n\nscalar Timestamp\nscalar Point\n") func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) diff --git a/example/scalars/resolvers.go b/example/scalars/resolvers.go index 21a72555f6..5afe061238 100644 --- a/example/scalars/resolvers.go +++ b/example/scalars/resolvers.go @@ -45,3 +45,11 @@ func (r *Resolver) Query_search(ctx context.Context, input SearchArgs) ([]User, }, }, nil } + +func (r *Resolver) User_primitiveResolver(ctx context.Context, obj *User) (string, error) { + return "test", nil +} + +func (r *Resolver) User_customResolver(ctx context.Context, obj *User) (Point, error) { + return Point{5, 1}, nil +} diff --git a/example/scalars/scalar_test.go b/example/scalars/scalar_test.go index 835cb434d2..e3c84bb511 100644 --- a/example/scalars/scalar_test.go +++ b/example/scalars/scalar_test.go @@ -12,10 +12,12 @@ import ( ) type RawUser struct { - ID string - Name string - Created int64 - Location string + ID string + Name string + Created int64 + Location string + PrimitiveResolver string + CustomResolver string } func TestScalars(t *testing.T) { @@ -51,13 +53,21 @@ func TestScalars(t *testing.T) { require.Equal(t, "37,144", resp.Search[0].Location) }) - t.Run("test custom error messages", func(t *testing.T) { + t.Run("custom error messages", func(t *testing.T) { var resp struct{ Search []RawUser } err := c.Post(`{ search(input:{createdAfter:"2014"}) { id } }`, &resp) require.EqualError(t, err, "errors: [graphql: time should be a unix timestamp]") }) + t.Run("scalar resolver methods", func(t *testing.T) { + var resp struct{ User RawUser } + c.MustPost(`{ user(id: "1") { primitiveResolver, customResolver } }`, &resp) + + require.Equal(t, "test", resp.User.PrimitiveResolver) + require.Equal(t, "5,1", resp.User.CustomResolver) + }) + t.Run("introspection", func(t *testing.T) { // Make sure we can run the graphiql introspection query without errors var resp interface{} diff --git a/example/scalars/schema.graphql b/example/scalars/schema.graphql index 0ca4c890b0..4162b9f9ab 100644 --- a/example/scalars/schema.graphql +++ b/example/scalars/schema.graphql @@ -9,6 +9,8 @@ type User { created: Timestamp location: Point isBanned: Boolean! + primitiveResolver: String! + customResolver: Point! } input SearchArgs {