Skip to content

Commit 84a9e2c

Browse files
authored
Support react/promise v3
1 parent 9dbc47a commit 84a9e2c

File tree

6 files changed

+46
-14
lines changed

6 files changed

+46
-14
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ You can find and compare releases at the [GitHub release page](https://github.co
99

1010
## Unreleased
1111

12+
## v15.9.0
13+
14+
### Added
15+
16+
- Support `react/promise` v3 https://github.com/webonyx/graphql-php/pull/1517
17+
1218
## v15.8.1
1319

1420
### Fixed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"phpunit/phpunit": "^9.5 || ^10",
3030
"psr/http-message": "^1 || ^2",
3131
"react/http": "^1.6",
32-
"react/promise": "^2.9",
32+
"react/promise": "^2.0 || ^3.0",
3333
"rector/rector": "^0.19",
3434
"symfony/polyfill-php81": "^1.23",
3535
"symfony/var-exporter": "^5 || ^6 || ^7",

examples/04-async-php/reactphp/hello-world-http-server/graphql.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
$deferred = new \React\Promise\Deferred();
3535
$promise = $deferred->promise();
3636
$promise = $promise = $promise->then(static fn (): string => $rootValue['prefix'] . $args['message']);
37-
$deferred->resolve();
37+
$deferred->resolve(null);
3838

3939
return $promise;
4040
},

src/Executor/Promise/Promise.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313
class Promise
1414
{
15-
/** @var SyncPromise|ReactPromise|AmpPromise<mixed> */
15+
/** @var SyncPromise|ReactPromise<mixed>|AmpPromise<mixed> */
1616
public $adoptedPromise;
1717

1818
private PromiseAdapter $adapter;

tests/Executor/Promise/AmpPromiseAdapterTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function testIsThenableReturnsTrueWhenAnAmpPromiseIsGiven(): void
4343
self::assertFalse($ampAdapter->isThenable(new \stdClass()));
4444
}
4545

46-
public function testConvertsReactPromisesToGraphQlOnes(): void
46+
public function testConvertsReactPromisesToGraphQLOnes(): void
4747
{
4848
$ampAdapter = new AmpPromiseAdapter();
4949
$ampPromise = new Success(1);

tests/Executor/Promise/ReactPromiseAdapterTest.php

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
use GraphQL\Executor\Promise\Adapter\ReactPromiseAdapter;
66
use PHPUnit\Framework\TestCase;
77
use React\Promise\Deferred;
8-
use React\Promise\FulfilledPromise;
98
use React\Promise\Promise;
109
use React\Promise\Promise as ReactPromise;
11-
use React\Promise\RejectedPromise;
1210

1311
use function React\Promise\reject;
1412
use function React\Promise\resolve;
@@ -18,13 +16,41 @@
1816
*/
1917
final class ReactPromiseAdapterTest extends TestCase
2018
{
19+
/** @var class-string<object> */
20+
private string $classFulfilledPromise;
21+
22+
/** @var class-string<object> */
23+
private string $classRejectedPromise;
24+
25+
public function setUp(): void
26+
{
27+
/** @var class-string<object> $classFulfilledPromise */
28+
$classFulfilledPromise = \class_exists('\React\Promise\FulfilledPromise')
29+
? '\React\Promise\FulfilledPromise'
30+
: '\React\Promise\Internal\FulfilledPromise';
31+
$this->classFulfilledPromise = $classFulfilledPromise;
32+
33+
/** @var class-string<object> $classRejectedPromise */
34+
$classRejectedPromise = \class_exists('\React\Promise\RejectedPromise')
35+
? '\React\Promise\RejectedPromise'
36+
: '\React\Promise\Internal\RejectedPromise';
37+
$this->classRejectedPromise = $classRejectedPromise;
38+
}
39+
2140
public function testIsThenableReturnsTrueWhenAReactPromiseIsGiven(): void
2241
{
42+
/** @var callable $reactPromiseSetRejectionHandler */
43+
$reactPromiseSetRejectionHandler = \function_exists('\React\Promise\set_rejection_handler')
44+
? '\React\Promise\set_rejection_handler'
45+
: fn ($error) => null;
46+
2347
$reactAdapter = new ReactPromiseAdapter();
2448

2549
self::assertTrue($reactAdapter->isThenable(new ReactPromise(static fn () => null)));
26-
self::assertTrue($reactAdapter->isThenable(resolve()));
27-
self::assertTrue($reactAdapter->isThenable(reject()));
50+
self::assertTrue($reactAdapter->isThenable(resolve(null)));
51+
$original = $reactPromiseSetRejectionHandler(fn (\Throwable $reason) => null);
52+
self::assertTrue($reactAdapter->isThenable(reject(new \Exception())));
53+
$reactPromiseSetRejectionHandler($original);
2854
self::assertFalse($reactAdapter->isThenable(static fn () => null));
2955
self::assertFalse($reactAdapter->isThenable(false));
3056
self::assertFalse($reactAdapter->isThenable(true));
@@ -36,14 +62,14 @@ public function testIsThenableReturnsTrueWhenAReactPromiseIsGiven(): void
3662
self::assertFalse($reactAdapter->isThenable(new \stdClass()));
3763
}
3864

39-
public function testConvertsReactPromisesToGraphQlOnes(): void
65+
public function testConvertsReactPromisesToGraphQLOnes(): void
4066
{
4167
$reactAdapter = new ReactPromiseAdapter();
4268
$reactPromise = resolve(1);
4369

4470
$promise = $reactAdapter->convertThenable($reactPromise);
4571

46-
self::assertInstanceOf(FulfilledPromise::class, $promise->adoptedPromise);
72+
self::assertInstanceOf($this->classFulfilledPromise, $promise->adoptedPromise);
4773
}
4874

4975
public function testThen(): void
@@ -61,7 +87,7 @@ static function ($value) use (&$result): void {
6187
);
6288

6389
self::assertSame(1, $result);
64-
self::assertInstanceOf(FulfilledPromise::class, $resultPromise->adoptedPromise);
90+
self::assertInstanceOf($this->classFulfilledPromise, $resultPromise->adoptedPromise);
6591
}
6692

6793
public function testCreate(): void
@@ -86,7 +112,7 @@ public function testCreateFulfilled(): void
86112
$reactAdapter = new ReactPromiseAdapter();
87113
$fulfilledPromise = $reactAdapter->createFulfilled(1);
88114

89-
self::assertInstanceOf(FulfilledPromise::class, $fulfilledPromise->adoptedPromise);
115+
self::assertInstanceOf($this->classFulfilledPromise, $fulfilledPromise->adoptedPromise);
90116

91117
$result = null;
92118
$fulfilledPromise->then(static function ($value) use (&$result): void {
@@ -101,7 +127,7 @@ public function testCreateRejected(): void
101127
$reactAdapter = new ReactPromiseAdapter();
102128
$rejectedPromise = $reactAdapter->createRejected(new \Exception('I am a bad promise'));
103129

104-
self::assertInstanceOf(RejectedPromise::class, $rejectedPromise->adoptedPromise);
130+
self::assertInstanceOf($this->classRejectedPromise, $rejectedPromise->adoptedPromise);
105131

106132
$exception = null;
107133
$rejectedPromise->then(
@@ -122,7 +148,7 @@ public function testAll(): void
122148

123149
$allPromise = $reactAdapter->all($promises);
124150

125-
self::assertInstanceOf(FulfilledPromise::class, $allPromise->adoptedPromise);
151+
self::assertInstanceOf($this->classFulfilledPromise, $allPromise->adoptedPromise);
126152

127153
$result = null;
128154
$allPromise->then(static function ($values) use (&$result): void {

0 commit comments

Comments
 (0)