From 15a6896694bcb73570a2cd0354dd9e7dfe22d817 Mon Sep 17 00:00:00 2001 From: Ananya Saxena Date: Sat, 17 Oct 2020 12:39:01 -0400 Subject: [PATCH] Treating pointer to a slice as a slice --- TESTING.md | 4 ++-- codegen/config/binder.go | 8 ++++++++ codegen/type.go | 2 +- codegen/type.gotpl | 9 +++++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/TESTING.md b/TESTING.md index ad7e63352ac..72ba06056c6 100644 --- a/TESTING.md +++ b/TESTING.md @@ -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. @@ -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 diff --git a/codegen/config/binder.go b/codegen/config/binder.go index 2be7b7bdd6b..6de7ae117a3 100644 --- a/codegen/config/binder.go +++ b/codegen/config/binder.go @@ -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 diff --git a/codegen/type.go b/codegen/type.go index 06b370be7f2..5a059d70131 100644 --- a/codegen/type.go +++ b/codegen/type.go @@ -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()) } } diff --git a/codegen/type.gotpl b/codegen/type.gotpl index bd5c8435113..e71b4bb5c8c 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -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 { @@ -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