Laravel version update
Laravel version update
This commit is contained in:
11
vendor/guzzlehttp/promises/.gitignore
vendored
11
vendor/guzzlehttp/promises/.gitignore
vendored
@@ -1,11 +0,0 @@
|
||||
phpunit.xml
|
||||
composer.phar
|
||||
composer.lock
|
||||
composer-test.lock
|
||||
vendor/
|
||||
build/artifacts/
|
||||
artifacts/
|
||||
docs/_build
|
||||
docs/*.pyc
|
||||
.idea
|
||||
.DS_STORE
|
||||
19
vendor/guzzlehttp/promises/.travis.yml
vendored
19
vendor/guzzlehttp/promises/.travis.yml
vendored
@@ -1,19 +0,0 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
sudo: false
|
||||
|
||||
install:
|
||||
- travis_retry composer install --no-interaction --prefer-source
|
||||
|
||||
script: make test
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
fast_finish: true
|
||||
48
vendor/guzzlehttp/promises/CHANGELOG.md
vendored
48
vendor/guzzlehttp/promises/CHANGELOG.md
vendored
@@ -1,31 +1,65 @@
|
||||
# CHANGELOG
|
||||
|
||||
|
||||
## 1.3.1 - 2016-12-20
|
||||
|
||||
### Fixed
|
||||
|
||||
- `wait()` foreign promise compatibility
|
||||
|
||||
|
||||
## 1.3.0 - 2016-11-18
|
||||
|
||||
### Added
|
||||
|
||||
- Adds support for custom task queues.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed coroutine promise memory leak.
|
||||
|
||||
|
||||
## 1.2.0 - 2016-05-18
|
||||
|
||||
* Update to now catch `\Throwable` on PHP 7+
|
||||
### Changed
|
||||
|
||||
- Update to now catch `\Throwable` on PHP 7+
|
||||
|
||||
|
||||
## 1.1.0 - 2016-03-07
|
||||
|
||||
* Update EachPromise to prevent recurring on a iterator when advancing, as this
|
||||
### Changed
|
||||
|
||||
- Update EachPromise to prevent recurring on a iterator when advancing, as this
|
||||
could trigger fatal generator errors.
|
||||
* Update Promise to allow recursive waiting without unwrapping exceptions.
|
||||
- Update Promise to allow recursive waiting without unwrapping exceptions.
|
||||
|
||||
|
||||
## 1.0.3 - 2015-10-15
|
||||
|
||||
* Update EachPromise to immediately resolve when the underlying promise iterator
|
||||
### Changed
|
||||
|
||||
- Update EachPromise to immediately resolve when the underlying promise iterator
|
||||
is empty. Previously, such a promise would throw an exception when its `wait`
|
||||
function was called.
|
||||
|
||||
|
||||
## 1.0.2 - 2015-05-15
|
||||
|
||||
* Conditionally require functions.php.
|
||||
### Changed
|
||||
|
||||
- Conditionally require functions.php.
|
||||
|
||||
|
||||
## 1.0.1 - 2015-06-24
|
||||
|
||||
* Updating EachPromise to call next on the underlying promise iterator as late
|
||||
### Changed
|
||||
|
||||
- Updating EachPromise to call next on the underlying promise iterator as late
|
||||
as possible to ensure that generators that generate new requests based on
|
||||
callbacks are not iterated until after callbacks are invoked.
|
||||
|
||||
|
||||
## 1.0.0 - 2015-05-12
|
||||
|
||||
* Initial release
|
||||
- Initial release
|
||||
|
||||
2
vendor/guzzlehttp/promises/LICENSE
vendored
2
vendor/guzzlehttp/promises/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
|
||||
Copyright (c) 2015-2016 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
9
vendor/guzzlehttp/promises/README.md
vendored
9
vendor/guzzlehttp/promises/README.md
vendored
@@ -96,7 +96,7 @@ $promise->resolve('reader.');
|
||||
## Promise forwarding
|
||||
|
||||
Promises can be chained one after the other. Each then in the chain is a new
|
||||
promise. The return value of of a promise is what's forwarded to the next
|
||||
promise. The return value of a promise is what's forwarded to the next
|
||||
promise in the chain. Returning a promise in a `then` callback will cause the
|
||||
subsequent promises in the chain to only be fulfilled when the returned promise
|
||||
has been fulfilled. The next promise in the chain will be invoked with the
|
||||
@@ -315,8 +315,11 @@ A promise has the following methods:
|
||||
|
||||
- `then(callable $onFulfilled, callable $onRejected) : PromiseInterface`
|
||||
|
||||
Creates a new promise that is fulfilled or rejected when the promise is
|
||||
resolved.
|
||||
Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.
|
||||
|
||||
- `otherwise(callable $onRejected) : PromiseInterface`
|
||||
|
||||
Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
|
||||
|
||||
- `wait($unwrap = true) : mixed`
|
||||
|
||||
|
||||
9
vendor/guzzlehttp/promises/composer.json
vendored
9
vendor/guzzlehttp/promises/composer.json
vendored
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
"type": "library",
|
||||
"description": "Guzzle promises library",
|
||||
"keywords": ["promise"],
|
||||
"license": "MIT",
|
||||
@@ -15,7 +14,7 @@
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
"phpunit/phpunit": "^4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -23,9 +22,13 @@
|
||||
},
|
||||
"files": ["src/functions_include.php"]
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vendor/bin/phpunit",
|
||||
"test-ci": "vendor/bin/phpunit --coverage-text"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
vendor/guzzlehttp/promises/phpunit.xml.dist
vendored
17
vendor/guzzlehttp/promises/phpunit.xml.dist
vendored
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit bootstrap="./tests/bootstrap.php"
|
||||
colors="true">
|
||||
<testsuites>
|
||||
<testsuite>
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src</directory>
|
||||
<exclude>
|
||||
<directory suffix="Interface.php">src/</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
151
vendor/guzzlehttp/promises/src/Coroutine.php
vendored
Normal file
151
vendor/guzzlehttp/promises/src/Coroutine.php
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
use Exception;
|
||||
use Generator;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Creates a promise that is resolved using a generator that yields values or
|
||||
* promises (somewhat similar to C#'s async keyword).
|
||||
*
|
||||
* When called, the coroutine function will start an instance of the generator
|
||||
* and returns a promise that is fulfilled with its final yielded value.
|
||||
*
|
||||
* Control is returned back to the generator when the yielded promise settles.
|
||||
* This can lead to less verbose code when doing lots of sequential async calls
|
||||
* with minimal processing in between.
|
||||
*
|
||||
* use GuzzleHttp\Promise;
|
||||
*
|
||||
* function createPromise($value) {
|
||||
* return new Promise\FulfilledPromise($value);
|
||||
* }
|
||||
*
|
||||
* $promise = Promise\coroutine(function () {
|
||||
* $value = (yield createPromise('a'));
|
||||
* try {
|
||||
* $value = (yield createPromise($value . 'b'));
|
||||
* } catch (\Exception $e) {
|
||||
* // The promise was rejected.
|
||||
* }
|
||||
* yield $value . 'c';
|
||||
* });
|
||||
*
|
||||
* // Outputs "abc"
|
||||
* $promise->then(function ($v) { echo $v; });
|
||||
*
|
||||
* @param callable $generatorFn Generator function to wrap into a promise.
|
||||
*
|
||||
* @return Promise
|
||||
* @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
|
||||
*/
|
||||
final class Coroutine implements PromiseInterface
|
||||
{
|
||||
/**
|
||||
* @var PromiseInterface|null
|
||||
*/
|
||||
private $currentPromise;
|
||||
|
||||
/**
|
||||
* @var Generator
|
||||
*/
|
||||
private $generator;
|
||||
|
||||
/**
|
||||
* @var Promise
|
||||
*/
|
||||
private $result;
|
||||
|
||||
public function __construct(callable $generatorFn)
|
||||
{
|
||||
$this->generator = $generatorFn();
|
||||
$this->result = new Promise(function () {
|
||||
while (isset($this->currentPromise)) {
|
||||
$this->currentPromise->wait();
|
||||
}
|
||||
});
|
||||
$this->nextCoroutine($this->generator->current());
|
||||
}
|
||||
|
||||
public function then(
|
||||
callable $onFulfilled = null,
|
||||
callable $onRejected = null
|
||||
) {
|
||||
return $this->result->then($onFulfilled, $onRejected);
|
||||
}
|
||||
|
||||
public function otherwise(callable $onRejected)
|
||||
{
|
||||
return $this->result->otherwise($onRejected);
|
||||
}
|
||||
|
||||
public function wait($unwrap = true)
|
||||
{
|
||||
return $this->result->wait($unwrap);
|
||||
}
|
||||
|
||||
public function getState()
|
||||
{
|
||||
return $this->result->getState();
|
||||
}
|
||||
|
||||
public function resolve($value)
|
||||
{
|
||||
$this->result->resolve($value);
|
||||
}
|
||||
|
||||
public function reject($reason)
|
||||
{
|
||||
$this->result->reject($reason);
|
||||
}
|
||||
|
||||
public function cancel()
|
||||
{
|
||||
$this->currentPromise->cancel();
|
||||
$this->result->cancel();
|
||||
}
|
||||
|
||||
private function nextCoroutine($yielded)
|
||||
{
|
||||
$this->currentPromise = promise_for($yielded)
|
||||
->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function _handleSuccess($value)
|
||||
{
|
||||
unset($this->currentPromise);
|
||||
try {
|
||||
$next = $this->generator->send($value);
|
||||
if ($this->generator->valid()) {
|
||||
$this->nextCoroutine($next);
|
||||
} else {
|
||||
$this->result->resolve($value);
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
$this->result->reject($exception);
|
||||
} catch (Throwable $throwable) {
|
||||
$this->result->reject($throwable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function _handleFailure($reason)
|
||||
{
|
||||
unset($this->currentPromise);
|
||||
try {
|
||||
$nextYield = $this->generator->throw(exception_for($reason));
|
||||
// The throw was caught, so keep iterating on the coroutine
|
||||
$this->nextCoroutine($nextYield);
|
||||
} catch (Exception $exception) {
|
||||
$this->result->reject($exception);
|
||||
} catch (Throwable $throwable) {
|
||||
$this->result->reject($throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
vendor/guzzlehttp/promises/src/Promise.php
vendored
13
vendor/guzzlehttp/promises/src/Promise.php
vendored
@@ -263,10 +263,17 @@ class Promise implements PromiseInterface
|
||||
$this->waitList = null;
|
||||
|
||||
foreach ($waitList as $result) {
|
||||
$result->waitIfPending();
|
||||
while ($result->result instanceof Promise) {
|
||||
$result = $result->result;
|
||||
while (true) {
|
||||
$result->waitIfPending();
|
||||
|
||||
if ($result->result instanceof Promise) {
|
||||
$result = $result->result;
|
||||
} else {
|
||||
if ($result->result instanceof PromiseInterface) {
|
||||
$result->result->wait(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
vendor/guzzlehttp/promises/src/TaskQueue.php
vendored
16
vendor/guzzlehttp/promises/src/TaskQueue.php
vendored
@@ -10,7 +10,7 @@ namespace GuzzleHttp\Promise;
|
||||
*
|
||||
* GuzzleHttp\Promise\queue()->run();
|
||||
*/
|
||||
class TaskQueue
|
||||
class TaskQueue implements TaskQueueInterface
|
||||
{
|
||||
private $enableShutdown = true;
|
||||
private $queue = [];
|
||||
@@ -30,30 +30,16 @@ class TaskQueue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the queue is empty.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return !$this->queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a task to the queue that will be executed the next time run is
|
||||
* called.
|
||||
*
|
||||
* @param callable $task
|
||||
*/
|
||||
public function add(callable $task)
|
||||
{
|
||||
$this->queue[] = $task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute all of the pending task in the queue.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
/** @var callable $task */
|
||||
|
||||
25
vendor/guzzlehttp/promises/src/TaskQueueInterface.php
vendored
Normal file
25
vendor/guzzlehttp/promises/src/TaskQueueInterface.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise;
|
||||
|
||||
interface TaskQueueInterface
|
||||
{
|
||||
/**
|
||||
* Returns true if the queue is empty.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty();
|
||||
|
||||
/**
|
||||
* Adds a task to the queue that will be executed the next time run is
|
||||
* called.
|
||||
*
|
||||
* @param callable $task
|
||||
*/
|
||||
public function add(callable $task);
|
||||
|
||||
/**
|
||||
* Execute all of the pending task in the queue.
|
||||
*/
|
||||
public function run();
|
||||
}
|
||||
77
vendor/guzzlehttp/promises/src/functions.php
vendored
77
vendor/guzzlehttp/promises/src/functions.php
vendored
@@ -14,13 +14,17 @@ namespace GuzzleHttp\Promise;
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @return TaskQueue
|
||||
* @param TaskQueueInterface $assign Optionally specify a new queue instance.
|
||||
*
|
||||
* @return TaskQueueInterface
|
||||
*/
|
||||
function queue()
|
||||
function queue(TaskQueueInterface $assign = null)
|
||||
{
|
||||
static $queue;
|
||||
|
||||
if (!$queue) {
|
||||
if ($assign) {
|
||||
$queue = $assign;
|
||||
} elseif (!$queue) {
|
||||
$queue = new TaskQueue();
|
||||
}
|
||||
|
||||
@@ -210,7 +214,7 @@ function unwrap($promises)
|
||||
*
|
||||
* @param mixed $promises Promises or values.
|
||||
*
|
||||
* @return Promise
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
function all($promises)
|
||||
{
|
||||
@@ -243,7 +247,7 @@ function all($promises)
|
||||
* @param int $count Total number of promises.
|
||||
* @param mixed $promises Promises or values.
|
||||
*
|
||||
* @return Promise
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
function some($count, $promises)
|
||||
{
|
||||
@@ -299,7 +303,7 @@ function any($promises)
|
||||
*
|
||||
* @param mixed $promises Promises or values.
|
||||
*
|
||||
* @return Promise
|
||||
* @return PromiseInterface
|
||||
* @see GuzzleHttp\Promise\inspect for the inspection state array format.
|
||||
*/
|
||||
function settle($promises)
|
||||
@@ -337,7 +341,7 @@ function settle($promises)
|
||||
* @param callable $onFulfilled
|
||||
* @param callable $onRejected
|
||||
*
|
||||
* @return Promise
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
function each(
|
||||
$iterable,
|
||||
@@ -363,7 +367,7 @@ function each(
|
||||
* @param callable $onFulfilled
|
||||
* @param callable $onRejected
|
||||
*
|
||||
* @return mixed
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
function each_limit(
|
||||
$iterable,
|
||||
@@ -387,7 +391,7 @@ function each_limit(
|
||||
* @param int|callable $concurrency
|
||||
* @param callable $onFulfilled
|
||||
*
|
||||
* @return mixed
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
function each_limit_all(
|
||||
$iterable,
|
||||
@@ -441,60 +445,13 @@ function is_settled(PromiseInterface $promise)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a promise that is resolved using a generator that yields values or
|
||||
* promises (somewhat similar to C#'s async keyword).
|
||||
* @see Coroutine
|
||||
*
|
||||
* When called, the coroutine function will start an instance of the generator
|
||||
* and returns a promise that is fulfilled with its final yielded value.
|
||||
* @param callable $generatorFn
|
||||
*
|
||||
* Control is returned back to the generator when the yielded promise settles.
|
||||
* This can lead to less verbose code when doing lots of sequential async calls
|
||||
* with minimal processing in between.
|
||||
*
|
||||
* use GuzzleHttp\Promise;
|
||||
*
|
||||
* function createPromise($value) {
|
||||
* return new Promise\FulfilledPromise($value);
|
||||
* }
|
||||
*
|
||||
* $promise = Promise\coroutine(function () {
|
||||
* $value = (yield createPromise('a'));
|
||||
* try {
|
||||
* $value = (yield createPromise($value . 'b'));
|
||||
* } catch (\Exception $e) {
|
||||
* // The promise was rejected.
|
||||
* }
|
||||
* yield $value . 'c';
|
||||
* });
|
||||
*
|
||||
* // Outputs "abc"
|
||||
* $promise->then(function ($v) { echo $v; });
|
||||
*
|
||||
* @param callable $generatorFn Generator function to wrap into a promise.
|
||||
*
|
||||
* @return Promise
|
||||
* @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
function coroutine(callable $generatorFn)
|
||||
{
|
||||
$generator = $generatorFn();
|
||||
return __next_coroutine($generator->current(), $generator)->then();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function __next_coroutine($yielded, \Generator $generator)
|
||||
{
|
||||
return promise_for($yielded)->then(
|
||||
function ($value) use ($generator) {
|
||||
$nextYield = $generator->send($value);
|
||||
return $generator->valid()
|
||||
? __next_coroutine($nextYield, $generator)
|
||||
: $value;
|
||||
},
|
||||
function ($reason) use ($generator) {
|
||||
$nextYield = $generator->throw(exception_for($reason));
|
||||
// The throw was caught, so keep iterating on the coroutine
|
||||
return __next_coroutine($nextYield, $generator);
|
||||
}
|
||||
);
|
||||
return new Coroutine($generatorFn);
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Tests;
|
||||
|
||||
use GuzzleHttp\Promise\AggregateException;
|
||||
|
||||
class AggregateExceptionTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testHasReason()
|
||||
{
|
||||
$e = new AggregateException('foo', ['baz', 'bar']);
|
||||
$this->assertContains('foo', $e->getMessage());
|
||||
$this->assertEquals(['baz', 'bar'], $e->getReason());
|
||||
}
|
||||
}
|
||||
336
vendor/guzzlehttp/promises/tests/EachPromiseTest.php
vendored
336
vendor/guzzlehttp/promises/tests/EachPromiseTest.php
vendored
@@ -1,336 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Tests;
|
||||
|
||||
use GuzzleHttp\Promise\RejectedPromise;
|
||||
use GuzzleHttp\Promise\FulfilledPromise;
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\Promise\EachPromise;
|
||||
use GuzzleHttp\Promise as P;
|
||||
|
||||
/**
|
||||
* @covers GuzzleHttp\Promise\EachPromise
|
||||
*/
|
||||
class EachPromiseTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testReturnsSameInstance()
|
||||
{
|
||||
$each = new EachPromise([], ['concurrency' => 100]);
|
||||
$this->assertSame($each->promise(), $each->promise());
|
||||
}
|
||||
|
||||
public function testInvokesAllPromises()
|
||||
{
|
||||
$promises = [new Promise(), new Promise(), new Promise()];
|
||||
$called = [];
|
||||
$each = new EachPromise($promises, [
|
||||
'fulfilled' => function ($value) use (&$called) {
|
||||
$called[] = $value;
|
||||
}
|
||||
]);
|
||||
$p = $each->promise();
|
||||
$promises[0]->resolve('a');
|
||||
$promises[1]->resolve('c');
|
||||
$promises[2]->resolve('b');
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['a', 'c', 'b'], $called);
|
||||
$this->assertEquals(PromiseInterface::FULFILLED, $p->getState());
|
||||
}
|
||||
|
||||
public function testIsWaitable()
|
||||
{
|
||||
$a = $this->createSelfResolvingPromise('a');
|
||||
$b = $this->createSelfResolvingPromise('b');
|
||||
$called = [];
|
||||
$each = new EachPromise([$a, $b], [
|
||||
'fulfilled' => function ($value) use (&$called) { $called[] = $value; }
|
||||
]);
|
||||
$p = $each->promise();
|
||||
$this->assertNull($p->wait());
|
||||
$this->assertEquals(PromiseInterface::FULFILLED, $p->getState());
|
||||
$this->assertEquals(['a', 'b'], $called);
|
||||
}
|
||||
|
||||
public function testCanResolveBeforeConsumingAll()
|
||||
{
|
||||
$called = 0;
|
||||
$a = $this->createSelfResolvingPromise('a');
|
||||
$b = new Promise(function () { $this->fail(); });
|
||||
$each = new EachPromise([$a, $b], [
|
||||
'fulfilled' => function ($value, $idx, Promise $aggregate) use (&$called) {
|
||||
$this->assertSame($idx, 0);
|
||||
$this->assertEquals('a', $value);
|
||||
$aggregate->resolve(null);
|
||||
$called++;
|
||||
},
|
||||
'rejected' => function (\Exception $reason) {
|
||||
$this->fail($reason->getMessage());
|
||||
}
|
||||
]);
|
||||
$p = $each->promise();
|
||||
$p->wait();
|
||||
$this->assertNull($p->wait());
|
||||
$this->assertEquals(1, $called);
|
||||
$this->assertEquals(PromiseInterface::FULFILLED, $a->getState());
|
||||
$this->assertEquals(PromiseInterface::PENDING, $b->getState());
|
||||
// Resolving $b has no effect on the aggregate promise.
|
||||
$b->resolve('foo');
|
||||
$this->assertEquals(1, $called);
|
||||
}
|
||||
|
||||
public function testLimitsPendingPromises()
|
||||
{
|
||||
$pending = [new Promise(), new Promise(), new Promise(), new Promise()];
|
||||
$promises = new \ArrayIterator($pending);
|
||||
$each = new EachPromise($promises, ['concurrency' => 2]);
|
||||
$p = $each->promise();
|
||||
$this->assertCount(2, $this->readAttribute($each, 'pending'));
|
||||
$pending[0]->resolve('a');
|
||||
$this->assertCount(2, $this->readAttribute($each, 'pending'));
|
||||
$this->assertTrue($promises->valid());
|
||||
$pending[1]->resolve('b');
|
||||
P\queue()->run();
|
||||
$this->assertCount(2, $this->readAttribute($each, 'pending'));
|
||||
$this->assertTrue($promises->valid());
|
||||
$promises[2]->resolve('c');
|
||||
P\queue()->run();
|
||||
$this->assertCount(1, $this->readAttribute($each, 'pending'));
|
||||
$this->assertEquals(PromiseInterface::PENDING, $p->getState());
|
||||
$promises[3]->resolve('d');
|
||||
P\queue()->run();
|
||||
$this->assertNull($this->readAttribute($each, 'pending'));
|
||||
$this->assertEquals(PromiseInterface::FULFILLED, $p->getState());
|
||||
$this->assertFalse($promises->valid());
|
||||
}
|
||||
|
||||
public function testDynamicallyLimitsPendingPromises()
|
||||
{
|
||||
$calls = [];
|
||||
$pendingFn = function ($count) use (&$calls) {
|
||||
$calls[] = $count;
|
||||
return 2;
|
||||
};
|
||||
$pending = [new Promise(), new Promise(), new Promise(), new Promise()];
|
||||
$promises = new \ArrayIterator($pending);
|
||||
$each = new EachPromise($promises, ['concurrency' => $pendingFn]);
|
||||
$p = $each->promise();
|
||||
$this->assertCount(2, $this->readAttribute($each, 'pending'));
|
||||
$pending[0]->resolve('a');
|
||||
$this->assertCount(2, $this->readAttribute($each, 'pending'));
|
||||
$this->assertTrue($promises->valid());
|
||||
$pending[1]->resolve('b');
|
||||
$this->assertCount(2, $this->readAttribute($each, 'pending'));
|
||||
P\queue()->run();
|
||||
$this->assertTrue($promises->valid());
|
||||
$promises[2]->resolve('c');
|
||||
P\queue()->run();
|
||||
$this->assertCount(1, $this->readAttribute($each, 'pending'));
|
||||
$this->assertEquals(PromiseInterface::PENDING, $p->getState());
|
||||
$promises[3]->resolve('d');
|
||||
P\queue()->run();
|
||||
$this->assertNull($this->readAttribute($each, 'pending'));
|
||||
$this->assertEquals(PromiseInterface::FULFILLED, $p->getState());
|
||||
$this->assertEquals([0, 1, 1, 1], $calls);
|
||||
$this->assertFalse($promises->valid());
|
||||
}
|
||||
|
||||
public function testClearsReferencesWhenResolved()
|
||||
{
|
||||
$called = false;
|
||||
$a = new Promise(function () use (&$a, &$called) {
|
||||
$a->resolve('a');
|
||||
$called = true;
|
||||
});
|
||||
$each = new EachPromise([$a], [
|
||||
'concurrency' => function () { return 1; },
|
||||
'fulfilled' => function () {},
|
||||
'rejected' => function () {}
|
||||
]);
|
||||
$each->promise()->wait();
|
||||
$this->assertNull($this->readAttribute($each, 'onFulfilled'));
|
||||
$this->assertNull($this->readAttribute($each, 'onRejected'));
|
||||
$this->assertNull($this->readAttribute($each, 'iterable'));
|
||||
$this->assertNull($this->readAttribute($each, 'pending'));
|
||||
$this->assertNull($this->readAttribute($each, 'concurrency'));
|
||||
$this->assertTrue($called);
|
||||
}
|
||||
|
||||
public function testCanBeCancelled()
|
||||
{
|
||||
$this->markTestIncomplete();
|
||||
}
|
||||
|
||||
public function testFulfillsImmediatelyWhenGivenAnEmptyIterator()
|
||||
{
|
||||
$each = new EachPromise(new \ArrayIterator([]));
|
||||
$result = $each->promise()->wait();
|
||||
}
|
||||
|
||||
public function testDoesNotBlowStackWithFulfilledPromises()
|
||||
{
|
||||
$pending = [];
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$pending[] = new FulfilledPromise($i);
|
||||
}
|
||||
$values = [];
|
||||
$each = new EachPromise($pending, [
|
||||
'fulfilled' => function ($value) use (&$values) {
|
||||
$values[] = $value;
|
||||
}
|
||||
]);
|
||||
$called = false;
|
||||
$each->promise()->then(function () use (&$called) {
|
||||
$called = true;
|
||||
});
|
||||
$this->assertFalse($called);
|
||||
P\queue()->run();
|
||||
$this->assertTrue($called);
|
||||
$this->assertEquals(range(0, 99), $values);
|
||||
}
|
||||
|
||||
public function testDoesNotBlowStackWithRejectedPromises()
|
||||
{
|
||||
$pending = [];
|
||||
for ($i = 0; $i < 100; $i++) {
|
||||
$pending[] = new RejectedPromise($i);
|
||||
}
|
||||
$values = [];
|
||||
$each = new EachPromise($pending, [
|
||||
'rejected' => function ($value) use (&$values) {
|
||||
$values[] = $value;
|
||||
}
|
||||
]);
|
||||
$called = false;
|
||||
$each->promise()->then(
|
||||
function () use (&$called) { $called = true; },
|
||||
function () { $this->fail('Should not have rejected.'); }
|
||||
);
|
||||
$this->assertFalse($called);
|
||||
P\queue()->run();
|
||||
$this->assertTrue($called);
|
||||
$this->assertEquals(range(0, 99), $values);
|
||||
}
|
||||
|
||||
public function testReturnsPromiseForWhatever()
|
||||
{
|
||||
$called = [];
|
||||
$arr = ['a', 'b'];
|
||||
$each = new EachPromise($arr, [
|
||||
'fulfilled' => function ($v) use (&$called) { $called[] = $v; }
|
||||
]);
|
||||
$p = $each->promise();
|
||||
$this->assertNull($p->wait());
|
||||
$this->assertEquals(['a', 'b'], $called);
|
||||
}
|
||||
|
||||
public function testRejectsAggregateWhenNextThrows()
|
||||
{
|
||||
$iter = function () {
|
||||
yield 'a';
|
||||
throw new \Exception('Failure');
|
||||
};
|
||||
$each = new EachPromise($iter());
|
||||
$p = $each->promise();
|
||||
$e = null;
|
||||
$received = null;
|
||||
$p->then(null, function ($reason) use (&$e) { $e = $reason; });
|
||||
P\queue()->run();
|
||||
$this->assertInstanceOf('Exception', $e);
|
||||
$this->assertEquals('Failure', $e->getMessage());
|
||||
}
|
||||
|
||||
public function testDoesNotCallNextOnIteratorUntilNeededWhenWaiting()
|
||||
{
|
||||
$results = [];
|
||||
$values = [10];
|
||||
$remaining = 9;
|
||||
$iter = function () use (&$values) {
|
||||
while ($value = array_pop($values)) {
|
||||
yield $value;
|
||||
}
|
||||
};
|
||||
$each = new EachPromise($iter(), [
|
||||
'concurrency' => 1,
|
||||
'fulfilled' => function ($r) use (&$results, &$values, &$remaining) {
|
||||
$results[] = $r;
|
||||
if ($remaining > 0) {
|
||||
$values[] = $remaining--;
|
||||
}
|
||||
}
|
||||
]);
|
||||
$each->promise()->wait();
|
||||
$this->assertEquals(range(10, 1), $results);
|
||||
}
|
||||
|
||||
public function testDoesNotCallNextOnIteratorUntilNeededWhenAsync()
|
||||
{
|
||||
$firstPromise = new Promise();
|
||||
$pending = [$firstPromise];
|
||||
$values = [$firstPromise];
|
||||
$results = [];
|
||||
$remaining = 9;
|
||||
$iter = function () use (&$values) {
|
||||
while ($value = array_pop($values)) {
|
||||
yield $value;
|
||||
}
|
||||
};
|
||||
$each = new EachPromise($iter(), [
|
||||
'concurrency' => 1,
|
||||
'fulfilled' => function ($r) use (&$results, &$values, &$remaining, &$pending) {
|
||||
$results[] = $r;
|
||||
if ($remaining-- > 0) {
|
||||
$pending[] = $values[] = new Promise();
|
||||
}
|
||||
}
|
||||
]);
|
||||
$i = 0;
|
||||
$each->promise();
|
||||
while ($promise = array_pop($pending)) {
|
||||
$promise->resolve($i++);
|
||||
P\queue()->run();
|
||||
}
|
||||
$this->assertEquals(range(0, 9), $results);
|
||||
}
|
||||
|
||||
private function createSelfResolvingPromise($value)
|
||||
{
|
||||
$p = new Promise(function () use (&$p, $value) {
|
||||
$p->resolve($value);
|
||||
});
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
public function testMutexPreventsGeneratorRecursion()
|
||||
{
|
||||
$results = $promises = [];
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
$p = $this->createSelfResolvingPromise($i);
|
||||
$pending[] = $p;
|
||||
$promises[] = $p;
|
||||
}
|
||||
|
||||
$iter = function () use (&$promises, &$pending) {
|
||||
foreach ($promises as $promise) {
|
||||
// Resolve a promises, which will trigger the then() function,
|
||||
// which would cause the EachPromise to try to add more
|
||||
// promises to the queue. Without a lock, this would trigger
|
||||
// a "Cannot resume an already running generator" fatal error.
|
||||
if ($p = array_pop($pending)) {
|
||||
$p->wait();
|
||||
}
|
||||
yield $promise;
|
||||
}
|
||||
};
|
||||
|
||||
$each = new EachPromise($iter(), [
|
||||
'concurrency' => 5,
|
||||
'fulfilled' => function ($r) use (&$results, &$pending) {
|
||||
$results[] = $r;
|
||||
}
|
||||
]);
|
||||
|
||||
$each->promise()->wait();
|
||||
$this->assertCount(20, $results);
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Tests\Promise;
|
||||
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
use GuzzleHttp\Promise\FulfilledPromise;
|
||||
|
||||
/**
|
||||
* @covers GuzzleHttp\Promise\FulfilledPromise
|
||||
*/
|
||||
class FulfilledPromiseTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testReturnsValueWhenWaitedUpon()
|
||||
{
|
||||
$p = new FulfilledPromise('foo');
|
||||
$this->assertEquals('fulfilled', $p->getState());
|
||||
$this->assertEquals('foo', $p->wait(true));
|
||||
}
|
||||
|
||||
public function testCannotCancel()
|
||||
{
|
||||
$p = new FulfilledPromise('foo');
|
||||
$this->assertEquals('fulfilled', $p->getState());
|
||||
$p->cancel();
|
||||
$this->assertEquals('foo', $p->wait());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @exepctedExceptionMessage Cannot resolve a fulfilled promise
|
||||
*/
|
||||
public function testCannotResolve()
|
||||
{
|
||||
$p = new FulfilledPromise('foo');
|
||||
$p->resolve('bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @exepctedExceptionMessage Cannot reject a fulfilled promise
|
||||
*/
|
||||
public function testCannotReject()
|
||||
{
|
||||
$p = new FulfilledPromise('foo');
|
||||
$p->reject('bar');
|
||||
}
|
||||
|
||||
public function testCanResolveWithSameValue()
|
||||
{
|
||||
$p = new FulfilledPromise('foo');
|
||||
$p->resolve('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testCannotResolveWithPromise()
|
||||
{
|
||||
new FulfilledPromise(new Promise());
|
||||
}
|
||||
|
||||
public function testReturnsSelfWhenNoOnFulfilled()
|
||||
{
|
||||
$p = new FulfilledPromise('a');
|
||||
$this->assertSame($p, $p->then());
|
||||
}
|
||||
|
||||
public function testAsynchronouslyInvokesOnFulfilled()
|
||||
{
|
||||
$p = new FulfilledPromise('a');
|
||||
$r = null;
|
||||
$f = function ($d) use (&$r) { $r = $d; };
|
||||
$p2 = $p->then($f);
|
||||
$this->assertNotSame($p, $p2);
|
||||
$this->assertNull($r);
|
||||
\GuzzleHttp\Promise\queue()->run();
|
||||
$this->assertEquals('a', $r);
|
||||
}
|
||||
|
||||
public function testReturnsNewRejectedWhenOnFulfilledFails()
|
||||
{
|
||||
$p = new FulfilledPromise('a');
|
||||
$f = function () { throw new \Exception('b'); };
|
||||
$p2 = $p->then($f);
|
||||
$this->assertNotSame($p, $p2);
|
||||
try {
|
||||
$p2->wait();
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('b', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testOtherwiseIsSugarForRejections()
|
||||
{
|
||||
$c = null;
|
||||
$p = new FulfilledPromise('foo');
|
||||
$p->otherwise(function ($v) use (&$c) { $c = $v; });
|
||||
$this->assertNull($c);
|
||||
}
|
||||
|
||||
public function testDoesNotTryToFulfillTwiceDuringTrampoline()
|
||||
{
|
||||
$fp = new FulfilledPromise('a');
|
||||
$t1 = $fp->then(function ($v) { return $v . ' b'; });
|
||||
$t1->resolve('why!');
|
||||
$this->assertEquals('why!', $t1->wait());
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Tests;
|
||||
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
|
||||
class NotPromiseInstance extends Thennable implements PromiseInterface
|
||||
{
|
||||
private $nextPromise = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->nextPromise = new Promise();
|
||||
}
|
||||
|
||||
public function then(callable $res = null, callable $rej = null)
|
||||
{
|
||||
return $this->nextPromise->then($res, $rej);
|
||||
}
|
||||
|
||||
public function otherwise(callable $onRejected)
|
||||
{
|
||||
return $this->then($onRejected);
|
||||
}
|
||||
|
||||
public function resolve($value)
|
||||
{
|
||||
$this->nextPromise->resolve($value);
|
||||
}
|
||||
|
||||
public function reject($reason)
|
||||
{
|
||||
$this->nextPromise->reject($reason);
|
||||
}
|
||||
|
||||
public function wait($unwrap = true, $defaultResolution = null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function cancel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function getState()
|
||||
{
|
||||
return $this->nextPromise->getState();
|
||||
}
|
||||
}
|
||||
591
vendor/guzzlehttp/promises/tests/PromiseTest.php
vendored
591
vendor/guzzlehttp/promises/tests/PromiseTest.php
vendored
@@ -1,591 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Tests;
|
||||
|
||||
use GuzzleHttp\Promise\CancellationException;
|
||||
use GuzzleHttp\Promise as P;
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
use GuzzleHttp\Promise\RejectedPromise;
|
||||
use GuzzleHttp\Promise\RejectionException;
|
||||
|
||||
/**
|
||||
* @covers GuzzleHttp\Promise\Promise
|
||||
*/
|
||||
class PromiseTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage The promise is already fulfilled
|
||||
*/
|
||||
public function testCannotResolveNonPendingPromise()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->resolve('foo');
|
||||
$p->resolve('bar');
|
||||
$this->assertEquals('foo', $p->wait());
|
||||
}
|
||||
|
||||
public function testCanResolveWithSameValue()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->resolve('foo');
|
||||
$p->resolve('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage Cannot change a fulfilled promise to rejected
|
||||
*/
|
||||
public function testCannotRejectNonPendingPromise()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->resolve('foo');
|
||||
$p->reject('bar');
|
||||
$this->assertEquals('foo', $p->wait());
|
||||
}
|
||||
|
||||
public function testCanRejectWithSameValue()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->reject('foo');
|
||||
$p->reject('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage Cannot change a fulfilled promise to rejected
|
||||
*/
|
||||
public function testCannotRejectResolveWithSameValue()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->resolve('foo');
|
||||
$p->reject('foo');
|
||||
}
|
||||
|
||||
public function testInvokesWaitFunction()
|
||||
{
|
||||
$p = new Promise(function () use (&$p) { $p->resolve('10'); });
|
||||
$this->assertEquals('10', $p->wait());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \GuzzleHttp\Promise\RejectionException
|
||||
*/
|
||||
public function testRejectsAndThrowsWhenWaitFailsToResolve()
|
||||
{
|
||||
$p = new Promise(function () {});
|
||||
$p->wait();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \GuzzleHttp\Promise\RejectionException
|
||||
* @expectedExceptionMessage The promise was rejected with reason: foo
|
||||
*/
|
||||
public function testThrowsWhenUnwrapIsRejectedWithNonException()
|
||||
{
|
||||
$p = new Promise(function () use (&$p) { $p->reject('foo'); });
|
||||
$p->wait();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \UnexpectedValueException
|
||||
* @expectedExceptionMessage foo
|
||||
*/
|
||||
public function testThrowsWhenUnwrapIsRejectedWithException()
|
||||
{
|
||||
$e = new \UnexpectedValueException('foo');
|
||||
$p = new Promise(function () use (&$p, $e) { $p->reject($e); });
|
||||
$p->wait();
|
||||
}
|
||||
|
||||
public function testDoesNotUnwrapExceptionsWhenDisabled()
|
||||
{
|
||||
$p = new Promise(function () use (&$p) { $p->reject('foo'); });
|
||||
$this->assertEquals('pending', $p->getState());
|
||||
$p->wait(false);
|
||||
$this->assertEquals('rejected', $p->getState());
|
||||
}
|
||||
|
||||
public function testRejectsSelfWhenWaitThrows()
|
||||
{
|
||||
$e = new \UnexpectedValueException('foo');
|
||||
$p = new Promise(function () use ($e) { throw $e; });
|
||||
try {
|
||||
$p->wait();
|
||||
$this->fail();
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
$this->assertEquals('rejected', $p->getState());
|
||||
}
|
||||
}
|
||||
|
||||
public function testWaitsOnNestedPromises()
|
||||
{
|
||||
$p = new Promise(function () use (&$p) { $p->resolve('_'); });
|
||||
$p2 = new Promise(function () use (&$p2) { $p2->resolve('foo'); });
|
||||
$p3 = $p->then(function () use ($p2) { return $p2; });
|
||||
$this->assertSame('foo', $p3->wait());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \GuzzleHttp\Promise\RejectionException
|
||||
*/
|
||||
public function testThrowsWhenWaitingOnPromiseWithNoWaitFunction()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->wait();
|
||||
}
|
||||
|
||||
public function testThrowsWaitExceptionAfterPromiseIsResolved()
|
||||
{
|
||||
$p = new Promise(function () use (&$p) {
|
||||
$p->reject('Foo!');
|
||||
throw new \Exception('Bar?');
|
||||
});
|
||||
|
||||
try {
|
||||
$p->wait();
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('Bar?', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetsActualWaitValueFromThen()
|
||||
{
|
||||
$p = new Promise(function () use (&$p) { $p->reject('Foo!'); });
|
||||
$p2 = $p->then(null, function ($reason) {
|
||||
return new RejectedPromise([$reason]);
|
||||
});
|
||||
|
||||
try {
|
||||
$p2->wait();
|
||||
$this->fail('Should have thrown');
|
||||
} catch (RejectionException $e) {
|
||||
$this->assertEquals(['Foo!'], $e->getReason());
|
||||
}
|
||||
}
|
||||
|
||||
public function testWaitBehaviorIsBasedOnLastPromiseInChain()
|
||||
{
|
||||
$p3 = new Promise(function () use (&$p3) { $p3->resolve('Whoop'); });
|
||||
$p2 = new Promise(function () use (&$p2, $p3) { $p2->reject($p3); });
|
||||
$p = new Promise(function () use (&$p, $p2) { $p->reject($p2); });
|
||||
$this->assertEquals('Whoop', $p->wait());
|
||||
}
|
||||
|
||||
public function testWaitsOnAPromiseChainEvenWhenNotUnwrapped()
|
||||
{
|
||||
$p2 = new Promise(function () use (&$p2) {
|
||||
$p2->reject('Fail');
|
||||
});
|
||||
$p = new Promise(function () use ($p2, &$p) {
|
||||
$p->resolve($p2);
|
||||
});
|
||||
$p->wait(false);
|
||||
$this->assertSame(Promise::REJECTED, $p2->getState());
|
||||
}
|
||||
|
||||
public function testCannotCancelNonPending()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->resolve('foo');
|
||||
$p->cancel();
|
||||
$this->assertEquals('fulfilled', $p->getState());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \GuzzleHttp\Promise\CancellationException
|
||||
*/
|
||||
public function testCancelsPromiseWhenNoCancelFunction()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->cancel();
|
||||
$this->assertEquals('rejected', $p->getState());
|
||||
$p->wait();
|
||||
}
|
||||
|
||||
public function testCancelsPromiseWithCancelFunction()
|
||||
{
|
||||
$called = false;
|
||||
$p = new Promise(null, function () use (&$called) { $called = true; });
|
||||
$p->cancel();
|
||||
$this->assertEquals('rejected', $p->getState());
|
||||
$this->assertTrue($called);
|
||||
}
|
||||
|
||||
public function testCancelsUppermostPendingPromise()
|
||||
{
|
||||
$called = false;
|
||||
$p1 = new Promise(null, function () use (&$called) { $called = true; });
|
||||
$p2 = $p1->then(function () {});
|
||||
$p3 = $p2->then(function () {});
|
||||
$p4 = $p3->then(function () {});
|
||||
$p3->cancel();
|
||||
$this->assertEquals('rejected', $p1->getState());
|
||||
$this->assertEquals('rejected', $p2->getState());
|
||||
$this->assertEquals('rejected', $p3->getState());
|
||||
$this->assertEquals('pending', $p4->getState());
|
||||
$this->assertTrue($called);
|
||||
|
||||
try {
|
||||
$p3->wait();
|
||||
$this->fail();
|
||||
} catch (CancellationException $e) {
|
||||
$this->assertContains('cancelled', $e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
$p4->wait();
|
||||
$this->fail();
|
||||
} catch (CancellationException $e) {
|
||||
$this->assertContains('cancelled', $e->getMessage());
|
||||
}
|
||||
|
||||
$this->assertEquals('rejected', $p4->getState());
|
||||
}
|
||||
|
||||
public function testCancelsChildPromises()
|
||||
{
|
||||
$called1 = $called2 = $called3 = false;
|
||||
$p1 = new Promise(null, function () use (&$called1) { $called1 = true; });
|
||||
$p2 = new Promise(null, function () use (&$called2) { $called2 = true; });
|
||||
$p3 = new Promise(null, function () use (&$called3) { $called3 = true; });
|
||||
$p4 = $p2->then(function () use ($p3) { return $p3; });
|
||||
$p5 = $p4->then(function () { $this->fail(); });
|
||||
$p4->cancel();
|
||||
$this->assertEquals('pending', $p1->getState());
|
||||
$this->assertEquals('rejected', $p2->getState());
|
||||
$this->assertEquals('rejected', $p4->getState());
|
||||
$this->assertEquals('pending', $p5->getState());
|
||||
$this->assertFalse($called1);
|
||||
$this->assertTrue($called2);
|
||||
$this->assertFalse($called3);
|
||||
}
|
||||
|
||||
public function testRejectsPromiseWhenCancelFails()
|
||||
{
|
||||
$called = false;
|
||||
$p = new Promise(null, function () use (&$called) {
|
||||
$called = true;
|
||||
throw new \Exception('e');
|
||||
});
|
||||
$p->cancel();
|
||||
$this->assertEquals('rejected', $p->getState());
|
||||
$this->assertTrue($called);
|
||||
try {
|
||||
$p->wait();
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('e', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testCreatesPromiseWhenFulfilledAfterThen()
|
||||
{
|
||||
$p = new Promise();
|
||||
$carry = null;
|
||||
$p2 = $p->then(function ($v) use (&$carry) { $carry = $v; });
|
||||
$this->assertNotSame($p, $p2);
|
||||
$p->resolve('foo');
|
||||
P\queue()->run();
|
||||
|
||||
$this->assertEquals('foo', $carry);
|
||||
}
|
||||
|
||||
public function testCreatesPromiseWhenFulfilledBeforeThen()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->resolve('foo');
|
||||
$carry = null;
|
||||
$p2 = $p->then(function ($v) use (&$carry) { $carry = $v; });
|
||||
$this->assertNotSame($p, $p2);
|
||||
$this->assertNull($carry);
|
||||
\GuzzleHttp\Promise\queue()->run();
|
||||
$this->assertEquals('foo', $carry);
|
||||
}
|
||||
|
||||
public function testCreatesPromiseWhenFulfilledWithNoCallback()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->resolve('foo');
|
||||
$p2 = $p->then();
|
||||
$this->assertNotSame($p, $p2);
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $p2);
|
||||
}
|
||||
|
||||
public function testCreatesPromiseWhenRejectedAfterThen()
|
||||
{
|
||||
$p = new Promise();
|
||||
$carry = null;
|
||||
$p2 = $p->then(null, function ($v) use (&$carry) { $carry = $v; });
|
||||
$this->assertNotSame($p, $p2);
|
||||
$p->reject('foo');
|
||||
P\queue()->run();
|
||||
$this->assertEquals('foo', $carry);
|
||||
}
|
||||
|
||||
public function testCreatesPromiseWhenRejectedBeforeThen()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->reject('foo');
|
||||
$carry = null;
|
||||
$p2 = $p->then(null, function ($v) use (&$carry) { $carry = $v; });
|
||||
$this->assertNotSame($p, $p2);
|
||||
$this->assertNull($carry);
|
||||
P\queue()->run();
|
||||
$this->assertEquals('foo', $carry);
|
||||
}
|
||||
|
||||
public function testCreatesPromiseWhenRejectedWithNoCallback()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->reject('foo');
|
||||
$p2 = $p->then();
|
||||
$this->assertNotSame($p, $p2);
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\RejectedPromise', $p2);
|
||||
}
|
||||
|
||||
public function testInvokesWaitFnsForThens()
|
||||
{
|
||||
$p = new Promise(function () use (&$p) { $p->resolve('a'); });
|
||||
$p2 = $p
|
||||
->then(function ($v) { return $v . '-1-'; })
|
||||
->then(function ($v) { return $v . '2'; });
|
||||
$this->assertEquals('a-1-2', $p2->wait());
|
||||
}
|
||||
|
||||
public function testStacksThenWaitFunctions()
|
||||
{
|
||||
$p1 = new Promise(function () use (&$p1) { $p1->resolve('a'); });
|
||||
$p2 = new Promise(function () use (&$p2) { $p2->resolve('b'); });
|
||||
$p3 = new Promise(function () use (&$p3) { $p3->resolve('c'); });
|
||||
$p4 = $p1
|
||||
->then(function () use ($p2) { return $p2; })
|
||||
->then(function () use ($p3) { return $p3; });
|
||||
$this->assertEquals('c', $p4->wait());
|
||||
}
|
||||
|
||||
public function testForwardsFulfilledDownChainBetweenGaps()
|
||||
{
|
||||
$p = new Promise();
|
||||
$r = $r2 = null;
|
||||
$p->then(null, null)
|
||||
->then(function ($v) use (&$r) { $r = $v; return $v . '2'; })
|
||||
->then(function ($v) use (&$r2) { $r2 = $v; });
|
||||
$p->resolve('foo');
|
||||
P\queue()->run();
|
||||
$this->assertEquals('foo', $r);
|
||||
$this->assertEquals('foo2', $r2);
|
||||
}
|
||||
|
||||
public function testForwardsRejectedPromisesDownChainBetweenGaps()
|
||||
{
|
||||
$p = new Promise();
|
||||
$r = $r2 = null;
|
||||
$p->then(null, null)
|
||||
->then(null, function ($v) use (&$r) { $r = $v; return $v . '2'; })
|
||||
->then(function ($v) use (&$r2) { $r2 = $v; });
|
||||
$p->reject('foo');
|
||||
P\queue()->run();
|
||||
$this->assertEquals('foo', $r);
|
||||
$this->assertEquals('foo2', $r2);
|
||||
}
|
||||
|
||||
public function testForwardsThrownPromisesDownChainBetweenGaps()
|
||||
{
|
||||
$e = new \Exception();
|
||||
$p = new Promise();
|
||||
$r = $r2 = null;
|
||||
$p->then(null, null)
|
||||
->then(null, function ($v) use (&$r, $e) {
|
||||
$r = $v;
|
||||
throw $e;
|
||||
})
|
||||
->then(
|
||||
null,
|
||||
function ($v) use (&$r2) { $r2 = $v; }
|
||||
);
|
||||
$p->reject('foo');
|
||||
P\queue()->run();
|
||||
$this->assertEquals('foo', $r);
|
||||
$this->assertSame($e, $r2);
|
||||
}
|
||||
|
||||
public function testForwardsReturnedRejectedPromisesDownChainBetweenGaps()
|
||||
{
|
||||
$p = new Promise();
|
||||
$rejected = new RejectedPromise('bar');
|
||||
$r = $r2 = null;
|
||||
$p->then(null, null)
|
||||
->then(null, function ($v) use (&$r, $rejected) {
|
||||
$r = $v;
|
||||
return $rejected;
|
||||
})
|
||||
->then(
|
||||
null,
|
||||
function ($v) use (&$r2) { $r2 = $v; }
|
||||
);
|
||||
$p->reject('foo');
|
||||
P\queue()->run();
|
||||
$this->assertEquals('foo', $r);
|
||||
$this->assertEquals('bar', $r2);
|
||||
try {
|
||||
$p->wait();
|
||||
} catch (RejectionException $e) {
|
||||
$this->assertEquals('foo', $e->getReason());
|
||||
}
|
||||
}
|
||||
|
||||
public function testForwardsHandlersToNextPromise()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p2 = new Promise();
|
||||
$resolved = null;
|
||||
$p
|
||||
->then(function ($v) use ($p2) { return $p2; })
|
||||
->then(function ($value) use (&$resolved) { $resolved = $value; });
|
||||
$p->resolve('a');
|
||||
$p2->resolve('b');
|
||||
P\queue()->run();
|
||||
$this->assertEquals('b', $resolved);
|
||||
}
|
||||
|
||||
public function testRemovesReferenceFromChildWhenParentWaitedUpon()
|
||||
{
|
||||
$r = null;
|
||||
$p = new Promise(function () use (&$p) { $p->resolve('a'); });
|
||||
$p2 = new Promise(function () use (&$p2) { $p2->resolve('b'); });
|
||||
$pb = $p->then(
|
||||
function ($v) use ($p2, &$r) {
|
||||
$r = $v;
|
||||
return $p2;
|
||||
})
|
||||
->then(function ($v) { return $v . '.'; });
|
||||
$this->assertEquals('a', $p->wait());
|
||||
$this->assertEquals('b', $p2->wait());
|
||||
$this->assertEquals('b.', $pb->wait());
|
||||
$this->assertEquals('a', $r);
|
||||
}
|
||||
|
||||
public function testForwardsHandlersWhenFulfilledPromiseIsReturned()
|
||||
{
|
||||
$res = [];
|
||||
$p = new Promise();
|
||||
$p2 = new Promise();
|
||||
$p2->resolve('foo');
|
||||
$p2->then(function ($v) use (&$res) { $res[] = 'A:' . $v; });
|
||||
// $res is A:foo
|
||||
$p
|
||||
->then(function () use ($p2, &$res) { $res[] = 'B'; return $p2; })
|
||||
->then(function ($v) use (&$res) { $res[] = 'C:' . $v; });
|
||||
$p->resolve('a');
|
||||
$p->then(function ($v) use (&$res) { $res[] = 'D:' . $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['A:foo', 'B', 'D:a', 'C:foo'], $res);
|
||||
}
|
||||
|
||||
public function testForwardsHandlersWhenRejectedPromiseIsReturned()
|
||||
{
|
||||
$res = [];
|
||||
$p = new Promise();
|
||||
$p2 = new Promise();
|
||||
$p2->reject('foo');
|
||||
$p2->then(null, function ($v) use (&$res) { $res[] = 'A:' . $v; });
|
||||
$p->then(null, function () use ($p2, &$res) { $res[] = 'B'; return $p2; })
|
||||
->then(null, function ($v) use (&$res) { $res[] = 'C:' . $v; });
|
||||
$p->reject('a');
|
||||
$p->then(null, function ($v) use (&$res) { $res[] = 'D:' . $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['A:foo', 'B', 'D:a', 'C:foo'], $res);
|
||||
}
|
||||
|
||||
public function testDoesNotForwardRejectedPromise()
|
||||
{
|
||||
$res = [];
|
||||
$p = new Promise();
|
||||
$p2 = new Promise();
|
||||
$p2->cancel();
|
||||
$p2->then(function ($v) use (&$res) { $res[] = "B:$v"; return $v; });
|
||||
$p->then(function ($v) use ($p2, &$res) { $res[] = "B:$v"; return $p2; })
|
||||
->then(function ($v) use (&$res) { $res[] = 'C:' . $v; });
|
||||
$p->resolve('a');
|
||||
$p->then(function ($v) use (&$res) { $res[] = 'D:' . $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['B:a', 'D:a'], $res);
|
||||
}
|
||||
|
||||
public function testRecursivelyForwardsWhenOnlyThennable()
|
||||
{
|
||||
$res = [];
|
||||
$p = new Promise();
|
||||
$p2 = new Thennable();
|
||||
$p2->resolve('foo');
|
||||
$p2->then(function ($v) use (&$res) { $res[] = 'A:' . $v; });
|
||||
$p->then(function () use ($p2, &$res) { $res[] = 'B'; return $p2; })
|
||||
->then(function ($v) use (&$res) { $res[] = 'C:' . $v; });
|
||||
$p->resolve('a');
|
||||
$p->then(function ($v) use (&$res) { $res[] = 'D:' . $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['A:foo', 'B', 'D:a', 'C:foo'], $res);
|
||||
}
|
||||
|
||||
public function testRecursivelyForwardsWhenNotInstanceOfPromise()
|
||||
{
|
||||
$res = [];
|
||||
$p = new Promise();
|
||||
$p2 = new NotPromiseInstance();
|
||||
$p2->then(function ($v) use (&$res) { $res[] = 'A:' . $v; });
|
||||
$p->then(function () use ($p2, &$res) { $res[] = 'B'; return $p2; })
|
||||
->then(function ($v) use (&$res) { $res[] = 'C:' . $v; });
|
||||
$p->resolve('a');
|
||||
$p->then(function ($v) use (&$res) { $res[] = 'D:' . $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['B', 'D:a'], $res);
|
||||
$p2->resolve('foo');
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['B', 'D:a', 'A:foo', 'C:foo'], $res);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage Cannot fulfill or reject a promise with itself
|
||||
*/
|
||||
public function testCannotResolveWithSelf()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->resolve($p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage Cannot fulfill or reject a promise with itself
|
||||
*/
|
||||
public function testCannotRejectWithSelf()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->reject($p);
|
||||
}
|
||||
|
||||
public function testDoesNotBlowStackWhenWaitingOnNestedThens()
|
||||
{
|
||||
$inner = new Promise(function () use (&$inner) { $inner->resolve(0); });
|
||||
$prev = $inner;
|
||||
for ($i = 1; $i < 100; $i++) {
|
||||
$prev = $prev->then(function ($i) { return $i + 1; });
|
||||
}
|
||||
|
||||
$parent = new Promise(function () use (&$parent, $prev) {
|
||||
$parent->resolve($prev);
|
||||
});
|
||||
|
||||
$this->assertEquals(99, $parent->wait());
|
||||
}
|
||||
|
||||
public function testOtherwiseIsSugarForRejections()
|
||||
{
|
||||
$p = new Promise();
|
||||
$p->reject('foo');
|
||||
$p->otherwise(function ($v) use (&$c) { $c = $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals($c, 'foo');
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Tests;
|
||||
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
use GuzzleHttp\Promise\RejectedPromise;
|
||||
|
||||
/**
|
||||
* @covers GuzzleHttp\Promise\RejectedPromise
|
||||
*/
|
||||
class RejectedPromiseTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testThrowsReasonWhenWaitedUpon()
|
||||
{
|
||||
$p = new RejectedPromise('foo');
|
||||
$this->assertEquals('rejected', $p->getState());
|
||||
try {
|
||||
$p->wait(true);
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('rejected', $p->getState());
|
||||
$this->assertContains('foo', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testCannotCancel()
|
||||
{
|
||||
$p = new RejectedPromise('foo');
|
||||
$p->cancel();
|
||||
$this->assertEquals('rejected', $p->getState());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @exepctedExceptionMessage Cannot resolve a rejected promise
|
||||
*/
|
||||
public function testCannotResolve()
|
||||
{
|
||||
$p = new RejectedPromise('foo');
|
||||
$p->resolve('bar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @exepctedExceptionMessage Cannot reject a rejected promise
|
||||
*/
|
||||
public function testCannotReject()
|
||||
{
|
||||
$p = new RejectedPromise('foo');
|
||||
$p->reject('bar');
|
||||
}
|
||||
|
||||
public function testCanRejectWithSameValue()
|
||||
{
|
||||
$p = new RejectedPromise('foo');
|
||||
$p->reject('foo');
|
||||
}
|
||||
|
||||
public function testThrowsSpecificException()
|
||||
{
|
||||
$e = new \Exception();
|
||||
$p = new RejectedPromise($e);
|
||||
try {
|
||||
$p->wait(true);
|
||||
$this->fail();
|
||||
} catch (\Exception $e2) {
|
||||
$this->assertSame($e, $e2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testCannotResolveWithPromise()
|
||||
{
|
||||
new RejectedPromise(new Promise());
|
||||
}
|
||||
|
||||
public function testReturnsSelfWhenNoOnReject()
|
||||
{
|
||||
$p = new RejectedPromise('a');
|
||||
$this->assertSame($p, $p->then());
|
||||
}
|
||||
|
||||
public function testInvokesOnRejectedAsynchronously()
|
||||
{
|
||||
$p = new RejectedPromise('a');
|
||||
$r = null;
|
||||
$f = function ($reason) use (&$r) { $r = $reason; };
|
||||
$p->then(null, $f);
|
||||
$this->assertNull($r);
|
||||
\GuzzleHttp\Promise\queue()->run();
|
||||
$this->assertEquals('a', $r);
|
||||
}
|
||||
|
||||
public function testReturnsNewRejectedWhenOnRejectedFails()
|
||||
{
|
||||
$p = new RejectedPromise('a');
|
||||
$f = function () { throw new \Exception('b'); };
|
||||
$p2 = $p->then(null, $f);
|
||||
$this->assertNotSame($p, $p2);
|
||||
try {
|
||||
$p2->wait();
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals('b', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testWaitingIsNoOp()
|
||||
{
|
||||
$p = new RejectedPromise('a');
|
||||
$p->wait(false);
|
||||
}
|
||||
|
||||
public function testOtherwiseIsSugarForRejections()
|
||||
{
|
||||
$p = new RejectedPromise('foo');
|
||||
$p->otherwise(function ($v) use (&$c) { $c = $v; });
|
||||
\GuzzleHttp\Promise\queue()->run();
|
||||
$this->assertSame('foo', $c);
|
||||
}
|
||||
|
||||
public function testCanResolveThenWithSuccess()
|
||||
{
|
||||
$actual = null;
|
||||
$p = new RejectedPromise('foo');
|
||||
$p->otherwise(function ($v) {
|
||||
return $v . ' bar';
|
||||
})->then(function ($v) use (&$actual) {
|
||||
$actual = $v;
|
||||
});
|
||||
\GuzzleHttp\Promise\queue()->run();
|
||||
$this->assertEquals('foo bar', $actual);
|
||||
}
|
||||
|
||||
public function testDoesNotTryToRejectTwiceDuringTrampoline()
|
||||
{
|
||||
$fp = new RejectedPromise('a');
|
||||
$t1 = $fp->then(null, function ($v) { return $v . ' b'; });
|
||||
$t1->resolve('why!');
|
||||
$this->assertEquals('why!', $t1->wait());
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Tests;
|
||||
|
||||
use GuzzleHttp\Promise\RejectionException;
|
||||
|
||||
class Thing1
|
||||
{
|
||||
public function __construct($message)
|
||||
{
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
}
|
||||
|
||||
class Thing2 implements \JsonSerializable
|
||||
{
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return '{}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers GuzzleHttp\Promise\RejectionException
|
||||
*/
|
||||
class RejectionExceptionTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCanGetReasonFromException()
|
||||
{
|
||||
$thing = new Thing1('foo');
|
||||
$e = new RejectionException($thing);
|
||||
|
||||
$this->assertSame($thing, $e->getReason());
|
||||
$this->assertEquals('The promise was rejected with reason: foo', $e->getMessage());
|
||||
}
|
||||
|
||||
public function testCanGetReasonMessageFromJson()
|
||||
{
|
||||
$reason = new Thing2();
|
||||
$e = new RejectionException($reason);
|
||||
$this->assertContains("{}", $e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Test;
|
||||
|
||||
use GuzzleHttp\Promise\TaskQueue;
|
||||
|
||||
class TaskQueueTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testKnowsIfEmpty()
|
||||
{
|
||||
$tq = new TaskQueue(false);
|
||||
$this->assertTrue($tq->isEmpty());
|
||||
}
|
||||
|
||||
public function testKnowsIfFull()
|
||||
{
|
||||
$tq = new TaskQueue(false);
|
||||
$tq->add(function () {});
|
||||
$this->assertFalse($tq->isEmpty());
|
||||
}
|
||||
|
||||
public function testExecutesTasksInOrder()
|
||||
{
|
||||
$tq = new TaskQueue(false);
|
||||
$called = [];
|
||||
$tq->add(function () use (&$called) { $called[] = 'a'; });
|
||||
$tq->add(function () use (&$called) { $called[] = 'b'; });
|
||||
$tq->add(function () use (&$called) { $called[] = 'c'; });
|
||||
$tq->run();
|
||||
$this->assertEquals(['a', 'b', 'c'], $called);
|
||||
}
|
||||
}
|
||||
24
vendor/guzzlehttp/promises/tests/Thennable.php
vendored
24
vendor/guzzlehttp/promises/tests/Thennable.php
vendored
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Tests;
|
||||
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
|
||||
class Thennable
|
||||
{
|
||||
private $nextPromise = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->nextPromise = new Promise();
|
||||
}
|
||||
|
||||
public function then(callable $res = null, callable $rej = null)
|
||||
{
|
||||
return $this->nextPromise->then($res, $rej);
|
||||
}
|
||||
|
||||
public function resolve($value)
|
||||
{
|
||||
$this->nextPromise->resolve($value);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
<?php
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
require __DIR__ . '/Thennable.php';
|
||||
require __DIR__ . '/NotPromiseInstance.php';
|
||||
694
vendor/guzzlehttp/promises/tests/functionsTest.php
vendored
694
vendor/guzzlehttp/promises/tests/functionsTest.php
vendored
@@ -1,694 +0,0 @@
|
||||
<?php
|
||||
namespace GuzzleHttp\Promise\Tests;
|
||||
|
||||
use GuzzleHttp\Promise as P;
|
||||
use GuzzleHttp\Promise\FulfilledPromise;
|
||||
use GuzzleHttp\Promise\Promise;
|
||||
use GuzzleHttp\Promise\RejectedPromise;
|
||||
|
||||
class FunctionsTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCreatesPromiseForValue()
|
||||
{
|
||||
$p = \GuzzleHttp\Promise\promise_for('foo');
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\FulfilledPromise', $p);
|
||||
}
|
||||
|
||||
public function testReturnsPromiseForPromise()
|
||||
{
|
||||
$p = new Promise();
|
||||
$this->assertSame($p, \GuzzleHttp\Promise\promise_for($p));
|
||||
}
|
||||
|
||||
public function testReturnsPromiseForThennable()
|
||||
{
|
||||
$p = new Thennable();
|
||||
$wrapped = \GuzzleHttp\Promise\promise_for($p);
|
||||
$this->assertNotSame($p, $wrapped);
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\PromiseInterface', $wrapped);
|
||||
$p->resolve('foo');
|
||||
P\queue()->run();
|
||||
$this->assertEquals('foo', $wrapped->wait());
|
||||
}
|
||||
|
||||
public function testReturnsRejection()
|
||||
{
|
||||
$p = \GuzzleHttp\Promise\rejection_for('fail');
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\RejectedPromise', $p);
|
||||
$this->assertEquals('fail', $this->readAttribute($p, 'reason'));
|
||||
}
|
||||
|
||||
public function testReturnsPromisesAsIsInRejectionFor()
|
||||
{
|
||||
$a = new Promise();
|
||||
$b = \GuzzleHttp\Promise\rejection_for($a);
|
||||
$this->assertSame($a, $b);
|
||||
}
|
||||
|
||||
public function testWaitsOnAllPromisesIntoArray()
|
||||
{
|
||||
$e = new \Exception();
|
||||
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
|
||||
$b = new Promise(function () use (&$b) { $b->reject('b'); });
|
||||
$c = new Promise(function () use (&$c, $e) { $c->reject($e); });
|
||||
$results = \GuzzleHttp\Promise\inspect_all([$a, $b, $c]);
|
||||
$this->assertEquals([
|
||||
['state' => 'fulfilled', 'value' => 'a'],
|
||||
['state' => 'rejected', 'reason' => 'b'],
|
||||
['state' => 'rejected', 'reason' => $e]
|
||||
], $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \GuzzleHttp\Promise\RejectionException
|
||||
*/
|
||||
public function testUnwrapsPromisesWithNoDefaultAndFailure()
|
||||
{
|
||||
$promises = [new FulfilledPromise('a'), new Promise()];
|
||||
\GuzzleHttp\Promise\unwrap($promises);
|
||||
}
|
||||
|
||||
public function testUnwrapsPromisesWithNoDefault()
|
||||
{
|
||||
$promises = [new FulfilledPromise('a')];
|
||||
$this->assertEquals(['a'], \GuzzleHttp\Promise\unwrap($promises));
|
||||
}
|
||||
|
||||
public function testUnwrapsPromisesWithKeys()
|
||||
{
|
||||
$promises = [
|
||||
'foo' => new FulfilledPromise('a'),
|
||||
'bar' => new FulfilledPromise('b'),
|
||||
];
|
||||
$this->assertEquals([
|
||||
'foo' => 'a',
|
||||
'bar' => 'b'
|
||||
], \GuzzleHttp\Promise\unwrap($promises));
|
||||
}
|
||||
|
||||
public function testAllAggregatesSortedArray()
|
||||
{
|
||||
$a = new Promise();
|
||||
$b = new Promise();
|
||||
$c = new Promise();
|
||||
$d = \GuzzleHttp\Promise\all([$a, $b, $c]);
|
||||
$b->resolve('b');
|
||||
$a->resolve('a');
|
||||
$c->resolve('c');
|
||||
$d->then(
|
||||
function ($value) use (&$result) { $result = $value; },
|
||||
function ($reason) use (&$result) { $result = $reason; }
|
||||
);
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['a', 'b', 'c'], $result);
|
||||
}
|
||||
|
||||
public function testAllThrowsWhenAnyRejected()
|
||||
{
|
||||
$a = new Promise();
|
||||
$b = new Promise();
|
||||
$c = new Promise();
|
||||
$d = \GuzzleHttp\Promise\all([$a, $b, $c]);
|
||||
$b->resolve('b');
|
||||
$a->reject('fail');
|
||||
$c->resolve('c');
|
||||
$d->then(
|
||||
function ($value) use (&$result) { $result = $value; },
|
||||
function ($reason) use (&$result) { $result = $reason; }
|
||||
);
|
||||
P\queue()->run();
|
||||
$this->assertEquals('fail', $result);
|
||||
}
|
||||
|
||||
public function testSomeAggregatesSortedArrayWithMax()
|
||||
{
|
||||
$a = new Promise();
|
||||
$b = new Promise();
|
||||
$c = new Promise();
|
||||
$d = \GuzzleHttp\Promise\some(2, [$a, $b, $c]);
|
||||
$b->resolve('b');
|
||||
$c->resolve('c');
|
||||
$a->resolve('a');
|
||||
$d->then(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(['b', 'c'], $result);
|
||||
}
|
||||
|
||||
public function testSomeRejectsWhenTooManyRejections()
|
||||
{
|
||||
$a = new Promise();
|
||||
$b = new Promise();
|
||||
$d = \GuzzleHttp\Promise\some(2, [$a, $b]);
|
||||
$a->reject('bad');
|
||||
$b->resolve('good');
|
||||
P\queue()->run();
|
||||
$this->assertEquals($a::REJECTED, $d->getState());
|
||||
$d->then(null, function ($reason) use (&$called) {
|
||||
$called = $reason;
|
||||
});
|
||||
P\queue()->run();
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\AggregateException', $called);
|
||||
$this->assertContains('bad', $called->getReason());
|
||||
}
|
||||
|
||||
public function testCanWaitUntilSomeCountIsSatisfied()
|
||||
{
|
||||
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
|
||||
$b = new Promise(function () use (&$b) { $b->resolve('b'); });
|
||||
$c = new Promise(function () use (&$c) { $c->resolve('c'); });
|
||||
$d = \GuzzleHttp\Promise\some(2, [$a, $b, $c]);
|
||||
$this->assertEquals(['a', 'b'], $d->wait());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \GuzzleHttp\Promise\AggregateException
|
||||
* @expectedExceptionMessage Not enough promises to fulfill count
|
||||
*/
|
||||
public function testThrowsIfImpossibleToWaitForSomeCount()
|
||||
{
|
||||
$a = new Promise(function () use (&$a) { $a->resolve('a'); });
|
||||
$d = \GuzzleHttp\Promise\some(2, [$a]);
|
||||
$d->wait();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \GuzzleHttp\Promise\AggregateException
|
||||
* @expectedExceptionMessage Not enough promises to fulfill count
|
||||
*/
|
||||
public function testThrowsIfResolvedWithoutCountTotalResults()
|
||||
{
|
||||
$a = new Promise();
|
||||
$b = new Promise();
|
||||
$d = \GuzzleHttp\Promise\some(3, [$a, $b]);
|
||||
$a->resolve('a');
|
||||
$b->resolve('b');
|
||||
$d->wait();
|
||||
}
|
||||
|
||||
public function testAnyReturnsFirstMatch()
|
||||
{
|
||||
$a = new Promise();
|
||||
$b = new Promise();
|
||||
$c = \GuzzleHttp\Promise\any([$a, $b]);
|
||||
$b->resolve('b');
|
||||
$a->resolve('a');
|
||||
//P\queue()->run();
|
||||
//$this->assertEquals('fulfilled', $c->getState());
|
||||
$c->then(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals('b', $result);
|
||||
}
|
||||
|
||||
public function testSettleFulfillsWithFulfilledAndRejected()
|
||||
{
|
||||
$a = new Promise();
|
||||
$b = new Promise();
|
||||
$c = new Promise();
|
||||
$d = \GuzzleHttp\Promise\settle([$a, $b, $c]);
|
||||
$b->resolve('b');
|
||||
$c->resolve('c');
|
||||
$a->reject('a');
|
||||
P\queue()->run();
|
||||
$this->assertEquals('fulfilled', $d->getState());
|
||||
$d->then(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals([
|
||||
['state' => 'rejected', 'reason' => 'a'],
|
||||
['state' => 'fulfilled', 'value' => 'b'],
|
||||
['state' => 'fulfilled', 'value' => 'c']
|
||||
], $result);
|
||||
}
|
||||
|
||||
public function testCanInspectFulfilledPromise()
|
||||
{
|
||||
$p = new FulfilledPromise('foo');
|
||||
$this->assertEquals([
|
||||
'state' => 'fulfilled',
|
||||
'value' => 'foo'
|
||||
], \GuzzleHttp\Promise\inspect($p));
|
||||
}
|
||||
|
||||
public function testCanInspectRejectedPromise()
|
||||
{
|
||||
$p = new RejectedPromise('foo');
|
||||
$this->assertEquals([
|
||||
'state' => 'rejected',
|
||||
'reason' => 'foo'
|
||||
], \GuzzleHttp\Promise\inspect($p));
|
||||
}
|
||||
|
||||
public function testCanInspectRejectedPromiseWithNormalException()
|
||||
{
|
||||
$e = new \Exception('foo');
|
||||
$p = new RejectedPromise($e);
|
||||
$this->assertEquals([
|
||||
'state' => 'rejected',
|
||||
'reason' => $e
|
||||
], \GuzzleHttp\Promise\inspect($p));
|
||||
}
|
||||
|
||||
public function testCallsEachLimit()
|
||||
{
|
||||
$p = new Promise();
|
||||
$aggregate = \GuzzleHttp\Promise\each_limit($p, 2);
|
||||
$p->resolve('a');
|
||||
P\queue()->run();
|
||||
$this->assertEquals($p::FULFILLED, $aggregate->getState());
|
||||
}
|
||||
|
||||
public function testEachLimitAllRejectsOnFailure()
|
||||
{
|
||||
$p = [new FulfilledPromise('a'), new RejectedPromise('b')];
|
||||
$aggregate = \GuzzleHttp\Promise\each_limit_all($p, 2);
|
||||
P\queue()->run();
|
||||
$this->assertEquals(P\PromiseInterface::REJECTED, $aggregate->getState());
|
||||
$result = \GuzzleHttp\Promise\inspect($aggregate);
|
||||
$this->assertEquals('b', $result['reason']);
|
||||
}
|
||||
|
||||
public function testIterForReturnsIterator()
|
||||
{
|
||||
$iter = new \ArrayIterator();
|
||||
$this->assertSame($iter, \GuzzleHttp\Promise\iter_for($iter));
|
||||
}
|
||||
|
||||
public function testKnowsIfFulfilled()
|
||||
{
|
||||
$p = new FulfilledPromise(null);
|
||||
$this->assertTrue(P\is_fulfilled($p));
|
||||
$this->assertFalse(P\is_rejected($p));
|
||||
}
|
||||
|
||||
public function testKnowsIfRejected()
|
||||
{
|
||||
$p = new RejectedPromise(null);
|
||||
$this->assertTrue(P\is_rejected($p));
|
||||
$this->assertFalse(P\is_fulfilled($p));
|
||||
}
|
||||
|
||||
public function testKnowsIfSettled()
|
||||
{
|
||||
$p = new RejectedPromise(null);
|
||||
$this->assertTrue(P\is_settled($p));
|
||||
$p = new Promise();
|
||||
$this->assertFalse(P\is_settled($p));
|
||||
}
|
||||
|
||||
public function testReturnsTrampoline()
|
||||
{
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\TaskQueue', P\queue());
|
||||
$this->assertSame(P\queue(), P\queue());
|
||||
}
|
||||
|
||||
public function testCanScheduleThunk()
|
||||
{
|
||||
$tramp = P\queue();
|
||||
$promise = P\task(function () { return 'Hi!'; });
|
||||
$c = null;
|
||||
$promise->then(function ($v) use (&$c) { $c = $v; });
|
||||
$this->assertNull($c);
|
||||
$tramp->run();
|
||||
$this->assertEquals('Hi!', $c);
|
||||
}
|
||||
|
||||
public function testCanScheduleThunkWithRejection()
|
||||
{
|
||||
$tramp = P\queue();
|
||||
$promise = P\task(function () { throw new \Exception('Hi!'); });
|
||||
$c = null;
|
||||
$promise->otherwise(function ($v) use (&$c) { $c = $v; });
|
||||
$this->assertNull($c);
|
||||
$tramp->run();
|
||||
$this->assertEquals('Hi!', $c->getMessage());
|
||||
}
|
||||
|
||||
public function testCanScheduleThunkWithWait()
|
||||
{
|
||||
$tramp = P\queue();
|
||||
$promise = P\task(function () { return 'a'; });
|
||||
$this->assertEquals('a', $promise->wait());
|
||||
$tramp->run();
|
||||
}
|
||||
|
||||
public function testYieldsFromCoroutine()
|
||||
{
|
||||
$promise = P\coroutine(function () {
|
||||
$value = (yield new P\FulfilledPromise('a'));
|
||||
yield $value . 'b';
|
||||
});
|
||||
$promise->then(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals('ab', $result);
|
||||
}
|
||||
|
||||
public function testCanCatchExceptionsInCoroutine()
|
||||
{
|
||||
$promise = P\coroutine(function () {
|
||||
try {
|
||||
yield new P\RejectedPromise('a');
|
||||
$this->fail('Should have thrown into the coroutine!');
|
||||
} catch (P\RejectionException $e) {
|
||||
$value = (yield new P\FulfilledPromise($e->getReason()));
|
||||
yield $value . 'b';
|
||||
}
|
||||
});
|
||||
$promise->then(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(P\PromiseInterface::FULFILLED, $promise->getState());
|
||||
$this->assertEquals('ab', $result);
|
||||
}
|
||||
|
||||
public function testRejectsParentExceptionWhenException()
|
||||
{
|
||||
$promise = P\coroutine(function () {
|
||||
yield new P\FulfilledPromise(0);
|
||||
throw new \Exception('a');
|
||||
});
|
||||
$promise->then(
|
||||
function () { $this->fail(); },
|
||||
function ($reason) use (&$result) { $result = $reason; }
|
||||
);
|
||||
P\queue()->run();
|
||||
$this->assertInstanceOf('Exception', $result);
|
||||
$this->assertEquals('a', $result->getMessage());
|
||||
}
|
||||
|
||||
public function testCanRejectFromRejectionCallback()
|
||||
{
|
||||
$promise = P\coroutine(function () {
|
||||
yield new P\FulfilledPromise(0);
|
||||
yield new P\RejectedPromise('no!');
|
||||
});
|
||||
$promise->then(
|
||||
function () { $this->fail(); },
|
||||
function ($reason) use (&$result) { $result = $reason; }
|
||||
);
|
||||
P\queue()->run();
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\RejectionException', $result);
|
||||
$this->assertEquals('no!', $result->getReason());
|
||||
}
|
||||
|
||||
public function testCanAsyncReject()
|
||||
{
|
||||
$rej = new P\Promise();
|
||||
$promise = P\coroutine(function () use ($rej) {
|
||||
yield new P\FulfilledPromise(0);
|
||||
yield $rej;
|
||||
});
|
||||
$promise->then(
|
||||
function () { $this->fail(); },
|
||||
function ($reason) use (&$result) { $result = $reason; }
|
||||
);
|
||||
$rej->reject('no!');
|
||||
P\queue()->run();
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\RejectionException', $result);
|
||||
$this->assertEquals('no!', $result->getReason());
|
||||
}
|
||||
|
||||
public function testCanCatchAndThrowOtherException()
|
||||
{
|
||||
$promise = P\coroutine(function () {
|
||||
try {
|
||||
yield new P\RejectedPromise('a');
|
||||
$this->fail('Should have thrown into the coroutine!');
|
||||
} catch (P\RejectionException $e) {
|
||||
throw new \Exception('foo');
|
||||
}
|
||||
});
|
||||
$promise->otherwise(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(P\PromiseInterface::REJECTED, $promise->getState());
|
||||
$this->assertContains('foo', $result->getMessage());
|
||||
}
|
||||
|
||||
public function testCanCatchAndYieldOtherException()
|
||||
{
|
||||
$promise = P\coroutine(function () {
|
||||
try {
|
||||
yield new P\RejectedPromise('a');
|
||||
$this->fail('Should have thrown into the coroutine!');
|
||||
} catch (P\RejectionException $e) {
|
||||
yield new P\RejectedPromise('foo');
|
||||
}
|
||||
});
|
||||
$promise->otherwise(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(P\PromiseInterface::REJECTED, $promise->getState());
|
||||
$this->assertContains('foo', $result->getMessage());
|
||||
}
|
||||
|
||||
public function createLotsOfSynchronousPromise()
|
||||
{
|
||||
return P\coroutine(function () {
|
||||
$value = 0;
|
||||
for ($i = 0; $i < 1000; $i++) {
|
||||
$value = (yield new P\FulfilledPromise($i));
|
||||
}
|
||||
yield $value;
|
||||
});
|
||||
}
|
||||
|
||||
public function testLotsOfSynchronousDoesNotBlowStack()
|
||||
{
|
||||
$promise = $this->createLotsOfSynchronousPromise();
|
||||
$promise->then(function ($v) use (&$r) { $r = $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(999, $r);
|
||||
}
|
||||
|
||||
public function testLotsOfSynchronousWaitDoesNotBlowStack()
|
||||
{
|
||||
$promise = $this->createLotsOfSynchronousPromise();
|
||||
$promise->then(function ($v) use (&$r) { $r = $v; });
|
||||
$this->assertEquals(999, $promise->wait());
|
||||
$this->assertEquals(999, $r);
|
||||
}
|
||||
|
||||
private function createLotsOfFlappingPromise()
|
||||
{
|
||||
return P\coroutine(function () {
|
||||
$value = 0;
|
||||
for ($i = 0; $i < 1000; $i++) {
|
||||
try {
|
||||
if ($i % 2) {
|
||||
$value = (yield new P\FulfilledPromise($i));
|
||||
} else {
|
||||
$value = (yield new P\RejectedPromise($i));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$value = (yield new P\FulfilledPromise($i));
|
||||
}
|
||||
}
|
||||
yield $value;
|
||||
});
|
||||
}
|
||||
|
||||
public function testLotsOfTryCatchingDoesNotBlowStack()
|
||||
{
|
||||
$promise = $this->createLotsOfFlappingPromise();
|
||||
$promise->then(function ($v) use (&$r) { $r = $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(999, $r);
|
||||
}
|
||||
|
||||
public function testLotsOfTryCatchingWaitingDoesNotBlowStack()
|
||||
{
|
||||
$promise = $this->createLotsOfFlappingPromise();
|
||||
$promise->then(function ($v) use (&$r) { $r = $v; });
|
||||
$this->assertEquals(999, $promise->wait());
|
||||
$this->assertEquals(999, $r);
|
||||
}
|
||||
|
||||
public function testAsyncPromisesWithCorrectlyYieldedValues()
|
||||
{
|
||||
$promises = [
|
||||
new P\Promise(),
|
||||
new P\Promise(),
|
||||
new P\Promise()
|
||||
];
|
||||
|
||||
$promise = P\coroutine(function () use ($promises) {
|
||||
$value = null;
|
||||
$this->assertEquals('skip', (yield new P\FulfilledPromise('skip')));
|
||||
foreach ($promises as $idx => $p) {
|
||||
$value = (yield $p);
|
||||
$this->assertEquals($value, $idx);
|
||||
$this->assertEquals('skip', (yield new P\FulfilledPromise('skip')));
|
||||
}
|
||||
$this->assertEquals('skip', (yield new P\FulfilledPromise('skip')));
|
||||
yield $value;
|
||||
});
|
||||
|
||||
$promises[0]->resolve(0);
|
||||
$promises[1]->resolve(1);
|
||||
$promises[2]->resolve(2);
|
||||
|
||||
$promise->then(function ($v) use (&$r) { $r = $v; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals(2, $r);
|
||||
}
|
||||
|
||||
public function testYieldFinalWaitablePromise()
|
||||
{
|
||||
$p1 = new P\Promise(function () use (&$p1) {
|
||||
$p1->resolve('skip me');
|
||||
});
|
||||
$p2 = new P\Promise(function () use (&$p2) {
|
||||
$p2->resolve('hello!');
|
||||
});
|
||||
$co = P\coroutine(function() use ($p1, $p2) {
|
||||
yield $p1;
|
||||
yield $p2;
|
||||
});
|
||||
P\queue()->run();
|
||||
$this->assertEquals('hello!', $co->wait());
|
||||
}
|
||||
|
||||
public function testCanYieldFinalPendingPromise()
|
||||
{
|
||||
$p1 = new P\Promise();
|
||||
$p2 = new P\Promise();
|
||||
$co = P\coroutine(function() use ($p1, $p2) {
|
||||
yield $p1;
|
||||
yield $p2;
|
||||
});
|
||||
$p1->resolve('a');
|
||||
$p2->resolve('b');
|
||||
$co->then(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals('b', $result);
|
||||
}
|
||||
|
||||
public function testCanNestYieldsAndFailures()
|
||||
{
|
||||
$p1 = new P\Promise();
|
||||
$p2 = new P\Promise();
|
||||
$p3 = new P\Promise();
|
||||
$p4 = new P\Promise();
|
||||
$p5 = new P\Promise();
|
||||
$co = P\coroutine(function() use ($p1, $p2, $p3, $p4, $p5) {
|
||||
try {
|
||||
yield $p1;
|
||||
} catch (\Exception $e) {
|
||||
yield $p2;
|
||||
try {
|
||||
yield $p3;
|
||||
yield $p4;
|
||||
} catch (\Exception $e) {
|
||||
yield $p5;
|
||||
}
|
||||
}
|
||||
});
|
||||
$p1->reject('a');
|
||||
$p2->resolve('b');
|
||||
$p3->resolve('c');
|
||||
$p4->reject('d');
|
||||
$p5->resolve('e');
|
||||
$co->then(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals('e', $result);
|
||||
}
|
||||
|
||||
public function testCanYieldErrorsAndSuccessesWithoutRecursion()
|
||||
{
|
||||
$promises = [];
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
$promises[] = new P\Promise();
|
||||
}
|
||||
|
||||
$co = P\coroutine(function() use ($promises) {
|
||||
for ($i = 0; $i < 20; $i += 4) {
|
||||
try {
|
||||
yield $promises[$i];
|
||||
yield $promises[$i + 1];
|
||||
} catch (\Exception $e) {
|
||||
yield $promises[$i + 2];
|
||||
yield $promises[$i + 3];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for ($i = 0; $i < 20; $i += 4) {
|
||||
$promises[$i]->resolve($i);
|
||||
$promises[$i + 1]->reject($i + 1);
|
||||
$promises[$i + 2]->resolve($i + 2);
|
||||
$promises[$i + 3]->resolve($i + 3);
|
||||
}
|
||||
|
||||
$co->then(function ($value) use (&$result) { $result = $value; });
|
||||
P\queue()->run();
|
||||
$this->assertEquals('19', $result);
|
||||
}
|
||||
|
||||
public function testCanWaitOnPromiseAfterFulfilled()
|
||||
{
|
||||
$f = function () {
|
||||
static $i = 0;
|
||||
$i++;
|
||||
return $p = new P\Promise(function () use (&$p, $i) {
|
||||
$p->resolve($i . '-bar');
|
||||
});
|
||||
};
|
||||
|
||||
$promises = [];
|
||||
for ($i = 0; $i < 20; $i++) {
|
||||
$promises[] = $f();
|
||||
}
|
||||
|
||||
$p = P\coroutine(function () use ($promises) {
|
||||
yield new P\FulfilledPromise('foo!');
|
||||
foreach ($promises as $promise) {
|
||||
yield $promise;
|
||||
}
|
||||
});
|
||||
|
||||
$this->assertEquals('20-bar', $p->wait());
|
||||
}
|
||||
|
||||
public function testCanWaitOnErroredPromises()
|
||||
{
|
||||
$p1 = new P\Promise(function () use (&$p1) { $p1->reject('a'); });
|
||||
$p2 = new P\Promise(function () use (&$p2) { $p2->resolve('b'); });
|
||||
$p3 = new P\Promise(function () use (&$p3) { $p3->resolve('c'); });
|
||||
$p4 = new P\Promise(function () use (&$p4) { $p4->reject('d'); });
|
||||
$p5 = new P\Promise(function () use (&$p5) { $p5->resolve('e'); });
|
||||
$p6 = new P\Promise(function () use (&$p6) { $p6->reject('f'); });
|
||||
|
||||
$co = P\coroutine(function() use ($p1, $p2, $p3, $p4, $p5, $p6) {
|
||||
try {
|
||||
yield $p1;
|
||||
} catch (\Exception $e) {
|
||||
yield $p2;
|
||||
try {
|
||||
yield $p3;
|
||||
yield $p4;
|
||||
} catch (\Exception $e) {
|
||||
yield $p5;
|
||||
yield $p6;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$res = P\inspect($co);
|
||||
$this->assertEquals('f', $res['reason']);
|
||||
}
|
||||
|
||||
public function testCoroutineOtherwiseIntegrationTest()
|
||||
{
|
||||
$a = new P\Promise();
|
||||
$b = new P\Promise();
|
||||
$promise = P\coroutine(function () use ($a, $b) {
|
||||
// Execute the pool of commands concurrently, and process errors.
|
||||
yield $a;
|
||||
yield $b;
|
||||
})->otherwise(function (\Exception $e) {
|
||||
// Throw errors from the operations as a specific Multipart error.
|
||||
throw new \OutOfBoundsException('a', 0, $e);
|
||||
});
|
||||
$a->resolve('a');
|
||||
$b->reject('b');
|
||||
$reason = P\inspect($promise)['reason'];
|
||||
$this->assertInstanceOf('OutOfBoundsException', $reason);
|
||||
$this->assertInstanceOf('GuzzleHttp\Promise\RejectionException', $reason->getPrevious());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user