Skip to content

Commit 176e8bd

Browse files
committed
Add NonNull Promise tests
1 parent 7da0fdf commit 176e8bd

File tree

2 files changed

+235
-14
lines changed

2 files changed

+235
-14
lines changed

src/Executor/Executor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public static function execute(Schema $schema, DocumentNode $ast, $rootValue = n
128128
$exeContext->addError($error);
129129
return null;
130130
})->then(function ($data) use ($exeContext) {
131-
return new ExecutionResult((array)$data, $exeContext->errors);
131+
return new ExecutionResult((array) $data, $exeContext->errors);
132132
});
133133
}
134134
} catch (Error $e) {

tests/Executor/NonNullTest.php

Lines changed: 234 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use GraphQL\Error\FormattedError;
77
use GraphQL\Language\Parser;
88
use GraphQL\Language\SourceLocation;
9-
use GraphQL\Executor\Promise\Adapter\GenericPromiseAdapter;
109
use GraphQL\Executor\Promise\Adapter\ReactPromiseAdapter;
1110
use GraphQL\Schema;
1211
use GraphQL\Type\Definition\ObjectType;
@@ -126,6 +125,10 @@ public function setUp()
126125
]);
127126

128127
$this->schema = new Schema(['query' => $dataType]);
128+
}
129+
130+
public function tearDown()
131+
{
129132
Executor::setPromiseAdapter(null);
130133
}
131134

@@ -473,9 +476,8 @@ public function testNullsANullableFieldThatReturnsNullInAPromise()
473476
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
474477
}
475478

476-
public function test4()
479+
public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatReturnsNullSynchronously()
477480
{
478-
// nulls a synchronously returned object that contains a non-nullable field that returns null synchronously
479481
$doc = '
480482
query Q {
481483
nest {
@@ -497,19 +499,107 @@ public function test4()
497499
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray());
498500
}
499501

500-
public function test5()
502+
public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatReturnsNullInAPromise()
503+
{
504+
$doc = '
505+
query Q {
506+
nest {
507+
nonNullPromise,
508+
}
509+
}
510+
';
511+
512+
$ast = Parser::parse($doc);
513+
514+
$expected = [
515+
'data' => [
516+
'nest' => null,
517+
],
518+
'errors' => [
519+
FormattedError::create('Cannot return null for non-nullable field DataType.nonNullPromise.', [new SourceLocation(4, 11)]),
520+
]
521+
];
522+
523+
Executor::setPromiseAdapter(new ReactPromiseAdapter());
524+
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
525+
}
526+
527+
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatReturnsNullSynchronously()
501528
{
502-
// nulls a complex tree of nullable fields that return null
529+
$doc = '
530+
query Q {
531+
promiseNest {
532+
nonNullSync,
533+
}
534+
}
535+
';
536+
537+
$ast = Parser::parse($doc);
538+
539+
$expected = [
540+
'data' => [
541+
'promiseNest' => null,
542+
],
543+
'errors' => [
544+
FormattedError::create('Cannot return null for non-nullable field DataType.nonNullSync.', [new SourceLocation(4, 11)]),
545+
]
546+
];
503547

548+
Executor::setPromiseAdapter(new ReactPromiseAdapter());
549+
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
550+
}
551+
552+
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatReturnsNullInaAPromise()
553+
{
554+
$doc = '
555+
query Q {
556+
promiseNest {
557+
nonNullPromise,
558+
}
559+
}
560+
';
561+
562+
$ast = Parser::parse($doc);
563+
564+
$expected = [
565+
'data' => [
566+
'promiseNest' => null,
567+
],
568+
'errors' => [
569+
FormattedError::create('Cannot return null for non-nullable field DataType.nonNullPromise.', [new SourceLocation(4, 11)]),
570+
]
571+
];
572+
573+
Executor::setPromiseAdapter(new ReactPromiseAdapter());
574+
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
575+
}
576+
577+
public function testNullsAComplexTreeOfNullableFieldsThatReturnNull()
578+
{
504579
$doc = '
505580
query Q {
506581
nest {
507582
sync
583+
promise
508584
nest {
509585
sync
510-
nest {
511-
sync
512-
}
586+
promise
587+
}
588+
promiseNest {
589+
sync
590+
promise
591+
}
592+
}
593+
promiseNest {
594+
sync
595+
promise
596+
nest {
597+
sync
598+
promise
599+
}
600+
promiseNest {
601+
sync
602+
promise
513603
}
514604
}
515605
}
@@ -521,16 +611,107 @@ public function test5()
521611
'data' => [
522612
'nest' => [
523613
'sync' => null,
614+
'promise' => null,
524615
'nest' => [
525616
'sync' => null,
526-
'nest' => [
527-
'sync' => null
528-
]
617+
'promise' => null,
529618
],
619+
'promiseNest' => [
620+
'sync' => null,
621+
'promise' => null,
622+
]
530623
],
624+
'promiseNest' => [
625+
'sync' => null,
626+
'promise' => null,
627+
'nest' => [
628+
'sync' => null,
629+
'promise' => null,
630+
],
631+
'promiseNest' => [
632+
'sync' => null,
633+
'promise' => null,
634+
]
635+
]
531636
]
532637
];
533-
$this->assertEquals($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray());
638+
639+
Executor::setPromiseAdapter(new ReactPromiseAdapter());
640+
Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->then(function ($actual) use ($expected) {
641+
$this->assertEquals($expected, $actual);
642+
});
643+
}
644+
645+
public function testNullsTheFirstNullableObjectAfterAFieldReturnsNullInALongChainOfFieldsThatAreNonNull()
646+
{
647+
$doc = '
648+
query Q {
649+
nest {
650+
nonNullNest {
651+
nonNullPromiseNest {
652+
nonNullNest {
653+
nonNullPromiseNest {
654+
nonNullSync
655+
}
656+
}
657+
}
658+
}
659+
}
660+
promiseNest {
661+
nonNullNest {
662+
nonNullPromiseNest {
663+
nonNullNest {
664+
nonNullPromiseNest {
665+
nonNullSync
666+
}
667+
}
668+
}
669+
}
670+
}
671+
anotherNest: nest {
672+
nonNullNest {
673+
nonNullPromiseNest {
674+
nonNullNest {
675+
nonNullPromiseNest {
676+
nonNullPromise
677+
}
678+
}
679+
}
680+
}
681+
}
682+
anotherPromiseNest: promiseNest {
683+
nonNullNest {
684+
nonNullPromiseNest {
685+
nonNullNest {
686+
nonNullPromiseNest {
687+
nonNullPromise
688+
}
689+
}
690+
}
691+
}
692+
}
693+
}
694+
';
695+
696+
$ast = Parser::parse($doc);
697+
698+
$expected = [
699+
'data' => [
700+
'nest' => null,
701+
'promiseNest' => null,
702+
'anotherNest' => null,
703+
'anotherPromiseNest' => null,
704+
],
705+
'errors' => [
706+
FormattedError::create('Cannot return null for non-nullable field DataType.nonNullSync.', [new SourceLocation(8, 19)]),
707+
FormattedError::create('Cannot return null for non-nullable field DataType.nonNullSync.', [new SourceLocation(19, 19)]),
708+
FormattedError::create('Cannot return null for non-nullable field DataType.nonNullPromise.', [new SourceLocation(30, 19)]),
709+
FormattedError::create('Cannot return null for non-nullable field DataType.nonNullPromise.', [new SourceLocation(41, 19)]),
710+
]
711+
];
712+
713+
Executor::setPromiseAdapter(new ReactPromiseAdapter());
714+
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
534715
}
535716

536717
public function testNullsTheTopLevelIfSyncNonNullableFieldThrows()
@@ -540,11 +721,32 @@ public function testNullsTheTopLevelIfSyncNonNullableFieldThrows()
540721
';
541722

542723
$expected = [
724+
'data' => null,
543725
'errors' => [
544726
FormattedError::create($this->nonNullSyncError->getMessage(), [new SourceLocation(2, 17)])
545727
]
546728
];
547-
$this->assertArraySubset($expected, Executor::execute($this->schema, Parser::parse($doc), $this->throwingData)->toArray());
729+
$actual = Executor::execute($this->schema, Parser::parse($doc), $this->throwingData)->toArray();
730+
$this->assertArraySubset($expected, $actual);
731+
}
732+
733+
public function testNullsTheTopLevelIfAsyncNonNullableFieldErrors()
734+
{
735+
$doc = '
736+
query Q { nonNullPromise }
737+
';
738+
739+
$ast = Parser::parse($doc);
740+
741+
$expected = [
742+
'data' => null,
743+
'errors' => [
744+
FormattedError::create($this->nonNullPromiseError->getMessage(), [new SourceLocation(2, 17)]),
745+
]
746+
];
747+
748+
Executor::setPromiseAdapter(new ReactPromiseAdapter());
749+
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q'));
548750
}
549751

550752
public function testNullsTheTopLevelIfSyncNonNullableFieldReturnsNull()
@@ -562,6 +764,25 @@ public function testNullsTheTopLevelIfSyncNonNullableFieldReturnsNull()
562764
$this->assertArraySubset($expected, Executor::execute($this->schema, Parser::parse($doc), $this->nullingData)->toArray());
563765
}
564766

767+
public function testNullsTheTopLevelIfAsyncNonNullableFieldResolvesNull()
768+
{
769+
$doc = '
770+
query Q { nonNullPromise }
771+
';
772+
773+
$ast = Parser::parse($doc);
774+
775+
$expected = [
776+
'data' => null,
777+
'errors' => [
778+
FormattedError::create('Cannot return null for non-nullable field DataType.nonNullPromise.', [new SourceLocation(2, 17)]),
779+
]
780+
];
781+
782+
Executor::setPromiseAdapter(new ReactPromiseAdapter());
783+
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
784+
}
785+
565786
private function assertArraySubsetPromise($subset, PromiseInterface $promise)
566787
{
567788
$array = null;

0 commit comments

Comments
 (0)