1 package jsonutil_test
2
3 import (
4 "reflect"
5 "testing"
6 "time"
7
8 "github.com/cli/shurcooL-graphql"
9 "github.com/cli/shurcooL-graphql/internal/jsonutil"
10 )
11
12 func TestUnmarshalGraphQL(t *testing.T) {
13
21 type query struct {
22 Me struct {
23 Name graphql.String
24 Height graphql.Float
25 }
26 }
27 var got query
28 err := jsonutil.UnmarshalGraphQL([]byte(`{
29 "me": {
30 "name": "Luke Skywalker",
31 "height": 1.72
32 }
33 }`), &got)
34 if err != nil {
35 t.Fatal(err)
36 }
37 var want query
38 want.Me.Name = "Luke Skywalker"
39 want.Me.Height = 1.72
40 if !reflect.DeepEqual(got, want) {
41 t.Error("not equal")
42 }
43 }
44
45 func TestUnmarshalGraphQL_graphqlTag(t *testing.T) {
46 type query struct {
47 Foo graphql.String `graphql:"baz"`
48 }
49 var got query
50 err := jsonutil.UnmarshalGraphQL([]byte(`{
51 "baz": "bar"
52 }`), &got)
53 if err != nil {
54 t.Fatal(err)
55 }
56 want := query{
57 Foo: "bar",
58 }
59 if !reflect.DeepEqual(got, want) {
60 t.Error("not equal")
61 }
62 }
63
64 func TestUnmarshalGraphQL_jsonTag(t *testing.T) {
65 type query struct {
66 Foo graphql.String `json:"baz"`
67 }
68 var got query
69 err := jsonutil.UnmarshalGraphQL([]byte(`{
70 "foo": "bar"
71 }`), &got)
72 if err != nil {
73 t.Fatal(err)
74 }
75 want := query{
76 Foo: "bar",
77 }
78 if !reflect.DeepEqual(got, want) {
79 t.Error("not equal")
80 }
81 }
82
83 func TestUnmarshalGraphQL_array(t *testing.T) {
84 type query struct {
85 Foo []graphql.String
86 Bar []graphql.String
87 Baz []graphql.String
88 }
89 var got query
90 err := jsonutil.UnmarshalGraphQL([]byte(`{
91 "foo": [
92 "bar",
93 "baz"
94 ],
95 "bar": [],
96 "baz": null
97 }`), &got)
98 if err != nil {
99 t.Fatal(err)
100 }
101 want := query{
102 Foo: []graphql.String{"bar", "baz"},
103 Bar: []graphql.String{},
104 Baz: []graphql.String(nil),
105 }
106 if !reflect.DeepEqual(got, want) {
107 t.Error("not equal")
108 }
109 }
110
111
112
113 func TestUnmarshalGraphQL_arrayReset(t *testing.T) {
114 var got = []string{"initial"}
115 err := jsonutil.UnmarshalGraphQL([]byte(`["bar", "baz"]`), &got)
116 if err != nil {
117 t.Fatal(err)
118 }
119 want := []string{"bar", "baz"}
120 if !reflect.DeepEqual(got, want) {
121 t.Error("not equal")
122 }
123 }
124
125 func TestUnmarshalGraphQL_objectArray(t *testing.T) {
126 type query struct {
127 Foo []struct {
128 Name graphql.String
129 }
130 }
131 var got query
132 err := jsonutil.UnmarshalGraphQL([]byte(`{
133 "foo": [
134 {"name": "bar"},
135 {"name": "baz"}
136 ]
137 }`), &got)
138 if err != nil {
139 t.Fatal(err)
140 }
141 want := query{
142 Foo: []struct{ Name graphql.String }{
143 {"bar"},
144 {"baz"},
145 },
146 }
147 if !reflect.DeepEqual(got, want) {
148 t.Error("not equal")
149 }
150 }
151
152 func TestUnmarshalGraphQL_pointer(t *testing.T) {
153 type query struct {
154 Foo *graphql.String
155 Bar *graphql.String
156 }
157 var got query
158 got.Bar = new(graphql.String)
159 err := jsonutil.UnmarshalGraphQL([]byte(`{
160 "foo": "foo",
161 "bar": null
162 }`), &got)
163 if err != nil {
164 t.Fatal(err)
165 }
166 want := query{
167 Foo: graphql.NewString("foo"),
168 Bar: nil,
169 }
170 if !reflect.DeepEqual(got, want) {
171 t.Error("not equal")
172 }
173 }
174
175 func TestUnmarshalGraphQL_objectPointerArray(t *testing.T) {
176 type query struct {
177 Foo []*struct {
178 Name graphql.String
179 }
180 }
181 var got query
182 err := jsonutil.UnmarshalGraphQL([]byte(`{
183 "foo": [
184 {"name": "bar"},
185 null,
186 {"name": "baz"}
187 ]
188 }`), &got)
189 if err != nil {
190 t.Fatal(err)
191 }
192 want := query{
193 Foo: []*struct{ Name graphql.String }{
194 {"bar"},
195 nil,
196 {"baz"},
197 },
198 }
199 if !reflect.DeepEqual(got, want) {
200 t.Error("not equal")
201 }
202 }
203
204 func TestUnmarshalGraphQL_pointerWithInlineFragment(t *testing.T) {
205 type actor struct {
206 User struct {
207 DatabaseID uint64
208 } `graphql:"... on User"`
209 Login string
210 }
211 type query struct {
212 Author actor
213 Editor *actor
214 }
215 var got query
216 err := jsonutil.UnmarshalGraphQL([]byte(`{
217 "author": {
218 "databaseId": 1,
219 "login": "test1"
220 },
221 "editor": {
222 "databaseId": 2,
223 "login": "test2"
224 }
225 }`), &got)
226 if err != nil {
227 t.Fatal(err)
228 }
229 var want query
230 want.Author = actor{
231 User: struct{ DatabaseID uint64 }{1},
232 Login: "test1",
233 }
234 want.Editor = &actor{
235 User: struct{ DatabaseID uint64 }{2},
236 Login: "test2",
237 }
238
239 if !reflect.DeepEqual(got, want) {
240 t.Error("not equal")
241 }
242 }
243
244 func TestUnmarshalGraphQL_unexportedField(t *testing.T) {
245 type query struct {
246 foo graphql.String
247 }
248 err := jsonutil.UnmarshalGraphQL([]byte(`{"foo": "bar"}`), new(query))
249 if err == nil {
250 t.Fatal("got error: nil, want: non-nil")
251 }
252 if got, want := err.Error(), "struct field for \"foo\" doesn't exist in any of 1 places to unmarshal"; got != want {
253 t.Errorf("got error: %v, want: %v", got, want)
254 }
255 }
256
257 func TestUnmarshalGraphQL_multipleValues(t *testing.T) {
258 type query struct {
259 Foo graphql.String
260 }
261 err := jsonutil.UnmarshalGraphQL([]byte(`{"foo": "bar"}{"foo": "baz"}`), new(query))
262 if err == nil {
263 t.Fatal("got error: nil, want: non-nil")
264 }
265 if got, want := err.Error(), "invalid token '{' after top-level value"; got != want {
266 t.Errorf("got error: %v, want: %v", got, want)
267 }
268 }
269
270 func TestUnmarshalGraphQL_directives(t *testing.T) {
271
279 type query struct {
280 Me struct {
281 Name graphql.String `graphql:"name @include(if: true)"`
282 Height graphql.Float `graphql:"height @skip(if: false)"`
283 }
284 }
285 var got query
286 err := jsonutil.UnmarshalGraphQL([]byte(`{
287 "me": {
288 "name": "Luke Skywalker",
289 "height": 1.72
290 }
291 }`), &got)
292 if err != nil {
293 t.Fatal(err)
294 }
295 var want query
296 want.Me.Name = "Luke Skywalker"
297 want.Me.Height = 1.72
298 if !reflect.DeepEqual(got, want) {
299 t.Error("not equal")
300 }
301 }
302
303 func TestUnmarshalGraphQL_union(t *testing.T) {
304
317 type actor struct{ Login graphql.String }
318 type closedEvent struct {
319 Actor actor
320 CreatedAt time.Time
321 }
322 type reopenedEvent struct {
323 Actor actor
324 CreatedAt time.Time
325 }
326 type issueTimelineItem struct {
327 Typename string `graphql:"__typename"`
328 ClosedEvent closedEvent `graphql:"... on ClosedEvent"`
329 ReopenedEvent reopenedEvent `graphql:"... on ReopenedEvent"`
330 }
331 var got issueTimelineItem
332 err := jsonutil.UnmarshalGraphQL([]byte(`{
333 "__typename": "ClosedEvent",
334 "createdAt": "2017-06-29T04:12:01Z",
335 "actor": {
336 "login": "shurcooL-test"
337 }
338 }`), &got)
339 if err != nil {
340 t.Fatal(err)
341 }
342 want := issueTimelineItem{
343 Typename: "ClosedEvent",
344 ClosedEvent: closedEvent{
345 Actor: actor{
346 Login: "shurcooL-test",
347 },
348 CreatedAt: time.Unix(1498709521, 0).UTC(),
349 },
350 ReopenedEvent: reopenedEvent{
351 Actor: actor{
352 Login: "shurcooL-test",
353 },
354 CreatedAt: time.Unix(1498709521, 0).UTC(),
355 },
356 }
357 if !reflect.DeepEqual(got, want) {
358 t.Error("not equal")
359 }
360 }
361
362
363 func TestUnmarshalGraphQL_arrayInsideInlineFragment(t *testing.T) {
364
379 type query struct {
380 Search struct {
381 Nodes []struct {
382 PullRequest struct {
383 Commits struct {
384 Nodes []struct {
385 URL string `graphql:"url"`
386 }
387 } `graphql:"commits(last: 1)"`
388 } `graphql:"... on PullRequest"`
389 }
390 } `graphql:"search(type: ISSUE, first: 1, query: \"type:pr repo:owner/name\")"`
391 }
392 var got query
393 err := jsonutil.UnmarshalGraphQL([]byte(`{
394 "search": {
395 "nodes": [
396 {
397 "commits": {
398 "nodes": [
399 {
400 "url": "https://example.org/commit/49e1"
401 }
402 ]
403 }
404 }
405 ]
406 }
407 }`), &got)
408 if err != nil {
409 t.Fatal(err)
410 }
411 var want query
412 want.Search.Nodes = make([]struct {
413 PullRequest struct {
414 Commits struct {
415 Nodes []struct {
416 URL string `graphql:"url"`
417 }
418 } `graphql:"commits(last: 1)"`
419 } `graphql:"... on PullRequest"`
420 }, 1)
421 want.Search.Nodes[0].PullRequest.Commits.Nodes = make([]struct {
422 URL string `graphql:"url"`
423 }, 1)
424 want.Search.Nodes[0].PullRequest.Commits.Nodes[0].URL = "https://example.org/commit/49e1"
425 if !reflect.DeepEqual(got, want) {
426 t.Error("not equal")
427 }
428 }
429
View as plain text