@@ -69,20 +69,134 @@ describe('Star Wars Query Stream Tests', () => {
69
69
} ) ;
70
70
} ) ;
71
71
72
- describe ( 'Basic Queries ' , ( ) => {
73
- it ( 'Can @stream an array field' , async ( ) => {
72
+ describe ( '@stream conflict validation ' , ( ) => {
73
+ it ( 'Does not allow a mix of @stream and no @stream on the same field' , async ( ) => {
74
74
const query = `
75
75
query HeroFriendsQuery {
76
76
hero {
77
- friends @stream(initial_count: 2, label: "HeroFriends") {
77
+ friends {
78
+ id
79
+ }
80
+ ...FriendsName
81
+ }
82
+ }
83
+ fragment FriendsName on Character {
84
+ friends @stream(label: "nameLabel", initial_count: 1) {
85
+ name
86
+ }
87
+ }
88
+ ` ;
89
+ const result = await graphql ( StarWarsSchemaDeferStreamEnabled , query ) ;
90
+ expect ( result ) . to . deep . equal ( {
91
+ errors : [
92
+ {
93
+ message :
94
+ 'Fields "friends" conflict because they have differing stream directives. Use different aliases on the fields to fetch both if this was intentional.' ,
95
+ locations : [
96
+ {
97
+ line : 4 ,
98
+ column : 13 ,
99
+ } ,
100
+ {
101
+ line : 11 ,
102
+ column : 11 ,
103
+ } ,
104
+ ] ,
105
+ } ,
106
+ ] ,
107
+ } ) ;
108
+ } ) ;
109
+ it ( 'Does not allow multiple @stream with different initial_count' , async ( ) => {
110
+ const query = `
111
+ query HeroFriendsQuery {
112
+ hero {
113
+ friends @stream(label: "sameLabel", initial_count: 3) {
114
+ id
115
+ }
116
+ ...FriendsName
117
+ }
118
+ }
119
+ fragment FriendsName on Character {
120
+ friends @stream(label: "sameLabel", initial_count: 1) {
121
+ name
122
+ }
123
+ }
124
+ ` ;
125
+ const result = await graphql ( StarWarsSchemaDeferStreamEnabled , query ) ;
126
+ expect ( result ) . to . deep . equal ( {
127
+ errors : [
128
+ {
129
+ message :
130
+ 'Fields "friends" conflict because they have differing stream directives. Use different aliases on the fields to fetch both if this was intentional.' ,
131
+ locations : [
132
+ {
133
+ line : 4 ,
134
+ column : 13 ,
135
+ } ,
136
+ {
137
+ line : 11 ,
138
+ column : 11 ,
139
+ } ,
140
+ ] ,
141
+ } ,
142
+ ] ,
143
+ } ) ;
144
+ } ) ;
145
+ it ( 'Does not allow multiple @stream with different label' , async ( ) => {
146
+ const query = `
147
+ query HeroFriendsQuery {
148
+ hero {
149
+ friends @stream(label: "idLabel", initial_count: 1) {
78
150
id
79
- name
80
151
}
152
+ ...FriendsName
153
+ }
154
+ }
155
+ fragment FriendsName on Character {
156
+ friends @stream(label: "nameLabel", initial_count: 1) {
157
+ name
81
158
}
82
159
}
83
160
` ;
161
+ const result = await graphql ( StarWarsSchemaDeferStreamEnabled , query ) ;
162
+ expect ( result ) . to . deep . equal ( {
163
+ errors : [
164
+ {
165
+ message :
166
+ 'Fields "friends" conflict because they have differing stream directives. Use different aliases on the fields to fetch both if this was intentional.' ,
167
+ locations : [
168
+ {
169
+ line : 4 ,
170
+ column : 13 ,
171
+ } ,
172
+ {
173
+ line : 11 ,
174
+ column : 11 ,
175
+ } ,
176
+ ] ,
177
+ } ,
178
+ ] ,
179
+ } ) ;
180
+ } ) ;
181
+ it ( 'Does allow multiple @stream with same label and initial_count' , async ( ) => {
182
+ const query = `
183
+ query HeroFriendsQuery {
184
+ hero {
185
+ friends @stream(label: "sameLabel", initial_count: 2) {
186
+ id
187
+ }
188
+ ...FriendsName
189
+ }
190
+ }
191
+ fragment FriendsName on Character {
192
+ friends @stream(label: "sameLabel", initial_count: 2) {
193
+ name
194
+ }
195
+ }
196
+ ` ;
84
197
const result = await graphql ( StarWarsSchemaDeferStreamEnabled , query ) ;
85
198
const { patches : patchesIterable , ...initial } = result ;
199
+
86
200
expect ( initial ) . to . deep . equal ( {
87
201
data : {
88
202
hero : {
@@ -99,44 +213,99 @@ describe('Star Wars Query Stream Tests', () => {
99
213
} ,
100
214
} ,
101
215
} ) ;
102
-
103
216
const patches = [ ] ;
104
-
105
217
if ( patchesIterable ) {
106
218
await forAwaitEach ( patchesIterable , patch => {
107
219
patches . push ( patch ) ;
108
220
} ) ;
109
221
}
110
-
111
222
expect ( patches ) . to . have . lengthOf ( 1 ) ;
112
223
expect ( patches [ 0 ] ) . to . deep . equal ( {
113
- label : 'HeroFriends' ,
224
+ data : {
225
+ id : '1003' ,
226
+ name : 'Leia Organa' ,
227
+ } ,
114
228
path : [ 'hero' , 'friends' , 2 ] ,
229
+ label : 'sameLabel' ,
230
+ } ) ;
231
+ } ) ;
232
+ it ( 'Does allow multiple @stream with different label and initial_count when fields are aliased' , async ( ) => {
233
+ const query = `
234
+ query HeroFriendsQuery {
235
+ hero {
236
+ friends @stream(label: "idLabel", initial_count: 2) {
237
+ id
238
+ }
239
+ ...FriendsName
240
+ }
241
+ }
242
+ fragment FriendsName on Character {
243
+ namedFriends: friends @stream(label: "nameLabel", initial_count: 1) {
244
+ name
245
+ }
246
+ }
247
+ ` ;
248
+ const result = await graphql ( StarWarsSchemaDeferStreamEnabled , query ) ;
249
+ const { patches : patchesIterable , ...initial } = result ;
250
+
251
+ expect ( initial ) . to . deep . equal ( {
252
+ data : {
253
+ hero : {
254
+ friends : [
255
+ {
256
+ id : '1000' ,
257
+ } ,
258
+ {
259
+ id : '1002' ,
260
+ } ,
261
+ ] ,
262
+ namedFriends : [
263
+ {
264
+ name : 'Luke Skywalker' ,
265
+ } ,
266
+ ] ,
267
+ } ,
268
+ } ,
269
+ } ) ;
270
+ const patches = [ ] ;
271
+ if ( patchesIterable ) {
272
+ await forAwaitEach ( patchesIterable , patch => {
273
+ patches . push ( patch ) ;
274
+ } ) ;
275
+ }
276
+ expect ( patches ) . to . have . lengthOf ( 3 ) ;
277
+ expect ( patches [ 0 ] ) . to . deep . equal ( {
115
278
data : {
116
279
id : '1003' ,
280
+ } ,
281
+ path : [ 'hero' , 'friends' , 2 ] ,
282
+ label : 'idLabel' ,
283
+ } ) ;
284
+ expect ( patches [ 1 ] ) . to . deep . equal ( {
285
+ data : {
286
+ name : 'Han Solo' ,
287
+ } ,
288
+ path : [ 'hero' , 'namedFriends' , 1 ] ,
289
+ label : 'nameLabel' ,
290
+ } ) ;
291
+ expect ( patches [ 2 ] ) . to . deep . equal ( {
292
+ data : {
117
293
name : 'Leia Organa' ,
118
294
} ,
295
+ path : [ 'hero' , 'namedFriends' , 2 ] ,
296
+ label : 'nameLabel' ,
119
297
} ) ;
120
298
} ) ;
121
- it ( 'Can @stream multiple selections on the same field' , async ( ) => {
299
+ } ) ;
300
+ describe ( 'Basic Queries' , ( ) => {
301
+ it ( 'Can @stream an array field' , async ( ) => {
122
302
const query = `
123
303
query HeroFriendsQuery {
124
304
hero {
125
- friends {
305
+ friends @stream(initial_count: 2, label: "HeroFriends") {
126
306
id
307
+ name
127
308
}
128
- ...FriendsName
129
- ...FriendsAppearsIn
130
- }
131
- }
132
- fragment FriendsName on Character {
133
- friends @stream(label: "nameLabel", initial_count: 1) {
134
- name
135
- }
136
- }
137
- fragment FriendsAppearsIn on Character {
138
- friends @stream(label: "appearsInLabel", initial_count: 2) {
139
- appearsIn
140
309
}
141
310
}
142
311
` ;
@@ -148,15 +317,11 @@ describe('Star Wars Query Stream Tests', () => {
148
317
friends : [
149
318
{
150
319
id : '1000' ,
151
- appearsIn : [ 'NEW_HOPE' , 'EMPIRE' , 'JEDI' ] ,
152
320
name : 'Luke Skywalker' ,
153
321
} ,
154
322
{
155
323
id : '1002' ,
156
- appearsIn : [ 'NEW_HOPE' , 'EMPIRE' , 'JEDI' ] ,
157
- } ,
158
- {
159
- id : '1003' ,
324
+ name : 'Han Solo' ,
160
325
} ,
161
326
] ,
162
327
} ,
@@ -171,29 +336,103 @@ describe('Star Wars Query Stream Tests', () => {
171
336
} ) ;
172
337
}
173
338
174
- expect ( patches ) . to . have . lengthOf ( 3 ) ;
339
+ expect ( patches ) . to . have . lengthOf ( 1 ) ;
175
340
expect ( patches [ 0 ] ) . to . deep . equal ( {
341
+ label : 'HeroFriends' ,
342
+ path : [ 'hero' , 'friends' , 2 ] ,
176
343
data : {
177
- name : 'Han Solo' ,
344
+ id : '1003' ,
345
+ name : 'Leia Organa' ,
346
+ } ,
347
+ } ) ;
348
+ } ) ;
349
+ it ( 'Errors are added to the correct patch' , async ( ) => {
350
+ const query = `
351
+ query HeroFriendsQuery {
352
+ hero {
353
+ friends @stream(initial_count: 0, label: "HeroFriends") {
354
+ ... on Human {
355
+ secretFriend
356
+ }
357
+ }
358
+ }
359
+ }
360
+ ` ;
361
+ const result = await graphql ( StarWarsSchemaDeferStreamEnabled , query ) ;
362
+ const { patches : patchesIterable , ...initial } = result ;
363
+ expect ( initial ) . to . deep . equal ( {
364
+ data : {
365
+ hero : {
366
+ friends : [ ] ,
367
+ } ,
178
368
} ,
179
- path : [ 'hero' , 'friends' , 1 ] ,
180
- label : 'nameLabel' ,
181
369
} ) ;
182
370
371
+ const patches = [ ] ;
372
+
373
+ if ( patchesIterable ) {
374
+ await forAwaitEach ( patchesIterable , patch => {
375
+ patches . push ( patch ) ;
376
+ } ) ;
377
+ }
378
+
379
+ expect ( patches ) . to . have . lengthOf ( 3 ) ;
380
+ expect ( patches [ 0 ] ) . to . deep . equal ( {
381
+ data : {
382
+ secretFriend : null ,
383
+ } ,
384
+ path : [ 'hero' , 'friends' , 0 ] ,
385
+ label : 'HeroFriends' ,
386
+ errors : [
387
+ {
388
+ message : 'secretFriend is secret.' ,
389
+ locations : [
390
+ {
391
+ line : 6 ,
392
+ column : 17 ,
393
+ } ,
394
+ ] ,
395
+ path : [ 'hero' , 'friends' , 0 , 'secretFriend' ] ,
396
+ } ,
397
+ ] ,
398
+ } ) ;
183
399
expect ( patches [ 1 ] ) . to . deep . equal ( {
184
400
data : {
185
- name : 'Leia Organa' ,
401
+ secretFriend : null ,
186
402
} ,
187
- path : [ 'hero' , 'friends' , 2 ] ,
188
- label : 'nameLabel' ,
403
+ path : [ 'hero' , 'friends' , 1 ] ,
404
+ label : 'HeroFriends' ,
405
+ errors : [
406
+ {
407
+ message : 'secretFriend is secret.' ,
408
+ locations : [
409
+ {
410
+ line : 6 ,
411
+ column : 17 ,
412
+ } ,
413
+ ] ,
414
+ path : [ 'hero' , 'friends' , 1 , 'secretFriend' ] ,
415
+ } ,
416
+ ] ,
189
417
} ) ;
190
-
191
418
expect ( patches [ 2 ] ) . to . deep . equal ( {
192
419
data : {
193
- appearsIn : [ 'NEW_HOPE' , 'EMPIRE' , 'JEDI' ] ,
420
+ secretFriend : null ,
194
421
} ,
195
422
path : [ 'hero' , 'friends' , 2 ] ,
196
- label : 'appearsInLabel' ,
423
+ label : 'HeroFriends' ,
424
+ errors : [
425
+ {
426
+ message : 'secretFriend is secret.' ,
427
+ locations : [
428
+ {
429
+ line : 6 ,
430
+ column : 17 ,
431
+ } ,
432
+ ] ,
433
+ path : [ 'hero' , 'friends' , 2 , 'secretFriend' ] ,
434
+ } ,
435
+ ] ,
197
436
} ) ;
198
437
} ) ;
199
438
} ) ;
0 commit comments