diff --git a/CHANGELOG.md b/CHANGELOG.md index 05dd126..29d9af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## 1.1.0 - Unreleased + +- Added HttpFulfilledPromise and HttpRejectedPromise which respect the HttpAsyncClient interface ## 1.0.0 - 2016-01-26 diff --git a/spec/Promise/HttpFulfilledPromiseSpec.php b/spec/Promise/HttpFulfilledPromiseSpec.php new file mode 100644 index 0000000..b58da8c --- /dev/null +++ b/spec/Promise/HttpFulfilledPromiseSpec.php @@ -0,0 +1,76 @@ +beConstructedWith($response); + } + + function it_is_initializable() + { + $this->shouldHaveType('Http\Client\Promise\HttpFulfilledPromise'); + } + + function it_is_a_promise() + { + $this->shouldImplement('Http\Promise\Promise'); + } + + function it_returns_a_http_fulfilled_promise() + { + $promise = $this->then(function ($result) { + return $result; + }); + $promise->shouldHaveType('Http\Promise\Promise'); + $promise->shouldHaveType('Http\Client\Promise\HttpFulfilledPromise'); + $promise->getState()->shouldReturn(Promise::FULFILLED); + $promise->wait()->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface'); + } + + function it_returns_a_http_rejected_promise() + { + $exception = new TransferException(); + $promise = $this->then(function () use ($exception) { + throw $exception; + }); + $promise->shouldHaveType('Http\Promise\Promise'); + $promise->shouldHaveType('Http\Client\Promise\HttpRejectedPromise'); + $promise->getState()->shouldReturn(Promise::REJECTED); + $promise->shouldThrow($exception)->duringWait(); + } + + function it_returns_itself_when_no_on_fulfilled_callback_is_passed() + { + $this->then()->shouldReturn($this); + } + + function it_is_in_fulfilled_state() + { + $this->getState()->shouldReturn(Promise::FULFILLED); + } + + function it_has_a_response() + { + $this->wait()->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface'); + } + + function it_does_not_unwrap_a_response() + { + $this->wait(false)->shouldNotReturnAnInstanceOf('Psr\Http\Message\ResponseInterface'); + } + + function it_throws_not_http_exception() + { + $this->shouldThrow('Exception')->duringThen(function () { + throw new \Exception(); + }, null); + } +} diff --git a/spec/Promise/HttpRejectedPromiseSpec.php b/spec/Promise/HttpRejectedPromiseSpec.php new file mode 100644 index 0000000..f46dcc5 --- /dev/null +++ b/spec/Promise/HttpRejectedPromiseSpec.php @@ -0,0 +1,90 @@ +beConstructedWith(new TransferException()); + } + + function it_is_initializable() + { + $this->shouldHaveType('Http\Client\Promise\HttpRejectedPromise'); + } + + function it_is_a_promise() + { + $this->shouldImplement('Http\Promise\Promise'); + } + + function it_returns_a_fulfilled_promise(ResponseInterface $response) + { + $exception = new TransferException(); + $this->beConstructedWith($exception); + + $promise = $this->then(null, function (Exception $exceptionReceived) use($exception, $response) { + return $response->getWrappedObject(); + }); + + $promise->shouldHaveType('Http\Promise\Promise'); + $promise->shouldHaveType('Http\Client\Promise\HttpFulfilledPromise'); + $promise->getState()->shouldReturn(Promise::FULFILLED); + $promise->wait()->shouldReturnAnInstanceOf('Psr\Http\Message\ResponseInterface'); + } + + function it_returns_a_rejected_promise() + { + $exception = new TransferException(); + $this->beConstructedWith($exception); + + $promise = $this->then(null, function (Exception $exceptionReceived) use($exception) { + if (Argument::is($exceptionReceived)->scoreArgument($exception)) { + throw $exception; + } + }); + + $promise->shouldHaveType('Http\Promise\Promise'); + $promise->shouldHaveType('Http\Client\Promise\HttpRejectedPromise'); + $promise->getState()->shouldReturn(Promise::REJECTED); + $promise->shouldThrow($exception)->duringWait(); + } + + function it_returns_itself_when_no_on_rejected_callback_is_passed() + { + $this->then()->shouldReturn($this); + } + + function it_is_in_rejected_state() + { + $this->getState()->shouldReturn(Promise::REJECTED); + } + + function it_returns_an_exception() + { + $exception = new TransferException(); + + $this->beConstructedWith($exception); + $this->shouldThrow($exception)->duringWait(); + } + + function it_does_not_unwrap_a_value() + { + $this->shouldNotThrow('Http\Client\Exception')->duringWait(false); + } + + function it_throws_not_http_exception() + { + $this->shouldThrow('Exception')->duringThen(null, function () { + throw new \Exception(); + }); + } +} diff --git a/src/Promise/HttpFulfilledPromise.php b/src/Promise/HttpFulfilledPromise.php new file mode 100644 index 0000000..6779e44 --- /dev/null +++ b/src/Promise/HttpFulfilledPromise.php @@ -0,0 +1,57 @@ +response = $response; + } + + /** + * {@inheritdoc} + */ + public function then(callable $onFulfilled = null, callable $onRejected = null) + { + if (null === $onFulfilled) { + return $this; + } + + try { + return new self($onFulfilled($this->response)); + } catch (Exception $e) { + return new HttpRejectedPromise($e); + } + } + + /** + * {@inheritdoc} + */ + public function getState() + { + return Promise::FULFILLED; + } + + /** + * {@inheritdoc} + */ + public function wait($unwrap = true) + { + if ($unwrap) { + return $this->response; + } + } +} diff --git a/src/Promise/HttpRejectedPromise.php b/src/Promise/HttpRejectedPromise.php new file mode 100644 index 0000000..bfb0738 --- /dev/null +++ b/src/Promise/HttpRejectedPromise.php @@ -0,0 +1,56 @@ +exception = $exception; + } + + /** + * {@inheritdoc} + */ + public function then(callable $onFulfilled = null, callable $onRejected = null) + { + if (null === $onRejected) { + return $this; + } + + try { + return new HttpFulfilledPromise($onRejected($this->exception)); + } catch (Exception $e) { + return new self($e); + } + } + + /** + * {@inheritdoc} + */ + public function getState() + { + return Promise::REJECTED; + } + + /** + * {@inheritdoc} + */ + public function wait($unwrap = true) + { + if ($unwrap) { + throw $this->exception; + } + } +}