@@ -2,6 +2,9 @@ import { expect } from 'chai';
22import { describe , it } from 'mocha' ;
33
44import { parse } from '../../language/parser' ;
5+ import { GraphQLList , GraphQLObjectType } from '../../type/definition' ;
6+ import { GraphQLString } from '../../type/scalars' ;
7+ import { GraphQLSchema } from '../../type/schema' ;
58
69import { buildSchema } from '../../utilities/buildASTSchema' ;
710
@@ -64,6 +67,125 @@ describe('Execute: Accepts any iterable as list value', () => {
6467 } ) ;
6568} ) ;
6669
70+ describe ( 'Execute: Accepts async iterables as list value' , ( ) => {
71+ function complete ( rootValue : mixed ) {
72+ return execute ( {
73+ schema : buildSchema ( 'type Query { listField: [String] }' ) ,
74+ document : parse ( '{ listField }' ) ,
75+ rootValue,
76+ } ) ;
77+ }
78+
79+ function completeObjectList ( resolve ) {
80+ const schema = new GraphQLSchema ( {
81+ query : new GraphQLObjectType ( {
82+ name : 'Query' ,
83+ fields : {
84+ listField : {
85+ resolve : async function * listField ( ) {
86+ yield await { index : 0 } ;
87+ yield await { index : 1 } ;
88+ yield await { index : 2 } ;
89+ } ,
90+ type : new GraphQLList (
91+ new GraphQLObjectType ( {
92+ name : 'ObjectWrapper' ,
93+ fields : {
94+ index : {
95+ type : GraphQLString ,
96+ resolve,
97+ } ,
98+ } ,
99+ } ) ,
100+ ) ,
101+ } ,
102+ } ,
103+ } ) ,
104+ } ) ;
105+ return execute ( {
106+ schema,
107+ document : parse ( '{ listField { index } }' ) ,
108+ } ) ;
109+ }
110+
111+ it ( 'Accepts an AsyncGenerator function as a List value' , async ( ) => {
112+ async function * listField ( ) {
113+ yield await 'two' ;
114+ yield await 4 ;
115+ yield await false ;
116+ }
117+
118+ expect ( await complete ( { listField } ) ) . to . deep . equal ( {
119+ data : { listField : [ 'two' , '4' , 'false' ] } ,
120+ } ) ;
121+ } ) ;
122+
123+ it ( 'Handles an AsyncGenerator function that throws' , async ( ) => {
124+ async function * listField ( ) {
125+ yield await 'two' ;
126+ yield await 4 ;
127+ throw new Error ( 'bad' ) ;
128+ }
129+
130+ expect ( await complete ( { listField } ) ) . to . deep . equal ( {
131+ data : { listField : [ 'two' , '4' , null ] } ,
132+ errors : [
133+ {
134+ message : 'bad' ,
135+ locations : [ { line : 1 , column : 3 } ] ,
136+ path : [ 'listField' , 2 ] ,
137+ } ,
138+ ] ,
139+ } ) ;
140+ } ) ;
141+
142+ it ( 'Handles errors from `completeValue` in AsyncIterables' , async ( ) => {
143+ async function * listField ( ) {
144+ yield await 'two' ;
145+ yield await { } ;
146+ }
147+
148+ expect ( await complete ( { listField } ) ) . to . deep . equal ( {
149+ data : { listField : [ 'two' , null ] } ,
150+ errors : [
151+ {
152+ message : 'String cannot represent value: {}' ,
153+ locations : [ { line : 1 , column : 3 } ] ,
154+ path : [ 'listField' , 1 ] ,
155+ } ,
156+ ] ,
157+ } ) ;
158+ } ) ;
159+
160+ it ( 'Handles promises from `completeValue` in AsyncIterables' , async ( ) => {
161+ expect (
162+ await completeObjectList ( ( { index } ) => Promise . resolve ( index ) ) ,
163+ ) . to . deep . equal ( {
164+ data : { listField : [ { index : '0' } , { index : '1' } , { index : '2' } ] } ,
165+ } ) ;
166+ } ) ;
167+
168+ it ( 'Handles rejected promises from `completeValue` in AsyncIterables' , async ( ) => {
169+ expect (
170+ await completeObjectList ( ( { index } ) => {
171+ if ( index === 2 ) {
172+ return Promise . reject ( new Error ( 'bad' ) ) ;
173+ }
174+ return Promise . resolve ( index ) ;
175+ } ) ,
176+ ) . to . deep . equal ( {
177+ data : { listField : [ { index : '0' } , { index : '1' } , { index : null } ] } ,
178+ errors : [
179+ {
180+ message : 'bad' ,
181+ locations : [ { line : 1 , column : 15 } ] ,
182+ path : [ 'listField' , 2 , 'index' ] ,
183+ } ,
184+ ] ,
185+ } ) ;
186+ } ) ;
187+ } ) ;
188+
67189describe ( 'Execute: Handles list nullability' , ( ) => {
68190 async function complete ( args : { | listField : mixed , as : string | } ) {
69191 const { listField, as } = args ;
0 commit comments