2016-12-29 21:09:49 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Amp\Test;
|
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
use Amp\Loop;
|
2017-03-28 01:37:55 +02:00
|
|
|
use React\Promise\RejectedPromise as RejectedReactPromise;
|
2017-03-11 06:40:30 +01:00
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
class Promise implements \Amp\Promise
|
|
|
|
{
|
2016-12-29 21:09:49 +01:00
|
|
|
use \Amp\Internal\Placeholder {
|
|
|
|
resolve as public;
|
|
|
|
fail as public;
|
|
|
|
}
|
|
|
|
}
|
2017-03-11 06:40:30 +01:00
|
|
|
|
2019-05-14 21:37:08 +02:00
|
|
|
class PromiseTest extends BaseTest
|
2018-06-18 20:00:01 +02:00
|
|
|
{
|
2017-01-07 11:49:38 +01:00
|
|
|
private $originalErrorHandler;
|
2016-12-29 21:09:49 +01:00
|
|
|
|
2016-10-24 17:08:08 +02:00
|
|
|
/**
|
2017-03-12 17:05:52 +01:00
|
|
|
* A Promise to use for a test with resolution methods.
|
2018-06-18 20:00:01 +02:00
|
|
|
* Note that the callables shall take care of the Promise being resolved in any case. Example: The actual
|
|
|
|
* implementation delays resolution to the next loop tick. The callables then must run one tick of the loop in
|
|
|
|
* order to ensure resolution.
|
2016-10-24 17:08:08 +02:00
|
|
|
*
|
2018-06-18 20:00:01 +02:00
|
|
|
* @return array(Promise, callable, callable) where the last two callables are resolving the Promise with a result
|
|
|
|
* or a Throwable/Exception respectively
|
2016-10-24 17:08:08 +02:00
|
|
|
*/
|
2018-06-18 20:00:01 +02:00
|
|
|
public function promise()
|
|
|
|
{
|
2016-12-29 21:09:49 +01:00
|
|
|
$promise = new Promise;
|
|
|
|
return [
|
|
|
|
$promise,
|
|
|
|
[$promise, 'resolve'],
|
|
|
|
[$promise, 'fail'],
|
|
|
|
];
|
|
|
|
}
|
2017-01-07 14:24:21 +01:00
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function provideSuccessValues()
|
|
|
|
{
|
2016-10-24 17:08:08 +02:00
|
|
|
return [
|
|
|
|
["string"],
|
|
|
|
[0],
|
2016-12-30 21:29:21 +01:00
|
|
|
[~PHP_INT_MAX],
|
2016-10-24 17:08:08 +02:00
|
|
|
[-1.0],
|
|
|
|
[true],
|
|
|
|
[false],
|
|
|
|
[[]],
|
|
|
|
[null],
|
|
|
|
[new \StdClass],
|
2017-01-07 11:50:21 +01:00
|
|
|
[new \Exception],
|
2016-10-24 17:08:08 +02:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testPromiseImplementsPromise()
|
|
|
|
{
|
2017-01-07 14:28:01 +01:00
|
|
|
list($promise) = $this->promise();
|
|
|
|
$this->assertInstanceOf(Promise::class, $promise);
|
|
|
|
}
|
|
|
|
|
2016-10-24 17:08:08 +02:00
|
|
|
/** @dataProvider provideSuccessValues */
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testPromiseSucceed($value)
|
|
|
|
{
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, $succeeder) = $this->promise();
|
2017-04-24 15:39:08 +02:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked, $value) {
|
|
|
|
$this->assertNull($e);
|
2016-10-24 17:08:08 +02:00
|
|
|
$this->assertSame($value, $v);
|
|
|
|
$invoked = true;
|
|
|
|
});
|
|
|
|
$succeeder($value);
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** @dataProvider provideSuccessValues */
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testOnResolveOnSucceededPromise($value)
|
|
|
|
{
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, $succeeder) = $this->promise();
|
2016-10-24 17:08:08 +02:00
|
|
|
$succeeder($value);
|
2017-04-24 15:39:08 +02:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked, $value) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
2016-10-24 17:08:08 +02:00
|
|
|
$this->assertSame($value, $v);
|
|
|
|
$invoked = true;
|
|
|
|
});
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
2017-01-07 11:47:58 +01:00
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testSuccessAllOnResolvesExecuted()
|
|
|
|
{
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, $succeeder) = $this->promise();
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked = 0;
|
2017-01-07 11:47:58 +01:00
|
|
|
|
2017-04-24 15:39:08 +02:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
|
|
|
$this->assertTrue($v);
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked++;
|
|
|
|
});
|
2017-04-24 15:39:08 +02:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
|
|
|
$this->assertTrue($v);
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked++;
|
|
|
|
});
|
|
|
|
|
|
|
|
$succeeder(true);
|
|
|
|
|
2017-04-24 15:39:08 +02:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
|
|
|
$this->assertTrue($v);
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked++;
|
|
|
|
});
|
2017-04-24 15:39:08 +02:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
|
|
|
$this->assertTrue($v);
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked++;
|
|
|
|
});
|
2017-01-07 11:47:58 +01:00
|
|
|
|
2016-10-24 17:08:08 +02:00
|
|
|
$this->assertSame(4, $invoked);
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testPromiseExceptionFailure()
|
|
|
|
{
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, , $failer) = $this->promise();
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertSame(\get_class($e), "RuntimeException");
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked = true;
|
|
|
|
});
|
|
|
|
$failer(new \RuntimeException);
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testOnResolveOnExceptionFailedPromise()
|
|
|
|
{
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, , $failer) = $this->promise();
|
2016-10-24 17:08:08 +02:00
|
|
|
$failer(new \RuntimeException);
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertSame(\get_class($e), "RuntimeException");
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked = true;
|
|
|
|
});
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
2017-01-07 11:47:58 +01:00
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testFailureAllOnResolvesExecuted()
|
|
|
|
{
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, , $failer) = $this->promise();
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked = 0;
|
|
|
|
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertSame(\get_class($e), "RuntimeException");
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked++;
|
|
|
|
});
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertSame(\get_class($e), "RuntimeException");
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked++;
|
|
|
|
});
|
|
|
|
|
|
|
|
$failer(new \RuntimeException);
|
|
|
|
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertSame(\get_class($e), "RuntimeException");
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked++;
|
|
|
|
});
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertSame(\get_class($e), "RuntimeException");
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked++;
|
|
|
|
});
|
|
|
|
|
|
|
|
$this->assertSame(4, $invoked);
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testPromiseErrorFailure()
|
|
|
|
{
|
2016-10-24 17:08:08 +02:00
|
|
|
if (PHP_VERSION_ID < 70000) {
|
|
|
|
$this->markTestSkipped("Error only exists on PHP 7+");
|
|
|
|
}
|
|
|
|
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, , $failer) = $this->promise();
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertSame(\get_class($e), "Error");
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked = true;
|
|
|
|
});
|
|
|
|
$failer(new \Error);
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testOnResolveOnErrorFailedPromise()
|
|
|
|
{
|
2016-10-24 17:08:08 +02:00
|
|
|
if (PHP_VERSION_ID < 70000) {
|
|
|
|
$this->markTestSkipped("Error only exists on PHP 7+");
|
|
|
|
}
|
|
|
|
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, , $failer) = $this->promise();
|
2016-10-24 17:08:08 +02:00
|
|
|
$failer(new \Error);
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e) use (&$invoked) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertSame(\get_class($e), "Error");
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked = true;
|
|
|
|
});
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
|
|
|
|
2017-03-12 17:05:52 +01:00
|
|
|
/** Implementations MAY fail upon resolution with a Promise, but they definitely MUST NOT return a Promise */
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testPromiseResolutionWithPromise()
|
|
|
|
{
|
2016-12-23 13:14:11 +01:00
|
|
|
list($success, $succeeder) = $this->promise();
|
2016-10-24 17:08:08 +02:00
|
|
|
$succeeder(true);
|
|
|
|
|
2016-12-23 13:14:11 +01:00
|
|
|
list($promise, $succeeder) = $this->promise();
|
2016-10-24 17:08:08 +02:00
|
|
|
|
|
|
|
$ex = false;
|
|
|
|
try {
|
|
|
|
$succeeder($success);
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
$ex = true;
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
$ex = true;
|
|
|
|
}
|
|
|
|
if (!$ex) {
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked) {
|
2016-10-24 17:08:08 +02:00
|
|
|
$invoked = true;
|
2018-11-12 21:04:12 +01:00
|
|
|
$this->assertNotInstanceOf(Promise::class, $v);
|
2016-10-24 17:08:08 +02:00
|
|
|
});
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testThrowingInCallback()
|
|
|
|
{
|
2017-03-11 06:40:30 +01:00
|
|
|
Loop::run(function () {
|
|
|
|
$invoked = 0;
|
2017-01-07 11:49:38 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
Loop::setErrorHandler(function () use (&$invoked) {
|
|
|
|
$invoked++;
|
|
|
|
});
|
2017-01-07 11:49:38 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
list($promise, $succeeder) = $this->promise();
|
|
|
|
$succeeder(true);
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked, $promise) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
|
|
|
$this->assertTrue($v);
|
2017-03-11 06:40:30 +01:00
|
|
|
$invoked++;
|
2016-10-24 17:08:08 +02:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
throw new \Exception;
|
|
|
|
});
|
2016-12-23 13:14:11 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
list($promise, $succeeder) = $this->promise();
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked, $promise) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
|
|
|
$this->assertTrue($v);
|
2017-03-11 06:40:30 +01:00
|
|
|
$invoked++;
|
2016-12-23 13:14:11 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
throw new \Exception;
|
|
|
|
});
|
|
|
|
$succeeder(true);
|
2016-12-23 13:14:11 +01:00
|
|
|
|
2017-04-24 15:39:08 +02:00
|
|
|
$this->assertSame(4, $invoked);
|
2017-03-11 06:40:30 +01:00
|
|
|
});
|
2017-01-07 11:51:24 +01:00
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testThrowingInCallbackContinuesOtherOnResolves()
|
|
|
|
{
|
2017-03-11 06:40:30 +01:00
|
|
|
Loop::run(function () {
|
|
|
|
$invoked = 0;
|
2017-01-07 11:51:24 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
Loop::setErrorHandler(function () use (&$invoked) {
|
|
|
|
$invoked++;
|
|
|
|
});
|
2017-01-07 11:51:24 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
list($promise, $succeeder) = $this->promise();
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked, $promise) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
|
|
|
$this->assertTrue($v);
|
2017-03-11 06:40:30 +01:00
|
|
|
$invoked++;
|
2017-01-07 11:51:24 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
throw new \Exception;
|
|
|
|
});
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked, $promise) {
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertNull($e);
|
|
|
|
$this->assertTrue($v);
|
2017-03-11 06:40:30 +01:00
|
|
|
$invoked++;
|
|
|
|
});
|
|
|
|
$succeeder(true);
|
2016-12-30 15:37:31 +01:00
|
|
|
|
2017-04-24 15:39:08 +02:00
|
|
|
$this->assertSame(3, $invoked);
|
2017-03-11 06:40:30 +01:00
|
|
|
});
|
2016-10-24 17:08:08 +02:00
|
|
|
}
|
2016-12-29 18:57:42 +01:00
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testThrowingInCallbackOnFailure()
|
|
|
|
{
|
2017-03-11 06:40:30 +01:00
|
|
|
Loop::run(function () {
|
|
|
|
$invoked = 0;
|
|
|
|
Loop::setErrorHandler(function () use (&$invoked) {
|
|
|
|
$invoked++;
|
|
|
|
});
|
2016-12-30 20:53:47 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
list($promise, , $failer) = $this->promise();
|
|
|
|
$exception = new \Exception;
|
|
|
|
$failer($exception);
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked, $exception) {
|
2017-03-11 06:40:30 +01:00
|
|
|
$this->assertSame($exception, $e);
|
|
|
|
$this->assertNull($v);
|
|
|
|
$invoked++;
|
2016-12-30 20:53:47 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
throw $e;
|
|
|
|
});
|
2016-12-30 20:53:47 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
list($promise, , $failer) = $this->promise();
|
|
|
|
$exception = new \Exception;
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function ($e, $v) use (&$invoked, $exception) {
|
2017-03-11 06:40:30 +01:00
|
|
|
$this->assertSame($exception, $e);
|
|
|
|
$this->assertNull($v);
|
|
|
|
$invoked++;
|
2016-12-30 20:53:47 +01:00
|
|
|
|
2017-03-11 06:40:30 +01:00
|
|
|
throw $e;
|
|
|
|
});
|
|
|
|
$failer($exception);
|
2016-12-30 20:53:47 +01:00
|
|
|
|
2017-04-24 15:39:08 +02:00
|
|
|
$this->assertSame(4, $invoked);
|
2017-03-11 06:40:30 +01:00
|
|
|
});
|
2016-12-30 20:53:47 +01:00
|
|
|
}
|
|
|
|
|
2016-12-30 22:11:05 +01:00
|
|
|
/**
|
|
|
|
* @requires PHP 7
|
|
|
|
*/
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testWeakTypes()
|
|
|
|
{
|
2016-12-29 18:57:42 +01:00
|
|
|
$invoked = 0;
|
|
|
|
list($promise, $succeeder) = $this->promise();
|
|
|
|
|
|
|
|
$expectedData = "15.24";
|
|
|
|
|
2017-04-24 15:39:08 +02:00
|
|
|
$promise->onResolve(function ($e, int $v) use (&$invoked, $expectedData) {
|
2016-12-29 18:57:42 +01:00
|
|
|
$invoked++;
|
|
|
|
$this->assertSame((int) $expectedData, $v);
|
|
|
|
});
|
|
|
|
$succeeder($expectedData);
|
2017-04-24 15:39:08 +02:00
|
|
|
$promise->onResolve(function ($e, int $v) use (&$invoked, $expectedData) {
|
2016-12-29 18:57:42 +01:00
|
|
|
$invoked++;
|
|
|
|
$this->assertSame((int) $expectedData, $v);
|
|
|
|
});
|
|
|
|
|
2017-04-24 15:39:08 +02:00
|
|
|
$this->assertSame(2, $invoked);
|
2016-12-29 18:57:42 +01:00
|
|
|
}
|
2017-03-10 22:07:00 +01:00
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testResolvedQueueUnrolling()
|
|
|
|
{
|
2017-01-07 14:24:21 +01:00
|
|
|
$count = 50;
|
|
|
|
$invoked = false;
|
|
|
|
|
|
|
|
$promise = new Promise;
|
2018-06-18 20:00:01 +02:00
|
|
|
$promise->onResolve(function () {
|
|
|
|
});
|
|
|
|
$promise->onResolve(function () {
|
|
|
|
});
|
2017-03-21 17:23:37 +01:00
|
|
|
$promise->onResolve(function () use (&$invoked) {
|
2017-01-07 14:24:21 +01:00
|
|
|
$invoked = true;
|
2017-11-29 13:36:50 +01:00
|
|
|
$this->assertLessThan(30, \count(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)));
|
2017-01-07 14:24:21 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
$last = $promise;
|
|
|
|
|
|
|
|
$f = function () use (&$f, &$count, &$last) {
|
|
|
|
$p = new Promise;
|
2018-06-18 20:00:01 +02:00
|
|
|
$p->onResolve(function () {
|
|
|
|
});
|
|
|
|
$p->onResolve(function () {
|
|
|
|
});
|
2017-01-07 14:24:21 +01:00
|
|
|
|
|
|
|
$last->resolve($p);
|
|
|
|
$last = $p;
|
|
|
|
|
|
|
|
if (--$count > 0) {
|
|
|
|
$f();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
$f();
|
|
|
|
$last->resolve();
|
|
|
|
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
2017-03-28 01:37:55 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \Exception
|
|
|
|
* @expectedExceptionMessage Success
|
|
|
|
*/
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testOnResolveWithReactPromise()
|
|
|
|
{
|
2017-03-28 01:37:55 +02:00
|
|
|
Loop::run(function () {
|
|
|
|
$promise = new Promise;
|
|
|
|
$promise->onResolve(function ($exception, $value) {
|
|
|
|
return new RejectedReactPromise(new \Exception("Success"));
|
|
|
|
});
|
|
|
|
$promise->resolve();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testOnResolveWithReactPromise
|
|
|
|
* @expectedException \Exception
|
|
|
|
* @expectedExceptionMessage Success
|
|
|
|
*/
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testOnResolveWithReactPromiseAfterResolve()
|
|
|
|
{
|
2017-03-28 01:37:55 +02:00
|
|
|
Loop::run(function () {
|
|
|
|
$promise = new Promise;
|
|
|
|
$promise->resolve();
|
|
|
|
$promise->onResolve(function ($exception, $value) {
|
|
|
|
return new RejectedReactPromise(new \Exception("Success"));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testOnResolveWithGenerator()
|
|
|
|
{
|
2017-03-28 01:37:55 +02:00
|
|
|
$promise = new Promise;
|
|
|
|
$invoked = false;
|
|
|
|
$promise->onResolve(function ($exception, $value) use (&$invoked) {
|
|
|
|
$invoked = true;
|
|
|
|
return $value;
|
|
|
|
yield; // Unreachable, but makes function a generator.
|
|
|
|
});
|
|
|
|
|
|
|
|
$promise->resolve(1);
|
|
|
|
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @depends testOnResolveWithGenerator
|
|
|
|
*/
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testOnResolveWithGeneratorAfterResolve()
|
|
|
|
{
|
2017-03-28 01:37:55 +02:00
|
|
|
$promise = new Promise;
|
|
|
|
$invoked = false;
|
|
|
|
$promise->resolve(1);
|
|
|
|
$promise->onResolve(function ($exception, $value) use (&$invoked) {
|
|
|
|
$invoked = true;
|
|
|
|
return $value;
|
|
|
|
yield; // Unreachable, but makes function a generator.
|
|
|
|
});
|
|
|
|
|
|
|
|
$this->assertTrue($invoked);
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:00:01 +02:00
|
|
|
public function testOnResolveWithGeneratorWithMultipleCallbacks()
|
|
|
|
{
|
2017-03-28 01:37:55 +02:00
|
|
|
$promise = new Promise;
|
|
|
|
$invoked = 0;
|
|
|
|
$callback = function ($exception, $value) use (&$invoked) {
|
|
|
|
++$invoked;
|
|
|
|
return $value;
|
|
|
|
yield; // Unreachable, but makes function a generator.
|
|
|
|
};
|
|
|
|
|
|
|
|
$promise->onResolve($callback);
|
|
|
|
$promise->onResolve($callback);
|
|
|
|
$promise->onResolve($callback);
|
|
|
|
|
|
|
|
$promise->resolve(1);
|
|
|
|
|
|
|
|
$this->assertSame(3, $invoked);
|
|
|
|
}
|
2017-04-24 15:39:08 +02:00
|
|
|
}
|