diff --git a/src/Experimental/Executor/CoroutineExecutor.php b/src/Experimental/Executor/CoroutineExecutor.php index d985633..91091b4 100644 --- a/src/Experimental/Executor/CoroutineExecutor.php +++ b/src/Experimental/Executor/CoroutineExecutor.php @@ -293,13 +293,17 @@ class CoroutineExecutor implements Runtime, ExecutorImplementation $strand->stack[$strand->depth++] = $strand->current; $strand->current = $value; goto START; - } elseif ($this->promiseAdapter->isThenable($value)) { + } elseif ($this->isPromise($value)) { // !!! increment pending before calling ->then() as it may invoke the callback right away ++$this->pending; + if (! $value instanceof Promise) { + $value = $this->promiseAdapter->convertThenable($value); + } + $this->promiseAdapter - ->convertThenable($value) ->then( + $value, function ($value) use ($strand) { $strand->success = true; $strand->value = $value; @@ -478,7 +482,7 @@ class CoroutineExecutor implements Runtime, ExecutorImplementation private function completeValueFast(CoroutineContext $ctx, Type $type, $value, array $path, &$returnValue) : bool { // special handling of Throwable inherited from JS reference implementation, but makes no sense in this PHP - if ($this->promiseAdapter->isThenable($value) || $value instanceof Throwable) { + if ($this->isPromise($value) || $value instanceof Throwable) { return false; } @@ -574,7 +578,7 @@ class CoroutineExecutor implements Runtime, ExecutorImplementation // !!! $value might be promise, yield to resolve try { - if ($this->promiseAdapter->isThenable($value)) { + if ($this->isPromise($value)) { $value = yield $value; } } catch (Throwable $reason) { @@ -931,4 +935,14 @@ class CoroutineExecutor implements Runtime, ExecutorImplementation return $selectedType; } + + /** + * @param mixed $value + * + * @return bool + */ + private function isPromise($value) + { + return $value instanceof Promise || $this->promiseAdapter->isThenable($value); + } } diff --git a/tests/GraphQLTest.php b/tests/GraphQLTest.php index 9617e9e..13193b5 100644 --- a/tests/GraphQLTest.php +++ b/tests/GraphQLTest.php @@ -42,6 +42,6 @@ class GraphQLTest extends TestCase $promise = GraphQL::promiseToExecute($promiseAdapter, $schema, '{ sayHi(name: "John") }'); $result = $promiseAdapter->wait($promise); - $this->assertSame(['data' => ['sayHi' => 'Hi John!']], $result->toArray()); + self::assertSame(['data' => ['sayHi' => 'Hi John!']], $result->toArray()); } }