1
0
mirror of https://github.com/guzzle/guzzle.git synced 2025-02-24 10:03:27 +01:00

Ensuring that futures are created or not created based on the future request attribute

This commit is contained in:
Michael Dowling 2014-10-01 17:24:47 -07:00
parent 0c21db3822
commit bfef02f98b
3 changed files with 59 additions and 22 deletions

View File

@ -226,11 +226,33 @@ class Client implements ClientInterface
public function send(RequestInterface $request)
{
$trans = new Transaction($this, $request);
$this->fsm->run($trans);
$response = $trans->response;
// Remove the response from the transaction to prevent future responses
// from returning themselves in an infinite loop when dereferenced.
$trans->response = null;
$needsFuture = $request->getConfig()->get('future');
// Return a future if one was requested.
try {
$this->fsm->run($trans);
$response = $trans->response;
} catch (\Exception $e) {
if (!$needsFuture) {
throw $e;
}
// Wrap the exception if the user asked for a future.
return new FutureResponse(function () use ($e) {
throw $e;
});
}
if ($response instanceof FutureInterface) {
// Don't deref cancelled responses here.
if (!$response->cancelled() && !$needsFuture) {
$response = $response->deref();
}
} elseif ($needsFuture) {
// Create a future if one was requested
$response = new FutureResponse(function () use ($response) {
return $response;
});
}
return $response;
}

View File

@ -347,19 +347,6 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$client->get('http://httpbin.org')->deref();
}
/**
* @expectedException \GuzzleHttp\Exception\RequestException
* @expectedExceptionMessage not calling the "then"
*/
public function testEnsuresResponseIsPresentAfterDereferencingWithBrokenAdapter()
{
$adapter = function () {
return new RingFuture(function () { return []; });
};
$client = new Client(['adapter' => $adapter]);
$client->get('http://httpbin.org')->deref();
}
public function testClientHandlesErrorsDuringBeforeSend()
{
$client = new Client();
@ -412,6 +399,7 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$client = new Client(['adapter' => $mock]);
$called = 0;
$response = $client->get('http://localhost:123/foo', [
'future' => true,
'events' => [
'error' => function (ErrorEvent $e) use (&$called) {
$called++;
@ -435,7 +423,7 @@ class ClientTest extends \PHPUnit_Framework_TestCase
});
$mock = new MockAdapter($future);
$client = new Client(['adapter' => $mock]);
$response = $client->get('http://localhost:123/foo');
$response = $client->get('http://localhost:123/foo', ['future' => true]);
$this->assertFalse($called);
$this->assertInstanceOf('GuzzleHttp\Message\FutureResponse', $response);
$this->assertEquals(201, $response->getStatusCode());
@ -554,4 +542,31 @@ class ClientTest extends \PHPUnit_Framework_TestCase
$res = $client->send($request);
$this->assertInstanceOf('GuzzleHttp\Message\CancelledResponse', $res);
}
public function testReturnsFutureForErrorWhenRequested()
{
$client = new Client(['adapter' => new MockAdapter(['status' => 404])]);
$request = $client->createRequest('GET', 'http://localhost:123/foo', [
'future' => true
]);
$res = $client->send($request);
$this->assertInstanceOf('GuzzleHttp\Message\FutureResponse', $res);
try {
$res->deref();
$this->fail('did not throw');
} catch (RequestException $e) {
$this->assertContains('404', $e->getMessage());
}
}
public function testReturnsFutureForResponseWhenRequested()
{
$client = new Client(['adapter' => new MockAdapter(['status' => 200])]);
$request = $client->createRequest('GET', 'http://localhost:123/foo', [
'future' => true
]);
$res = $client->send($request);
$this->assertInstanceOf('GuzzleHttp\Message\FutureResponse', $res);
$this->assertEquals(200, $res->getStatusCode());
}
}

View File

@ -109,7 +109,7 @@ class MockTest extends \PHPUnit_Framework_TestCase
public function testCanMockFutureResponses()
{
$client = new Client(['base_url' => 'http://test.com']);
$request = $client->createRequest('GET', '/');
$request = $client->createRequest('GET', '/', ['future' => true]);
$response = new Response(200);
$future = new FutureResponse(function () use ($response) {
return $response;
@ -126,7 +126,7 @@ class MockTest extends \PHPUnit_Framework_TestCase
public function testCanMockExceptionFutureResponses()
{
$client = new Client(['base_url' => 'http://test.com']);
$request = $client->createRequest('GET', '/');
$request = $client->createRequest('GET', '/', ['future' => true]);
$future = new FutureResponse(function () use ($request) {
throw new RequestException('foo', $request);
@ -149,7 +149,7 @@ class MockTest extends \PHPUnit_Framework_TestCase
public function testCanMockFailedFutureResponses()
{
$client = new Client(['base_url' => 'http://test.com']);
$request = $client->createRequest('GET', '/');
$request = $client->createRequest('GET', '/', ['future' => true]);
// The first mock will be a mocked future response.
$future = new FutureResponse(function () use ($client) {