@@ -266,6 +266,31 @@ describe('Execute: stream directive', () => {
266
266
} ,
267
267
] ) ;
268
268
} ) ;
269
+ it ( 'Can stream a list field in chunks of size greater than 1' , async ( ) => {
270
+ const document = parse ( '{ scalarList @stream(maxChunkSize: 2) }' ) ;
271
+ const result = await complete ( document ) ;
272
+
273
+ expect ( result ) . to . deep . equal ( [
274
+ {
275
+ data : {
276
+ scalarList : [ ] ,
277
+ } ,
278
+ hasNext : true ,
279
+ } ,
280
+ {
281
+ data : [ 'apple' , 'banana' ] ,
282
+ path : [ 'scalarList' ] ,
283
+ atIndex : 0 ,
284
+ hasNext : true ,
285
+ } ,
286
+ {
287
+ data : [ 'coconut' ] ,
288
+ path : [ 'scalarList' ] ,
289
+ atIndex : 2 ,
290
+ hasNext : false ,
291
+ } ,
292
+ ] ) ;
293
+ } ) ;
269
294
it ( 'Can use default value of initialCount' , async ( ) => {
270
295
const document = parse ( '{ scalarList @stream }' ) ;
271
296
const result = await complete ( document ) ;
@@ -311,7 +336,52 @@ describe('Execute: stream directive', () => {
311
336
expectJSON ( result ) . toDeepEqual ( {
312
337
errors : [
313
338
{
314
- message : 'initialCount must be a positive integer' ,
339
+ message :
340
+ 'initialCount must be an integer greater than or equal to zero' ,
341
+ locations : [
342
+ {
343
+ line : 1 ,
344
+ column : 3 ,
345
+ } ,
346
+ ] ,
347
+ path : [ 'scalarList' ] ,
348
+ } ,
349
+ ] ,
350
+ data : {
351
+ scalarList : null ,
352
+ } ,
353
+ } ) ;
354
+ } ) ;
355
+ it ( 'maxChunkSize values less than one throw field errors' , async ( ) => {
356
+ const document = parse ( '{ scalarList @stream(maxChunkSize: 0) }' ) ;
357
+ const result = await complete ( document ) ;
358
+ expectJSON ( result ) . toDeepEqual ( {
359
+ errors : [
360
+ {
361
+ message :
362
+ 'maxChunkSize must be an integer greater than or equal to one' ,
363
+ locations : [
364
+ {
365
+ line : 1 ,
366
+ column : 3 ,
367
+ } ,
368
+ ] ,
369
+ path : [ 'scalarList' ] ,
370
+ } ,
371
+ ] ,
372
+ data : {
373
+ scalarList : null ,
374
+ } ,
375
+ } ) ;
376
+ } ) ;
377
+ it ( 'maxInterval values less than zero throw field errors' , async ( ) => {
378
+ const document = parse ( '{ scalarList @stream(maxInterval: -1) }' ) ;
379
+ const result = await complete ( document ) ;
380
+ expectJSON ( result ) . toDeepEqual ( {
381
+ errors : [
382
+ {
383
+ message :
384
+ 'maxInterval must be an integer greater than or equal to zero' ,
315
385
locations : [
316
386
{
317
387
line : 1 ,
@@ -460,27 +530,36 @@ describe('Execute: stream directive', () => {
460
530
hasNext : true ,
461
531
} ,
462
532
{
463
- data : {
464
- name : 'Han' ,
465
- id : '2' ,
466
- } ,
467
- path : [ 'asyncSlowList' , 1 ] ,
533
+ data : [
534
+ {
535
+ name : 'Han' ,
536
+ id : '2' ,
537
+ } ,
538
+ ] ,
539
+ path : [ 'asyncSlowList' ] ,
540
+ atIndices : [ 1 ] ,
468
541
hasNext : true ,
469
542
} ,
470
543
{
471
- data : {
472
- name : 'Leia' ,
473
- id : '3' ,
474
- } ,
475
- path : [ 'asyncSlowList' , 2 ] ,
544
+ data : [
545
+ {
546
+ name : 'Leia' ,
547
+ id : '3' ,
548
+ } ,
549
+ ] ,
550
+ path : [ 'asyncSlowList' ] ,
551
+ atIndices : [ 2 ] ,
476
552
hasNext : true ,
477
553
} ,
478
554
{
479
- data : {
480
- name : 'Luke' ,
481
- id : '1' ,
482
- } ,
483
- path : [ 'asyncSlowList' , 0 ] ,
555
+ data : [
556
+ {
557
+ name : 'Luke' ,
558
+ id : '1' ,
559
+ } ,
560
+ ] ,
561
+ path : [ 'asyncSlowList' ] ,
562
+ atIndices : [ 0 ] ,
484
563
hasNext : false ,
485
564
} ,
486
565
] ) ;
@@ -622,6 +701,51 @@ describe('Execute: stream directive', () => {
622
701
} ,
623
702
] ) ;
624
703
} ) ;
704
+ it ( 'Can stream a field that returns an async iterable in chunks of size greater than 1' , async ( ) => {
705
+ const document = parse ( `
706
+ query {
707
+ asyncIterableList @stream(maxChunkSize: 2) {
708
+ name
709
+ id
710
+ }
711
+ }
712
+ ` ) ;
713
+ const result = await complete ( document ) ;
714
+ expect ( result ) . to . deep . equal ( [
715
+ {
716
+ data : {
717
+ asyncIterableList : [ ] ,
718
+ } ,
719
+ hasNext : true ,
720
+ } ,
721
+ {
722
+ data : [
723
+ {
724
+ name : 'Luke' ,
725
+ id : '1' ,
726
+ } ,
727
+ {
728
+ name : 'Han' ,
729
+ id : '2' ,
730
+ } ,
731
+ ] ,
732
+ path : [ 'asyncIterableList' ] ,
733
+ atIndex : 0 ,
734
+ hasNext : true ,
735
+ } ,
736
+ {
737
+ data : [
738
+ {
739
+ name : 'Leia' ,
740
+ id : '3' ,
741
+ } ,
742
+ ] ,
743
+ path : [ 'asyncIterableList' ] ,
744
+ atIndex : 2 ,
745
+ hasNext : false ,
746
+ } ,
747
+ ] ) ;
748
+ } ) ;
625
749
it ( 'Can stream a field that returns an async iterable, using a non-zero initialCount' , async ( ) => {
626
750
const document = parse ( `
627
751
query {
@@ -700,7 +824,8 @@ describe('Execute: stream directive', () => {
700
824
expectJSON ( result ) . toDeepEqual ( {
701
825
errors : [
702
826
{
703
- message : 'initialCount must be a positive integer' ,
827
+ message :
828
+ 'initialCount must be an integer greater than or equal to zero' ,
704
829
locations : [
705
830
{
706
831
line : 3 ,
@@ -930,10 +1055,10 @@ describe('Execute: stream directive', () => {
930
1055
} ,
931
1056
] ) ;
932
1057
} ) ;
933
- it ( 'Handles null returned in non-null async iterable list items after initialCount is reached with parallel streaming ' , async ( ) => {
1058
+ it ( 'Handles null returned in non-null async iterable list items after initialCount is reached with maxChunkSize greater than 1 ' , async ( ) => {
934
1059
const document = parse ( `
935
1060
query {
936
- asyncIterableNonNullError @stream(initialCount: 0, inParallel: true ) {
1061
+ asyncIterableNonNullError @stream(initialCount: 0, maxChunkSize: 2 ) {
937
1062
name
938
1063
}
939
1064
}
@@ -947,15 +1072,19 @@ describe('Execute: stream directive', () => {
947
1072
hasNext : true ,
948
1073
} ,
949
1074
{
950
- data : {
951
- name : 'Luke' ,
952
- } ,
953
- path : [ 'asyncIterableNonNullError' , 0 ] ,
1075
+ data : [
1076
+ {
1077
+ name : 'Luke' ,
1078
+ } ,
1079
+ ] ,
1080
+ path : [ 'asyncIterableNonNullError' ] ,
1081
+ atIndex : 0 ,
954
1082
hasNext : true ,
955
1083
} ,
956
1084
{
957
1085
data : null ,
958
- path : [ 'asyncIterableNonNullError' , 1 ] ,
1086
+ path : [ 'asyncIterableNonNullError' ] ,
1087
+ atIndex : 1 ,
959
1088
errors : [
960
1089
{
961
1090
message :
@@ -971,11 +1100,71 @@ describe('Execute: stream directive', () => {
971
1100
] ,
972
1101
hasNext : true ,
973
1102
} ,
1103
+ {
1104
+ data : [
1105
+ {
1106
+ name : 'Han' ,
1107
+ } ,
1108
+ ] ,
1109
+ path : [ 'asyncIterableNonNullError' ] ,
1110
+ atIndex : 2 ,
1111
+ hasNext : false ,
1112
+ } ,
1113
+ ] ) ;
1114
+ } ) ;
1115
+ it ( 'Handles null returned in non-null async iterable list items after initialCount is reached with parallel streaming' , async ( ) => {
1116
+ const document = parse ( `
1117
+ query {
1118
+ asyncIterableNonNullError @stream(initialCount: 0, inParallel: true) {
1119
+ name
1120
+ }
1121
+ }
1122
+ ` ) ;
1123
+ const result = await complete ( document ) ;
1124
+ expectJSON ( result ) . toDeepEqual ( [
974
1125
{
975
1126
data : {
976
- name : 'Han' ,
1127
+ asyncIterableNonNullError : [ ] ,
977
1128
} ,
978
- path : [ 'asyncIterableNonNullError' , 2 ] ,
1129
+ hasNext : true ,
1130
+ } ,
1131
+ {
1132
+ data : [
1133
+ {
1134
+ name : 'Luke' ,
1135
+ } ,
1136
+ ] ,
1137
+ path : [ 'asyncIterableNonNullError' ] ,
1138
+ atIndices : [ 0 ] ,
1139
+ hasNext : true ,
1140
+ } ,
1141
+ {
1142
+ data : null ,
1143
+ path : [ 'asyncIterableNonNullError' ] ,
1144
+ atIndices : [ 1 ] ,
1145
+ errors : [
1146
+ {
1147
+ message :
1148
+ 'Cannot return null for non-nullable field Query.asyncIterableNonNullError.' ,
1149
+ locations : [
1150
+ {
1151
+ line : 3 ,
1152
+ column : 9 ,
1153
+ } ,
1154
+ ] ,
1155
+ path : [ 'asyncIterableNonNullError' , 1 ] ,
1156
+ } ,
1157
+ ] ,
1158
+ hasNext : true ,
1159
+ } ,
1160
+ {
1161
+ data : [
1162
+ {
1163
+ name : 'Han' ,
1164
+ } ,
1165
+ ] ,
1166
+ path : [ 'asyncIterableNonNullError' ] ,
1167
+ atIndices : [ 2 ] ,
979
1168
hasNext : false ,
980
1169
} ,
981
1170
] ) ;
0 commit comments