mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-02-06 07:49:24 +03:00
Execution: tests are green
This commit is contained in:
parent
ab4ae779af
commit
7ab75cd05a
@ -677,15 +677,7 @@ class Executor
|
|||||||
$this->exeContext->variableValues
|
$this->exeContext->variableValues
|
||||||
);
|
);
|
||||||
|
|
||||||
$value = call_user_func($resolveFn, $source, $args, $context, $info);
|
return call_user_func($resolveFn, $source, $args, $context, $info);
|
||||||
|
|
||||||
// Adopt promises from external system:
|
|
||||||
if ($this->promises->isThenable($value)) {
|
|
||||||
$value = $this->promises->convert($value);
|
|
||||||
Utils::invariant($value instanceof Promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
} catch (\Exception $error) {
|
} catch (\Exception $error) {
|
||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
@ -827,6 +819,11 @@ class Executor
|
|||||||
&$result
|
&$result
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if ($this->promises->isThenable($result)) {
|
||||||
|
$result = $this->promises->convert($result);
|
||||||
|
Utils::invariant($result instanceof Promise);
|
||||||
|
}
|
||||||
|
|
||||||
// If result is a Promise, apply-lift over completeValue.
|
// If result is a Promise, apply-lift over completeValue.
|
||||||
if ($result instanceof Promise) {
|
if ($result instanceof Promise) {
|
||||||
return $result->then(function (&$resolved) use ($returnType, $fieldNodes, $info, $path) {
|
return $result->then(function (&$resolved) use ($returnType, $fieldNodes, $info, $path) {
|
||||||
|
@ -36,9 +36,18 @@ class SyncPromise
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function runNext()
|
||||||
|
{
|
||||||
|
$q = self::getQueue();
|
||||||
|
if (!$q->isEmpty()) {
|
||||||
|
$task = $q->dequeue();
|
||||||
|
$task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public $state = self::PENDING;
|
public $state = self::PENDING;
|
||||||
|
|
||||||
private $result;
|
public $result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Promises created in `then` method of this promise and awaiting for resolution of this promise
|
* Promises created in `then` method of this promise and awaiting for resolution of this promise
|
||||||
|
@ -53,10 +53,14 @@ class SyncPromiseAdapter implements PromiseAdapter
|
|||||||
{
|
{
|
||||||
$promise = new SyncPromise();
|
$promise = new SyncPromise();
|
||||||
|
|
||||||
$resolver(
|
try {
|
||||||
[$promise, 'resolve'],
|
$resolver(
|
||||||
[$promise, 'reject']
|
[$promise, 'resolve'],
|
||||||
);
|
[$promise, 'reject']
|
||||||
|
);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$promise->reject($e);
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise($promise, $this);
|
return new Promise($promise, $this);
|
||||||
}
|
}
|
||||||
@ -115,32 +119,26 @@ class SyncPromiseAdapter implements PromiseAdapter
|
|||||||
|
|
||||||
public function wait(Promise $promise)
|
public function wait(Promise $promise)
|
||||||
{
|
{
|
||||||
$fulfilledValue = null;
|
$dfdQueue = Deferred::getQueue();
|
||||||
$rejectedReason = null;
|
$promiseQueue = SyncPromise::getQueue();
|
||||||
|
|
||||||
$promise->then(
|
|
||||||
function ($value) use (&$fulfilledValue) {
|
|
||||||
$fulfilledValue = $value;
|
|
||||||
},
|
|
||||||
function ($reason) use (&$rejectedReason) {
|
|
||||||
$rejectedReason = $reason;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
while (
|
while (
|
||||||
$promise->adoptedPromise->state === SyncPromise::PENDING &&
|
$promise->adoptedPromise->state === SyncPromise::PENDING &&
|
||||||
!(Deferred::getQueue()->isEmpty() && SyncPromise::getQueue()->isEmpty())
|
!($dfdQueue->isEmpty() && $promiseQueue->isEmpty())
|
||||||
) {
|
) {
|
||||||
Deferred::runQueue();
|
Deferred::runQueue();
|
||||||
SyncPromise::runQueue();
|
SyncPromise::runNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($promise->adoptedPromise->state === SyncPromise::PENDING) {
|
/** @var SyncPromise $syncPromise */
|
||||||
throw new InvariantViolation("Could not resolve promise");
|
$syncPromise = $promise->adoptedPromise;
|
||||||
|
|
||||||
|
if ($syncPromise->state === SyncPromise::FULFILLED) {
|
||||||
|
return $syncPromise->result;
|
||||||
|
} else if ($syncPromise->state === SyncPromise::REJECTED) {
|
||||||
|
throw $syncPromise->result;
|
||||||
}
|
}
|
||||||
if ($rejectedReason instanceof \Exception) {
|
|
||||||
throw $rejectedReason;
|
throw new InvariantViolation("Could not resolve promise");
|
||||||
}
|
|
||||||
return $fulfilledValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace GraphQL;
|
namespace GraphQL;
|
||||||
|
|
||||||
use GraphQL\Error\Error;
|
use GraphQL\Error\Error;
|
||||||
|
use GraphQL\Error\InvariantViolation;
|
||||||
use GraphQL\Executor\ExecutionResult;
|
use GraphQL\Executor\ExecutionResult;
|
||||||
use GraphQL\Executor\Executor;
|
use GraphQL\Executor\Executor;
|
||||||
use GraphQL\Executor\Promise\Promise;
|
use GraphQL\Executor\Promise\Promise;
|
||||||
@ -30,13 +31,12 @@ class GraphQL
|
|||||||
if ($result instanceof ExecutionResult) {
|
if ($result instanceof ExecutionResult) {
|
||||||
return $result->toArray();
|
return $result->toArray();
|
||||||
}
|
}
|
||||||
|
if ($result instanceof Promise) {
|
||||||
return Executor::getPromiseAdapter()->then(
|
return $result->then(function(ExecutionResult $executionResult) {
|
||||||
$result,
|
|
||||||
function(ExecutionResult $executionResult) {
|
|
||||||
return $executionResult->toArray();
|
return $executionResult->toArray();
|
||||||
}
|
});
|
||||||
);
|
}
|
||||||
|
throw new InvariantViolation("Unexpected execution result");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
namespace GraphQL\Tests\Executor;
|
namespace GraphQL\Tests\Executor;
|
||||||
|
|
||||||
use GraphQL\Executor\ExecutionResult;
|
use GraphQL\Deferred;
|
||||||
use GraphQL\Executor\Executor;
|
use GraphQL\Executor\Executor;
|
||||||
use GraphQL\Error\FormattedError;
|
use GraphQL\Error\FormattedError;
|
||||||
use GraphQL\Executor\Promise\Adapter\ReactPromiseAdapter;
|
|
||||||
use GraphQL\Language\Parser;
|
use GraphQL\Language\Parser;
|
||||||
use GraphQL\Language\SourceLocation;
|
use GraphQL\Language\SourceLocation;
|
||||||
use GraphQL\Schema;
|
use GraphQL\Schema;
|
||||||
@ -14,16 +13,6 @@ use GraphQL\Type\Definition\Type;
|
|||||||
|
|
||||||
class ListsTest extends \PHPUnit_Framework_TestCase
|
class ListsTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public static function setUpBeforeClass()
|
|
||||||
{
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function tearDownAfterClass()
|
|
||||||
{
|
|
||||||
Executor::setPromiseAdapter(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Describe: Execute: Handles list nullability
|
// Describe: Execute: Handles list nullability
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,26 +46,34 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
// Contains values
|
// Contains values
|
||||||
$this->checkHandlesNullableLists(
|
$this->checkHandlesNullableLists(
|
||||||
\React\Promise\resolve([ 1, 2 ]),
|
new Deferred(function() {
|
||||||
|
return [1,2];
|
||||||
|
}),
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Contains null
|
// Contains null
|
||||||
$this->checkHandlesNullableLists(
|
$this->checkHandlesNullableLists(
|
||||||
\React\Promise\resolve([ 1, null, 2 ]),
|
new Deferred(function() {
|
||||||
|
return [1, null, 2];
|
||||||
|
}),
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, null, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, null, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Returns null
|
// Returns null
|
||||||
$this->checkHandlesNullableLists(
|
$this->checkHandlesNullableLists(
|
||||||
\React\Promise\resolve(null),
|
new Deferred(function() {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
[ 'data' => [ 'nest' => [ 'test' => null ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => null ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rejected
|
// Rejected
|
||||||
$this->checkHandlesNullableLists(
|
$this->checkHandlesNullableLists(
|
||||||
function () {
|
function () {
|
||||||
return \React\Promise\reject(new \Exception('bad'));
|
return new Deferred(function () {
|
||||||
|
throw new \Exception('bad');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
'data' => ['nest' => ['test' => null]],
|
'data' => ['nest' => ['test' => null]],
|
||||||
@ -98,13 +95,23 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
// Contains values
|
// Contains values
|
||||||
$this->checkHandlesNullableLists(
|
$this->checkHandlesNullableLists(
|
||||||
[ \React\Promise\resolve(1), \React\Promise\resolve(2) ],
|
[
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})],
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Contains null
|
// Contains null
|
||||||
$this->checkHandlesNullableLists(
|
$this->checkHandlesNullableLists(
|
||||||
[ \React\Promise\resolve(1), \React\Promise\resolve(null), \React\Promise\resolve(2) ],
|
[
|
||||||
|
new Deferred(function() {return 1;}),
|
||||||
|
new Deferred(function() {return null;}),
|
||||||
|
new Deferred(function() {return 2;})
|
||||||
|
],
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, null, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, null, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -117,7 +124,17 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
// Contains reject
|
// Contains reject
|
||||||
$this->checkHandlesNullableLists(
|
$this->checkHandlesNullableLists(
|
||||||
function () {
|
function () {
|
||||||
return [ \React\Promise\resolve(1), \React\Promise\reject(new \Exception('bad')), \React\Promise\resolve(2) ];
|
return [
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
throw new \Exception('bad');
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
];
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
'data' => ['nest' => ['test' => [1, null, 2]]],
|
'data' => ['nest' => ['test' => [1, null, 2]]],
|
||||||
@ -171,13 +188,17 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
// Contains values
|
// Contains values
|
||||||
$this->checkHandlesNonNullableLists(
|
$this->checkHandlesNonNullableLists(
|
||||||
\React\Promise\resolve([ 1, 2 ]),
|
new Deferred(function() {
|
||||||
|
return [1,2];
|
||||||
|
}),
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Contains null
|
// Contains null
|
||||||
$this->checkHandlesNonNullableLists(
|
$this->checkHandlesNonNullableLists(
|
||||||
\React\Promise\resolve([ 1, null, 2 ]),
|
new Deferred(function() {
|
||||||
|
return [1, null, 2];
|
||||||
|
}),
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, null, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, null, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -198,7 +219,9 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
// Rejected
|
// Rejected
|
||||||
$this->checkHandlesNonNullableLists(
|
$this->checkHandlesNonNullableLists(
|
||||||
function () {
|
function () {
|
||||||
return \React\Promise\reject(new \Exception('bad'));
|
return new Deferred(function() {
|
||||||
|
throw new \Exception('bad');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
'data' => ['nest' => null],
|
'data' => ['nest' => null],
|
||||||
@ -220,20 +243,47 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
// Contains values
|
// Contains values
|
||||||
$this->checkHandlesNonNullableLists(
|
$this->checkHandlesNonNullableLists(
|
||||||
[ \React\Promise\resolve(1), \React\Promise\resolve(2) ],
|
[
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
],
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Contains null
|
// Contains null
|
||||||
$this->checkHandlesNonNullableLists(
|
$this->checkHandlesNonNullableLists(
|
||||||
[ \React\Promise\resolve(1), \React\Promise\resolve(null), \React\Promise\resolve(2) ],
|
[
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
],
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, null, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, null, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Contains reject
|
// Contains reject
|
||||||
$this->checkHandlesNonNullableLists(
|
$this->checkHandlesNonNullableLists(
|
||||||
function () {
|
function () {
|
||||||
return [ \React\Promise\resolve(1), \React\Promise\reject(new \Exception('bad')), \React\Promise\resolve(2) ];
|
return [
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
throw new \Exception('bad');
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
];
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
'data' => ['nest' => ['test' => [1, null, 2]]],
|
'data' => ['nest' => ['test' => [1, null, 2]]],
|
||||||
@ -287,13 +337,17 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
// Contains values
|
// Contains values
|
||||||
$this->checkHandlesListOfNonNulls(
|
$this->checkHandlesListOfNonNulls(
|
||||||
\React\Promise\resolve([ 1, 2 ]),
|
new Deferred(function() {
|
||||||
|
return [1, 2];
|
||||||
|
}),
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Contains null
|
// Contains null
|
||||||
$this->checkHandlesListOfNonNulls(
|
$this->checkHandlesListOfNonNulls(
|
||||||
\React\Promise\resolve([ 1, null, 2 ]),
|
new Deferred(function() {
|
||||||
|
return [1, null, 2];
|
||||||
|
}),
|
||||||
[
|
[
|
||||||
'data' => [ 'nest' => [ 'test' => null ] ],
|
'data' => [ 'nest' => [ 'test' => null ] ],
|
||||||
'errors' => [
|
'errors' => [
|
||||||
@ -314,7 +368,9 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
// Rejected
|
// Rejected
|
||||||
$this->checkHandlesListOfNonNulls(
|
$this->checkHandlesListOfNonNulls(
|
||||||
function () {
|
function () {
|
||||||
return \React\Promise\reject(new \Exception('bad'));
|
return new Deferred(function() {
|
||||||
|
throw new \Exception('bad');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
'data' => ['nest' => ['test' => null]],
|
'data' => ['nest' => ['test' => null]],
|
||||||
@ -336,7 +392,14 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
// Contains values
|
// Contains values
|
||||||
$this->checkHandlesListOfNonNulls(
|
$this->checkHandlesListOfNonNulls(
|
||||||
[ \React\Promise\resolve(1), \React\Promise\resolve(2) ],
|
[
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
],
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -349,7 +412,17 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
// Contains reject
|
// Contains reject
|
||||||
$this->checkHandlesListOfNonNulls(
|
$this->checkHandlesListOfNonNulls(
|
||||||
function () {
|
function () {
|
||||||
return [ \React\Promise\resolve(1), \React\Promise\reject(new \Exception('bad')), \React\Promise\resolve(2) ];
|
return [
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
throw new \Exception('bad');
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
];
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
'data' => ['nest' => ['test' => null]],
|
'data' => ['nest' => ['test' => null]],
|
||||||
@ -412,13 +485,17 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
// Contains values
|
// Contains values
|
||||||
$this->checkHandlesNonNullListOfNonNulls(
|
$this->checkHandlesNonNullListOfNonNulls(
|
||||||
\React\Promise\resolve([ 1, 2 ]),
|
new Deferred(function() {
|
||||||
|
return [1, 2];
|
||||||
|
}),
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Contains null
|
// Contains null
|
||||||
$this->checkHandlesNonNullListOfNonNulls(
|
$this->checkHandlesNonNullListOfNonNulls(
|
||||||
\React\Promise\resolve([ 1, null, 2 ]),
|
new Deferred(function() {
|
||||||
|
return [1, null, 2];
|
||||||
|
}),
|
||||||
[
|
[
|
||||||
'data' => [ 'nest' => null ],
|
'data' => [ 'nest' => null ],
|
||||||
'errors' => [
|
'errors' => [
|
||||||
@ -432,7 +509,9 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
// Returns null
|
// Returns null
|
||||||
$this->checkHandlesNonNullListOfNonNulls(
|
$this->checkHandlesNonNullListOfNonNulls(
|
||||||
\React\Promise\resolve(null),
|
new Deferred(function() {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
[
|
[
|
||||||
'data' => [ 'nest' => null ],
|
'data' => [ 'nest' => null ],
|
||||||
'errors' => [
|
'errors' => [
|
||||||
@ -447,7 +526,9 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
// Rejected
|
// Rejected
|
||||||
$this->checkHandlesNonNullListOfNonNulls(
|
$this->checkHandlesNonNullListOfNonNulls(
|
||||||
function () {
|
function () {
|
||||||
return \React\Promise\reject(new \Exception('bad'));
|
return new Deferred(function() {
|
||||||
|
throw new \Exception('bad');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
'data' => ['nest' => null ],
|
'data' => ['nest' => null ],
|
||||||
@ -469,13 +550,31 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
// Contains values
|
// Contains values
|
||||||
$this->checkHandlesNonNullListOfNonNulls(
|
$this->checkHandlesNonNullListOfNonNulls(
|
||||||
[ \React\Promise\resolve(1), \React\Promise\resolve(2) ],
|
[
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
|
||||||
|
],
|
||||||
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
[ 'data' => [ 'nest' => [ 'test' => [ 1, 2 ] ] ] ]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Contains null
|
// Contains null
|
||||||
$this->checkHandlesNonNullListOfNonNulls(
|
$this->checkHandlesNonNullListOfNonNulls(
|
||||||
[ \React\Promise\resolve(1), \React\Promise\resolve(null), \React\Promise\resolve(2) ],
|
[
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'data' => [ 'nest' => null ],
|
'data' => [ 'nest' => null ],
|
||||||
'errors' => [
|
'errors' => [
|
||||||
@ -490,7 +589,17 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
// Contains reject
|
// Contains reject
|
||||||
$this->checkHandlesNonNullListOfNonNulls(
|
$this->checkHandlesNonNullListOfNonNulls(
|
||||||
function () {
|
function () {
|
||||||
return [ \React\Promise\resolve(1), \React\Promise\reject(new \Exception('bad')), \React\Promise\resolve(2) ];
|
return [
|
||||||
|
new Deferred(function() {
|
||||||
|
return 1;
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
throw new \Exception('bad');
|
||||||
|
}),
|
||||||
|
new Deferred(function() {
|
||||||
|
return 2;
|
||||||
|
})
|
||||||
|
];
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
'data' => ['nest' => null ],
|
'data' => ['nest' => null ],
|
||||||
@ -507,7 +616,7 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
private function checkHandlesNullableLists($testData, $expected)
|
private function checkHandlesNullableLists($testData, $expected)
|
||||||
{
|
{
|
||||||
$testType = Type::listOf(Type::int());;
|
$testType = Type::listOf(Type::int());
|
||||||
$this->check($testType, $testData, $expected);
|
$this->check($testType, $testData, $expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,19 +667,6 @@ class ListsTest extends \PHPUnit_Framework_TestCase
|
|||||||
$ast = Parser::parse('{ nest { test } }');
|
$ast = Parser::parse('{ nest { test } }');
|
||||||
|
|
||||||
$result = Executor::execute($schema, $ast, $data);
|
$result = Executor::execute($schema, $ast, $data);
|
||||||
$this->assertArraySubset($expected, self::awaitPromise($result));
|
$this->assertArraySubset($expected, $result->toArray());
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \GraphQL\Executor\Promise\Promise $promise
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private static function awaitPromise($promise)
|
|
||||||
{
|
|
||||||
$results = null;
|
|
||||||
$promise->then(function (ExecutionResult $executionResult) use (&$results) {
|
|
||||||
$results = $executionResult->toArray();
|
|
||||||
});
|
|
||||||
return $results;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,14 @@
|
|||||||
|
|
||||||
namespace GraphQL\Tests\Executor;
|
namespace GraphQL\Tests\Executor;
|
||||||
|
|
||||||
|
use GraphQL\Deferred;
|
||||||
use GraphQL\Executor\Executor;
|
use GraphQL\Executor\Executor;
|
||||||
use GraphQL\Error\FormattedError;
|
use GraphQL\Error\FormattedError;
|
||||||
use GraphQL\Language\Parser;
|
use GraphQL\Language\Parser;
|
||||||
use GraphQL\Language\SourceLocation;
|
use GraphQL\Language\SourceLocation;
|
||||||
use GraphQL\Executor\Promise\Adapter\ReactPromiseAdapter;
|
|
||||||
use GraphQL\Schema;
|
use GraphQL\Schema;
|
||||||
use GraphQL\Type\Definition\ObjectType;
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use React\Promise\Promise;
|
|
||||||
use React\Promise\PromiseInterface;
|
|
||||||
|
|
||||||
class NonNullTest extends \PHPUnit_Framework_TestCase
|
class NonNullTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
@ -46,12 +44,12 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
throw $this->nonNullSyncError;
|
throw $this->nonNullSyncError;
|
||||||
},
|
},
|
||||||
'promise' => function () {
|
'promise' => function () {
|
||||||
return new Promise(function () {
|
return new Deferred(function () {
|
||||||
throw $this->promiseError;
|
throw $this->promiseError;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'nonNullPromise' => function () {
|
'nonNullPromise' => function () {
|
||||||
return new Promise(function () {
|
return new Deferred(function () {
|
||||||
throw $this->nonNullPromiseError;
|
throw $this->nonNullPromiseError;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -62,13 +60,13 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
return $this->throwingData;
|
return $this->throwingData;
|
||||||
},
|
},
|
||||||
'promiseNest' => function () {
|
'promiseNest' => function () {
|
||||||
return new Promise(function (callable $resolve) {
|
return new Deferred(function () {
|
||||||
$resolve($this->throwingData);
|
return $this->throwingData;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'nonNullPromiseNest' => function () {
|
'nonNullPromiseNest' => function () {
|
||||||
return new Promise(function (callable $resolve) {
|
return new Deferred(function () {
|
||||||
$resolve($this->throwingData);
|
return $this->throwingData;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -81,13 +79,13 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
'promise' => function () {
|
'promise' => function () {
|
||||||
return new Promise(function (callable $resolve) {
|
return new Deferred(function () {
|
||||||
return $resolve(null);
|
return null;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'nonNullPromise' => function () {
|
'nonNullPromise' => function () {
|
||||||
return new Promise(function (callable $resolve) {
|
return new Deferred(function () {
|
||||||
return $resolve(null);
|
return null;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'nest' => function () {
|
'nest' => function () {
|
||||||
@ -97,13 +95,13 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
return $this->nullingData;
|
return $this->nullingData;
|
||||||
},
|
},
|
||||||
'promiseNest' => function () {
|
'promiseNest' => function () {
|
||||||
return new Promise(function (callable $resolve) {
|
return new Deferred(function () {
|
||||||
$resolve($this->nullingData);
|
return $this->nullingData;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'nonNullPromiseNest' => function () {
|
'nonNullPromiseNest' => function () {
|
||||||
return new Promise(function (callable $resolve) {
|
return new Deferred(function () {
|
||||||
$resolve($this->nullingData);
|
return $this->nullingData;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -127,11 +125,6 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->schema = new Schema(['query' => $dataType]);
|
$this->schema = new Schema(['query' => $dataType]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown()
|
|
||||||
{
|
|
||||||
Executor::setPromiseAdapter(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute: handles non-nullable types
|
// Execute: handles non-nullable types
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -183,8 +176,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatThrowsSynchronously()
|
public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatThrowsSynchronously()
|
||||||
@ -232,8 +224,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatThrowsSynchronously()
|
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatThrowsSynchronously()
|
||||||
@ -257,8 +248,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatThrowsInAPromise()
|
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatThrowsInAPromise()
|
||||||
@ -282,10 +272,12 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @it nulls a complex tree of nullable fields that throw
|
||||||
|
*/
|
||||||
public function testNullsAComplexTreeOfNullableFieldsThatThrow()
|
public function testNullsAComplexTreeOfNullableFieldsThatThrow()
|
||||||
{
|
{
|
||||||
$doc = '
|
$doc = '
|
||||||
@ -348,22 +340,21 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
],
|
],
|
||||||
'errors' => [
|
'errors' => [
|
||||||
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(4, 11)]),
|
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(4, 11)]),
|
||||||
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(5, 11)]),
|
|
||||||
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(7, 13)]),
|
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(7, 13)]),
|
||||||
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(8, 13)]),
|
|
||||||
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(11, 13)]),
|
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(11, 13)]),
|
||||||
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(12, 13)]),
|
|
||||||
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(16, 11)]),
|
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(16, 11)]),
|
||||||
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(17, 11)]),
|
|
||||||
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(19, 13)]),
|
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(19, 13)]),
|
||||||
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(20, 13)]),
|
|
||||||
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(23, 13)]),
|
FormattedError::create($this->syncError->getMessage(), [new SourceLocation(23, 13)]),
|
||||||
|
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(5, 11)]),
|
||||||
|
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(8, 13)]),
|
||||||
|
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(12, 13)]),
|
||||||
|
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(17, 11)]),
|
||||||
|
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(20, 13)]),
|
||||||
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(24, 13)]),
|
FormattedError::create($this->promiseError->getMessage(), [new SourceLocation(24, 13)]),
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfFieldsThatAreNonNull()
|
public function testNullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfFieldsThatAreNonNull()
|
||||||
@ -434,8 +425,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsANullableFieldThatSynchronouslyReturnsNull()
|
public function testNullsANullableFieldThatSynchronouslyReturnsNull()
|
||||||
@ -472,8 +462,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatReturnsNullSynchronously()
|
public function testNullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatReturnsNullSynchronously()
|
||||||
@ -520,8 +509,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatReturnsNullSynchronously()
|
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatReturnsNullSynchronously()
|
||||||
@ -545,8 +533,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatReturnsNullInaAPromise()
|
public function testNullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatReturnsNullInaAPromise()
|
||||||
@ -570,8 +557,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsAComplexTreeOfNullableFieldsThatReturnNull()
|
public function testNullsAComplexTreeOfNullableFieldsThatReturnNull()
|
||||||
@ -636,10 +622,8 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$actual = Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray();
|
||||||
Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->then(function ($actual) use ($expected) {
|
$this->assertEquals($expected, $actual);
|
||||||
$this->assertEquals($expected, $actual);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsTheFirstNullableObjectAfterAFieldReturnsNullInALongChainOfFieldsThatAreNonNull()
|
public function testNullsTheFirstNullableObjectAfterAFieldReturnsNullInALongChainOfFieldsThatAreNonNull()
|
||||||
@ -710,10 +694,12 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @it nulls the top level if sync non-nullable field throws
|
||||||
|
*/
|
||||||
public function testNullsTheTopLevelIfSyncNonNullableFieldThrows()
|
public function testNullsTheTopLevelIfSyncNonNullableFieldThrows()
|
||||||
{
|
{
|
||||||
$doc = '
|
$doc = '
|
||||||
@ -745,8 +731,7 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->throwingData, null, [], 'Q'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullsTheTopLevelIfSyncNonNullableFieldReturnsNull()
|
public function testNullsTheTopLevelIfSyncNonNullableFieldReturnsNull()
|
||||||
@ -779,17 +764,6 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
Executor::setPromiseAdapter(new ReactPromiseAdapter());
|
$this->assertArraySubset($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q')->toArray());
|
||||||
$this->assertArraySubsetPromise($expected, Executor::execute($this->schema, $ast, $this->nullingData, null, [], 'Q'));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function assertArraySubsetPromise($subset, PromiseInterface $promise)
|
|
||||||
{
|
|
||||||
$array = null;
|
|
||||||
$promise->then(function ($value) use (&$array) {
|
|
||||||
$array = $value->toArray();
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->assertArraySubset($subset, $array);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user