Skip to content

Commit

Permalink
Merge pull request #116 from php-http/feature/http-specific-promise
Browse files Browse the repository at this point in the history
Add specific http promise
  • Loading branch information
Nyholm authored Aug 31, 2016
2 parents 5183cf8 + 67ce613 commit 5343ca1
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
76 changes: 76 additions & 0 deletions spec/Promise/HttpFulfilledPromiseSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace spec\Http\Client\Promise;

use Http\Client\Exception\TransferException;
use Http\Promise\Promise;
use PhpSpec\ObjectBehavior;
use Psr\Http\Message\ResponseInterface;

class HttpFulfilledPromiseSpec extends ObjectBehavior
{
function let(ResponseInterface $response)
{
$this->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);
}
}
90 changes: 90 additions & 0 deletions spec/Promise/HttpRejectedPromiseSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace spec\Http\Client\Promise;

use Http\Client\Exception;
use Http\Client\Exception\TransferException;
use Http\Promise\Promise;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Psr\Http\Message\ResponseInterface;

class HttpRejectedPromiseSpec extends ObjectBehavior
{
function let()
{
$this->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();
});
}
}
57 changes: 57 additions & 0 deletions src/Promise/HttpFulfilledPromise.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace Http\Client\Promise;

use Http\Client\Exception;
use Http\Promise\Promise;
use Psr\Http\Message\ResponseInterface;

final class HttpFulfilledPromise implements Promise
{
/**
* @var ResponseInterface
*/
private $response;

/**
* @param ResponseInterface $response
*/
public function __construct(ResponseInterface $response)
{
$this->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;
}
}
}
56 changes: 56 additions & 0 deletions src/Promise/HttpRejectedPromise.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Http\Client\Promise;

use Http\Client\Exception;
use Http\Promise\Promise;

final class HttpRejectedPromise implements Promise
{
/**
* @var Exception
*/
private $exception;

/**
* @param Exception $exception
*/
public function __construct(Exception $exception)
{
$this->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;
}
}
}

0 comments on commit 5343ca1

Please sign in to comment.