1
1
<?php
2
+
2
3
namespace GraphQL \Tests \Executor ;
3
4
4
- use GraphQL \ Error \ Error ;
5
+
5
6
use GraphQL \Executor \Executor ;
6
7
use GraphQL \Error \FormattedError ;
7
8
use GraphQL \Language \Parser ;
8
9
use GraphQL \Language \SourceLocation ;
10
+ use GraphQL \Promise \Adapter \ReactPromiseAdapter ;
9
11
use GraphQL \Schema ;
10
12
use GraphQL \Type \Definition \ObjectType ;
11
13
use GraphQL \Type \Definition \Type ;
14
+ use React \Promise \Promise ;
15
+ use React \Promise \PromiseInterface ;
12
16
13
17
class NonNullTest extends \PHPUnit_Framework_TestCase
14
18
{
@@ -17,6 +21,13 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
17
21
18
22
/** @var \Exception */
19
23
public $ nonNullSyncError ;
24
+
25
+ /** @var \Exception */
26
+ public $ promiseError ;
27
+
28
+ /** @var \Exception */
29
+ public $ nonNullPromiseError ;
30
+
20
31
public $ throwingData ;
21
32
public $ nullingData ;
22
33
public $ schema ;
@@ -25,6 +36,8 @@ public function setUp()
25
36
{
26
37
$ this ->syncError = new \Exception ('sync ' );
27
38
$ this ->nonNullSyncError = new \Exception ('nonNullSync ' );
39
+ $ this ->promiseError = new \Exception ('promise ' );
40
+ $ this ->nonNullPromiseError = new \Exception ('nonNullPromise ' );
28
41
29
42
$ this ->throwingData = [
30
43
'sync ' => function () {
@@ -33,12 +46,32 @@ public function setUp()
33
46
'nonNullSync ' => function () {
34
47
throw $ this ->nonNullSyncError ;
35
48
},
49
+ 'promise ' => function () {
50
+ return new Promise (function () {
51
+ throw $ this ->promiseError ;
52
+ });
53
+ },
54
+ 'nonNullPromise ' => function () {
55
+ return new Promise (function () {
56
+ throw $ this ->nonNullPromiseError ;
57
+ });
58
+ },
36
59
'nest ' => function () {
37
60
return $ this ->throwingData ;
38
61
},
39
62
'nonNullNest ' => function () {
40
63
return $ this ->throwingData ;
41
64
},
65
+ 'promiseNest ' => function () {
66
+ return new Promise (function (callable $ resolve ) {
67
+ $ resolve ($ this ->throwingData );
68
+ });
69
+ },
70
+ 'nonNullPromiseNest ' => function () {
71
+ return new Promise (function (callable $ resolve ) {
72
+ $ resolve ($ this ->throwingData );
73
+ });
74
+ },
42
75
];
43
76
44
77
$ this ->nullingData = [
@@ -48,12 +81,32 @@ public function setUp()
48
81
'nonNullSync ' => function () {
49
82
return null ;
50
83
},
84
+ 'promise ' => function () {
85
+ return new Promise (function (callable $ resolve ) {
86
+ return $ resolve (null );
87
+ });
88
+ },
89
+ 'nonNullPromise ' => function () {
90
+ return new Promise (function (callable $ resolve ) {
91
+ return $ resolve (null );
92
+ });
93
+ },
51
94
'nest ' => function () {
52
95
return $ this ->nullingData ;
53
96
},
54
97
'nonNullNest ' => function () {
55
98
return $ this ->nullingData ;
56
99
},
100
+ 'promiseNest ' => function () {
101
+ return new Promise (function (callable $ resolve ) {
102
+ $ resolve ($ this ->nullingData );
103
+ });
104
+ },
105
+ 'nonNullPromiseNest ' => function () {
106
+ return new Promise (function (callable $ resolve ) {
107
+ $ resolve ($ this ->nullingData );
108
+ });
109
+ },
57
110
];
58
111
59
112
$ dataType = new ObjectType ([
@@ -62,13 +115,18 @@ public function setUp()
62
115
return [
63
116
'sync ' => ['type ' => Type::string ()],
64
117
'nonNullSync ' => ['type ' => Type::nonNull (Type::string ())],
118
+ 'promise ' => Type::string (),
119
+ 'nonNullPromise ' => Type::nonNull (Type::string ()),
65
120
'nest ' => $ dataType ,
66
- 'nonNullNest ' => Type::nonNull ($ dataType )
121
+ 'nonNullNest ' => Type::nonNull ($ dataType ),
122
+ 'promiseNest ' => $ dataType ,
123
+ 'nonNullPromiseNest ' => Type::nonNull ($ dataType ),
67
124
];
68
125
}
69
126
]);
70
127
71
128
$ this ->schema = new Schema (['query ' => $ dataType ]);
129
+ Executor::setPromiseAdapter (null );
72
130
}
73
131
74
132
// Execute: handles non-nullable types
@@ -100,6 +158,32 @@ public function testNullsANullableFieldThatThrowsSynchronously()
100
158
$ this ->assertArraySubset ($ expected , Executor::execute ($ this ->schema , $ ast , $ this ->throwingData , null , [], 'Q ' )->toArray ());
101
159
}
102
160
161
+ public function testNullsANullableFieldThatThrowsInAPromise ()
162
+ {
163
+ $ doc = '
164
+ query Q {
165
+ promise
166
+ }
167
+ ' ;
168
+
169
+ $ ast = Parser::parse ($ doc );
170
+
171
+ $ expected = [
172
+ 'data ' => [
173
+ 'promise ' => null ,
174
+ ],
175
+ 'errors ' => [
176
+ FormattedError::create (
177
+ $ this ->promiseError ->getMessage (),
178
+ [new SourceLocation (3 , 9 )]
179
+ )
180
+ ]
181
+ ];
182
+
183
+ Executor::setPromiseAdapter (new ReactPromiseAdapter ());
184
+ $ this ->assertArraySubsetPromise ($ expected , Executor::execute ($ this ->schema , $ ast , $ this ->throwingData , null , [], 'Q ' ));
185
+ }
186
+
103
187
public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatThrowsSynchronously ()
104
188
{
105
189
// nulls a synchronously returned object that contains a non-nullable field that throws synchronously
@@ -124,6 +208,31 @@ public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFie
124
208
$ this ->assertArraySubset ($ expected , Executor::execute ($ this ->schema , $ ast , $ this ->throwingData , null , [], 'Q ' )->toArray ());
125
209
}
126
210
211
+ public function testNullsAsynchronouslyReturnedObjectThatContainsANonNullableFieldThatThrowsInAPromise ()
212
+ {
213
+ $ doc = '
214
+ query Q {
215
+ nest {
216
+ nonNullPromise,
217
+ }
218
+ }
219
+ ' ;
220
+
221
+ $ ast = Parser::parse ($ doc );
222
+
223
+ $ expected = [
224
+ 'data ' => [
225
+ 'nest ' => null
226
+ ],
227
+ 'errors ' => [
228
+ FormattedError::create ($ this ->nonNullPromiseError ->getMessage (), [new SourceLocation (4 , 11 )])
229
+ ]
230
+ ];
231
+
232
+ Executor::setPromiseAdapter (new ReactPromiseAdapter ());
233
+ $ this ->assertArraySubsetPromise ($ expected , Executor::execute ($ this ->schema , $ ast , $ this ->throwingData , null , [], 'Q ' ));
234
+ }
235
+
127
236
public function testNullsAComplexTreeOfNullableFieldsThatThrow ()
128
237
{
129
238
$ doc = '
@@ -262,4 +371,14 @@ public function testNullsTheTopLevelIfSyncNonNullableFieldReturnsNull()
262
371
];
263
372
$ this ->assertArraySubset ($ expected , Executor::execute ($ this ->schema , Parser::parse ($ doc ), $ this ->nullingData )->toArray ());
264
373
}
374
+
375
+ private function assertArraySubsetPromise ($ subset , PromiseInterface $ promise )
376
+ {
377
+ $ array = null ;
378
+ $ promise ->then (function ($ value ) use (&$ array ) {
379
+ $ array = $ value ;
380
+ });
381
+
382
+ $ this ->assertArraySubset ($ subset , $ array );
383
+ }
265
384
}
0 commit comments