Skip to content

Commit

Permalink
Special handling for pointers to slices (#1363)
Browse files Browse the repository at this point in the history
  • Loading branch information
ananyasaxena authored Apr 12, 2021
1 parent c920bde commit 3f68ea2
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 5 deletions.
4 changes: 2 additions & 2 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Testing generated code is a little tricky, heres how its currently set up.

### Testing responses from a server

There is a server in `codegen/testserver` that is generated as part
There is a server in `codegen/testserver` that is generated as part
of `go generate ./...`, and tests written against it.

There are also a bunch of tests in against the examples, feel free to take examples from there.
Expand All @@ -15,7 +15,7 @@ There are also a bunch of tests in against the examples, feel free to take examp

These tests are **really** slow, because they need to run the whole codegen step. Use them very sparingly. If you can, find a way to unit test it instead.

Take a look at `codegen/input_test.go` for an example.
Take a look at `codegen/testserver/input_test.go` for an example.

### Testing introspection

Expand Down
8 changes: 8 additions & 0 deletions codegen/config/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ func (t *TypeReference) IsSlice() bool {
return t.GQL.Elem != nil && isSlice
}

func (t *TypeReference) IsPtrToSlice() bool {
if t.IsPtr() {
_, isPointerToSlice := t.GO.(*types.Pointer).Elem().(*types.Slice)
return isPointerToSlice
}
return false
}

func (t *TypeReference) IsNamed() bool {
_, isSlice := t.GO.(*types.Named)
return isSlice
Expand Down
153 changes: 153 additions & 0 deletions codegen/testserver/generated.go

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

5 changes: 5 additions & 0 deletions codegen/testserver/ptr_to_slice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package testserver

type PtrToSliceContainer struct {
PtrToSlice *[]string
}
7 changes: 7 additions & 0 deletions codegen/testserver/ptr_to_slice.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type PtrToSliceContainer {
ptrToSlice: [String!]
}

extend type Query {
ptrToSliceContainer: PtrToSliceContainer!
}
37 changes: 37 additions & 0 deletions codegen/testserver/ptr_to_slice_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package testserver

import (
"context"
"testing"

"github.com/99designs/gqlgen/client"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/stretchr/testify/require"
)

func TestPtrToSlice(t *testing.T) {
resolvers := &Stub{}

c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})))

resolvers.QueryResolver.PtrToSliceContainer = func(ctx context.Context) (wrappedStruct *PtrToSliceContainer, e error) {
ptrToSliceContainer := PtrToSliceContainer{
PtrToSlice: &[]string{"hello"},
}
return &ptrToSliceContainer, nil
}

t.Run("pointer to slice", func(t *testing.T) {
var resp struct {
PtrToSliceContainer struct {
PtrToSlice []string
}
}

err := c.Post(`query { ptrToSliceContainer { ptrToSlice }}`, &resp)
require.NoError(t, err)

require.Equal(t, []string{"hello"}, resp.PtrToSliceContainer.PtrToSlice)

})
}
4 changes: 4 additions & 0 deletions codegen/testserver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ func (r *queryResolver) PrimitiveStringObject(ctx context.Context) ([]PrimitiveS
panic("not implemented")
}

func (r *queryResolver) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) {
panic("not implemented")
}

func (r *queryResolver) DefaultScalar(ctx context.Context, arg string) (string, error) {
panic("not implemented")
}
Expand Down
4 changes: 4 additions & 0 deletions codegen/testserver/stub.go

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

2 changes: 1 addition & 1 deletion codegen/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func processType(ret map[string]*config.TypeReference, ref *config.TypeReference
}
ret[key] = ref

if ref.IsSlice() {
if ref.IsSlice() || ref.IsPtrToSlice() {
processType(ret, ref.Elem())
}
}
9 changes: 7 additions & 2 deletions codegen/type.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
{{- if and $type.IsNilable (not $type.GQL.NonNull) }}
if v == nil { return nil, nil }
{{- end }}
{{- if $type.IsSlice }}
{{- if $type.IsPtrToSlice }}
res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v)
return &res, graphql.ErrorOnPath(ctx, err)
{{- else if $type.IsSlice }}
var vSlice []interface{}
if v != nil {
if tmp1, ok := v.([]interface{}); ok {
Expand Down Expand Up @@ -66,7 +69,9 @@

{{ with $type.MarshalFunc }}
func (ec *executionContext) {{ . }}(ctx context.Context, sel ast.SelectionSet, v {{ $type.GO | ref }}) graphql.Marshaler {
{{- if $type.IsSlice }}
{{- if $type.IsPtrToSlice }}
return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v)
{{- else if $type.IsSlice }}
{{- if not $type.GQL.NonNull }}
if v == nil {
return graphql.Null
Expand Down

0 comments on commit 3f68ea2

Please sign in to comment.