1 package config
2
3 import (
4 "go/types"
5 "testing"
6
7 "github.com/stretchr/testify/require"
8 "github.com/vektah/gqlparser/v2"
9 "github.com/vektah/gqlparser/v2/ast"
10
11 "github.com/99designs/gqlgen/internal/code"
12 )
13
14 func TestBindingToInvalid(t *testing.T) {
15 binder, schema := createBinder(Config{})
16 _, err := binder.TypeReference(schema.Query.Fields.ForName("messages").Type, &types.Basic{})
17 require.EqualError(t, err, "Message has an invalid type")
18 }
19
20 func TestSlicePointerBinding(t *testing.T) {
21 t.Run("without OmitSliceElementPointers", func(t *testing.T) {
22 binder, schema := createBinder(Config{
23 OmitSliceElementPointers: false,
24 })
25
26 ta, err := binder.TypeReference(schema.Query.Fields.ForName("messages").Type, nil)
27 if err != nil {
28 panic(err)
29 }
30
31 require.Equal(t, ta.GO.String(), "[]*github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat.Message")
32 })
33
34 t.Run("with OmitSliceElementPointers", func(t *testing.T) {
35 binder, schema := createBinder(Config{
36 OmitSliceElementPointers: true,
37 })
38
39 ta, err := binder.TypeReference(schema.Query.Fields.ForName("messages").Type, nil)
40 if err != nil {
41 panic(err)
42 }
43
44 require.Equal(t, ta.GO.String(), "[]github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat.Message")
45 })
46 }
47
48 func TestOmittableBinding(t *testing.T) {
49 t.Run("bind nullable string with Omittable[string]", func(t *testing.T) {
50 binder, schema := createBinder(Config{})
51
52 ot, err := binder.FindType("github.com/99designs/gqlgen/graphql", "Omittable")
53 if err != nil {
54 panic(err)
55 }
56
57 it, err := binder.InstantiateType(ot, []types.Type{types.Universe.Lookup("string").Type()})
58 if err != nil {
59 panic(err)
60 }
61
62 ta, err := binder.TypeReference(schema.Types["FooInput"].Fields.ForName("nullableString").Type, it)
63 if err != nil {
64 panic(err)
65 }
66
67 require.True(t, ta.IsOmittable)
68 })
69
70 t.Run("bind nullable string with Omittable[*string]", func(t *testing.T) {
71 binder, schema := createBinder(Config{})
72
73 ot, err := binder.FindType("github.com/99designs/gqlgen/graphql", "Omittable")
74 if err != nil {
75 panic(err)
76 }
77
78 it, err := binder.InstantiateType(ot, []types.Type{types.NewPointer(types.Universe.Lookup("string").Type())})
79 if err != nil {
80 panic(err)
81 }
82
83 ta, err := binder.TypeReference(schema.Types["FooInput"].Fields.ForName("nullableString").Type, it)
84 if err != nil {
85 panic(err)
86 }
87
88 require.True(t, ta.IsOmittable)
89 })
90
91 t.Run("fail binding non-nullable string with Omittable[string]", func(t *testing.T) {
92 binder, schema := createBinder(Config{})
93
94 ot, err := binder.FindType("github.com/99designs/gqlgen/graphql", "Omittable")
95 if err != nil {
96 panic(err)
97 }
98
99 it, err := binder.InstantiateType(ot, []types.Type{types.Universe.Lookup("string").Type()})
100 if err != nil {
101 panic(err)
102 }
103
104 _, err = binder.TypeReference(schema.Types["FooInput"].Fields.ForName("nonNullableString").Type, it)
105 require.Error(t, err)
106 })
107
108 t.Run("fail binding non-nullable string with Omittable[*string]", func(t *testing.T) {
109 binder, schema := createBinder(Config{})
110
111 ot, err := binder.FindType("github.com/99designs/gqlgen/graphql", "Omittable")
112 if err != nil {
113 panic(err)
114 }
115
116 it, err := binder.InstantiateType(ot, []types.Type{types.NewPointer(types.Universe.Lookup("string").Type())})
117 if err != nil {
118 panic(err)
119 }
120
121 _, err = binder.TypeReference(schema.Types["FooInput"].Fields.ForName("nonNullableString").Type, it)
122 require.Error(t, err)
123 })
124
125 t.Run("bind nullable object with Omittable[T]", func(t *testing.T) {
126 binder, schema := createBinder(Config{})
127
128 typ, err := binder.FindType("github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat", "Message")
129 if err != nil {
130 panic(err)
131 }
132
133 ot, err := binder.FindType("github.com/99designs/gqlgen/graphql", "Omittable")
134 if err != nil {
135 panic(err)
136 }
137
138 it, err := binder.InstantiateType(ot, []types.Type{typ})
139 if err != nil {
140 panic(err)
141 }
142
143 ta, err := binder.TypeReference(schema.Types["FooInput"].Fields.ForName("nullableObject").Type, it)
144 if err != nil {
145 panic(err)
146 }
147
148 require.True(t, ta.IsOmittable)
149 })
150
151 t.Run("bind nullable object with Omittable[*T]", func(t *testing.T) {
152 binder, schema := createBinder(Config{})
153
154 typ, err := binder.FindType("github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat", "Message")
155 if err != nil {
156 panic(err)
157 }
158
159 ot, err := binder.FindType("github.com/99designs/gqlgen/graphql", "Omittable")
160 if err != nil {
161 panic(err)
162 }
163
164 it, err := binder.InstantiateType(ot, []types.Type{types.NewPointer(typ)})
165 if err != nil {
166 panic(err)
167 }
168
169 ta, err := binder.TypeReference(schema.Types["FooInput"].Fields.ForName("nullableObject").Type, it)
170 if err != nil {
171 panic(err)
172 }
173
174 require.True(t, ta.IsOmittable)
175 })
176 }
177
178 func createBinder(cfg Config) (*Binder, *ast.Schema) {
179 cfg.Models = TypeMap{
180 "Message": TypeMapEntry{
181 Model: []string{"github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat.Message"},
182 },
183 "BarInput": TypeMapEntry{
184 Model: []string{"github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat.Message"},
185 },
186 "String": TypeMapEntry{
187 Model: []string{"github.com/99designs/gqlgen/graphql.String"},
188 },
189 }
190 cfg.Packages = code.NewPackages()
191
192 cfg.Schema = gqlparser.MustLoadSchema(&ast.Source{Name: "TestAutobinding.schema", Input: `
193 type Message { id: ID }
194
195 input FooInput {
196 nullableString: String
197 nonNullableString: String!
198 nullableObject: BarInput
199 }
200
201 input BarInput {
202 id: ID
203 text: String!
204 }
205
206 type Query {
207 messages: [Message!]!
208 }
209 `})
210
211 b := cfg.NewBinder()
212
213 return b, cfg.Schema
214 }
215
View as plain text