Skip to content

Commit

Permalink
use UnmarshalFunc in args directives implement
Browse files Browse the repository at this point in the history
  • Loading branch information
asamusev committed Jun 25, 2019
1 parent dd162f0 commit be890ab
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 47 deletions.
14 changes: 4 additions & 10 deletions codegen/directive.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,12 @@ func (d *Directive) CallArgs() string {
return strings.Join(args, ", ")
}

func (d *Directive) ResolveArgs(obj string, next string) string {
args := []string{"ctx", obj, next}
func (d *Directive) ResolveArgs(obj string, next int) string {
args := []string{"ctx", obj, fmt.Sprintf("directive%d", next)}

for _, arg := range d.Args {
dArg := "&" + arg.VarName
if !arg.TypeReference.IsPtr() {
if arg.Value != nil {
dArg = templates.Dump(arg.Value)
} else {
dArg = templates.Dump(arg.Default)
}
} else if arg.Value == nil && arg.Default == nil {
dArg := arg.VarName
if arg.Value == nil && arg.Default == nil {
dArg = "nil"
}

Expand Down
17 changes: 12 additions & 5 deletions codegen/directives.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@
{{- range $i, $directive := .Directives -}}
directive{{add $i 1}} := func(ctx context.Context) (interface{}, error) {
{{- range $arg := $directive.Args }}
{{- if and $arg.TypeReference.IsPtr ( notNil "Value" $arg ) }}
{{ $arg.VarName }} := {{ $arg.Value | dump }}
{{- end }}
{{- if notNil "Value" $arg }}
{{ $arg.VarName }}, err := ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, {{ $arg.Value | dump }})
if err != nil{
return nil, err
}
{{- else if notNil "Default" $arg }}
{{ $arg.VarName }}, err := ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, {{ $arg.Default | dump }})
if err != nil{
return nil, err
}
{{- end }}
{{- end }}
n := directive{{$i}}
return ec.directives.{{$directive.Name|ucFirst}}({{$directive.ResolveArgs "in" "n" }})
return ec.directives.{{$directive.Name|ucFirst}}({{$directive.ResolveArgs "in" $i }})
}
{{- end }}
{{ end }}
Expand Down
20 changes: 13 additions & 7 deletions codegen/testserver/directive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,24 @@ func TestDirectives(t *testing.T) {
NewExecutableSchema(Config{
Resolvers: resolvers,
Directives: DirectiveRoot{
Length: func(ctx context.Context, obj interface{}, next graphql.Resolver, min int, max *int) (interface{}, error) {
Length: func(ctx context.Context, obj interface{}, next graphql.Resolver, min int, max *int, message *string) (interface{}, error) {
e := func(msg string) error {
if message == nil{
return fmt.Errorf(msg)
}
return fmt.Errorf(*message)
}
res, err := next(ctx)
if err != nil {
return nil, err
}

s := res.(string)
if len(s) < min {
return nil, fmt.Errorf("too short")
return nil, e("too short")
}
if max != nil && len(s) > *max {
return nil, fmt.Errorf("too long")
return nil, e("too long")
}
return res, nil
},
Expand Down Expand Up @@ -119,7 +125,7 @@ func TestDirectives(t *testing.T) {

err := c.Post(`query { directiveArg(arg: "") }`, &resp)

require.EqualError(t, err, `[{"message":"too short","path":["directiveArg"]}]`)
require.EqualError(t, err, `[{"message":"invalid length","path":["directiveArg"]}]`)
require.Nil(t, resp.DirectiveArg)
})
t.Run("when function errors on nullable arg directives", func(t *testing.T) {
Expand Down Expand Up @@ -171,7 +177,7 @@ func TestDirectives(t *testing.T) {

err := c.Post(`query { directiveInputNullable(arg: {text:"invalid text",inner:{message:"123"}}) }`, &resp)

require.EqualError(t, err, `[{"message":"too long","path":["directiveInputNullable"]}]`)
require.EqualError(t, err, `[{"message":"not valid","path":["directiveInputNullable"]}]`)
require.Nil(t, resp.DirectiveInputNullable)
})
t.Run("when function errors on inner directives", func(t *testing.T) {
Expand All @@ -181,7 +187,7 @@ func TestDirectives(t *testing.T) {

err := c.Post(`query { directiveInputNullable(arg: {text:"2",inner:{message:""}}) }`, &resp)

require.EqualError(t, err, `[{"message":"too short","path":["directiveInputNullable"]}]`)
require.EqualError(t, err, `[{"message":"not valid","path":["directiveInputNullable"]}]`)
require.Nil(t, resp.DirectiveInputNullable)
})
t.Run("when function errors on nullable inner directives", func(t *testing.T) {
Expand All @@ -191,7 +197,7 @@ func TestDirectives(t *testing.T) {

err := c.Post(`query { directiveInputNullable(arg: {text:"success",inner:{message:"1"},innerNullable:{message:""}}) }`, &resp)

require.EqualError(t, err, `[{"message":"too short","path":["directiveInputNullable"]}]`)
require.EqualError(t, err, `[{"message":"not valid","path":["directiveInputNullable"]}]`)
require.Nil(t, resp.DirectiveInputNullable)
})
t.Run("when function success", func(t *testing.T) {
Expand Down
90 changes: 67 additions & 23 deletions codegen/testserver/generated.go

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

4 changes: 2 additions & 2 deletions codegen/testserver/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ input InputDirectives {
text: String! @length(min: 0, max: 7, message: "not valid")
inner: InnerDirectives!
innerNullable: InnerDirectives
thirdParty: ThirdParty @length(min: 0, max: 7, message: "not valid")
thirdParty: ThirdParty @length(min: 0, max: 7)
}

input InnerDirectives {
Expand Down Expand Up @@ -116,7 +116,7 @@ type EmbeddedPointer {
Title: String
}

directive @length(min: Int!, max: Int) on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION
directive @length(min: Int!, max: Int, message: String) on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION
directive @range(min: Int = 0, max: Int) on ARGUMENT_DEFINITION
directive @custom on ARGUMENT_DEFINITION

Expand Down

0 comments on commit be890ab

Please sign in to comment.