@@ -2,6 +2,11 @@ import { describe, it } from 'mocha';
22
33import { expectJSON } from '../../__testUtils__/expectJSON.js' ;
44
5+ import { invariant } from '../../jsutils/invariant.js' ;
6+ import { isPromise } from '../../jsutils/isPromise.js' ;
7+ import type { ObjMap } from '../../jsutils/ObjMap.js' ;
8+
9+ import type { DocumentNode } from '../../language/ast.js' ;
510import { Kind } from '../../language/kinds.js' ;
611import { parse } from '../../language/parser.js' ;
712
@@ -10,14 +15,52 @@ import { GraphQLString } from '../../type/scalars.js';
1015import { GraphQLSchema } from '../../type/schema.js' ;
1116
1217import { legacyExecuteIncrementally } from '../legacyExecuteIncrementally.js' ;
18+ import type {
19+ LegacyInitialIncrementalExecutionResult ,
20+ LegacySubsequentIncrementalExecutionResult ,
21+ } from '../transformResult.js' ;
22+
23+ const someObjectType = new GraphQLObjectType ( {
24+ name : 'SomeObject' ,
25+ fields : {
26+ someField : { type : GraphQLString } ,
27+ anotherField : { type : GraphQLString } ,
28+ nonNullableField : { type : new GraphQLNonNull ( GraphQLString ) } ,
29+ } ,
30+ } ) ;
1331
1432const schema = new GraphQLSchema ( {
1533 query : new GraphQLObjectType ( {
1634 name : 'Query' ,
17- fields : { someField : { type : new GraphQLNonNull ( GraphQLString ) } } ,
35+ fields : {
36+ someField : { type : new GraphQLNonNull ( GraphQLString ) } ,
37+ someObjectField : { type : someObjectType } ,
38+ } ,
1839 } ) ,
1940} ) ;
2041
42+ async function complete ( document : DocumentNode , rootValue : ObjMap < unknown > ) {
43+ const result = legacyExecuteIncrementally ( {
44+ schema,
45+ document,
46+ rootValue,
47+ } ) ;
48+
49+ invariant ( ! isPromise ( result ) ) ;
50+
51+ if ( 'initialResult' in result ) {
52+ const results : Array <
53+ | LegacyInitialIncrementalExecutionResult
54+ | LegacySubsequentIncrementalExecutionResult
55+ > = [ result . initialResult ] ;
56+ for await ( const patch of result . subsequentResults ) {
57+ results . push ( patch ) ;
58+ }
59+ return results ;
60+ }
61+ return result ;
62+ }
63+
2164describe ( 'legacyExecuteIncrementally' , ( ) => {
2265 it ( 'handles invalid document' , ( ) => {
2366 const result = legacyExecuteIncrementally ( {
@@ -52,4 +95,49 @@ describe('legacyExecuteIncrementally', () => {
5295 ] ,
5396 } ) ;
5497 } ) ;
98+
99+ it ( 'handles null-bubbling from latest format' , async ( ) => {
100+ const document = parse ( `
101+ query {
102+ someObjectField {
103+ ... @defer { someField anotherField }
104+ ... @defer { someField nonNullableField }
105+ }
106+ }
107+ ` ) ;
108+ const result = await complete ( document , {
109+ someObjectField : {
110+ someField : 'someField' ,
111+ anotherField : 'anotherField' ,
112+ nonNullableField : null ,
113+ } ,
114+ } ) ;
115+ expectJSON ( result ) . toDeepEqual ( [
116+ {
117+ data : { someObjectField : { } } ,
118+ hasNext : true ,
119+ } ,
120+ {
121+ incremental : [
122+ {
123+ data : { someField : 'someField' , anotherField : 'anotherField' } ,
124+ path : [ 'someObjectField' ] ,
125+ } ,
126+ {
127+ data : null ,
128+ errors : [
129+ {
130+ message :
131+ 'Cannot return null for non-nullable field SomeObject.nonNullableField.' ,
132+ locations : [ { line : 5 , column : 11 } ] ,
133+ path : [ 'someObjectField' , 'nonNullableField' ] ,
134+ } ,
135+ ] ,
136+ path : [ 'someObjectField' ] ,
137+ } ,
138+ ] ,
139+ hasNext : false ,
140+ } ,
141+ ] ) ;
142+ } ) ;
55143} ) ;
0 commit comments