Skip to content

Commit 4d59cc4

Browse files
authored
Merge pull request #123 from php-http/mark-as-final
mark classes as final and methods and properties as private
2 parents 5541efd + fadb51a commit 4d59cc4

23 files changed

+326
-306
lines changed

Diff for: CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
- RetryPlugin will no longer retry requests when the response failed with a HTTP code < 500.
77
- Abstract method `HttpClientPool::chooseHttpClient()` has now an explicit return type (`Http\Client\Common\HttpClientPoolItem`)
88
- Interface method `Plugin::handleRequest(...)` has now an explicit return type (`Http\Promise\Promise`)
9+
- Made classes final that are not intended to be extended.
10+
Added interfaces for BatchClient, HttpClientRouter and HttpMethodsClient.
11+
(These interfaces use the `Interface` suffix to avoid name collisions.)
12+
- Added an interface for HttpClientPool and moved the abstract class to the HttpClientPool sub namespace.
913

1014
### Removed
1115
- Deprecated option `debug_plugins` has been removed from `PluginClient`

Diff for: spec/HttpClientPoolItemSpec.php renamed to spec/HttpClientPool/HttpClientPoolItemSpec.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace spec\Http\Client\Common;
3+
namespace spec\Http\Client\Common\HttpClientPool;
44

55
use Http\Client\Exception;
66
use Http\Client\Exception\TransferException;

Diff for: spec/HttpClientPool/LeastUsedClientPoolSpec.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace spec\Http\Client\Common\HttpClientPool;
44

5-
use Http\Client\Common\HttpClientPoolItem;
5+
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
66
use Http\Client\HttpAsyncClient;
77
use Http\Client\HttpClient;
88
use Http\Promise\Promise;

Diff for: spec/HttpClientPool/RandomClientPoolSpec.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace spec\Http\Client\Common\HttpClientPool;
44

5-
use Http\Client\Common\HttpClientPoolItem;
5+
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
66
use Http\Client\HttpAsyncClient;
77
use Http\Client\HttpClient;
88
use Http\Promise\Promise;

Diff for: spec/HttpClientPool/RoundRobinClientPoolSpec.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace spec\Http\Client\Common\HttpClientPool;
44

5-
use Http\Client\Common\HttpClientPoolItem;
5+
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
66
use Http\Client\HttpAsyncClient;
77
use Http\Client\HttpClient;
88
use Http\Promise\Promise;

Diff for: spec/HttpClientRouterSpec.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
namespace spec\Http\Client\Common;
44

5+
use Http\Client\Common\HttpClientRouter;
56
use Http\Message\RequestMatcher;
67
use Http\Client\HttpAsyncClient;
78
use Http\Client\HttpClient;
89
use Http\Promise\Promise;
910
use Psr\Http\Message\RequestInterface;
1011
use Psr\Http\Message\ResponseInterface;
1112
use PhpSpec\ObjectBehavior;
12-
use Http\Client\Common\HttpClientRouter;
13+
use Http\Client\Common\HttpClientRouterInterface;
1314
use Http\Client\Exception\RequestException;
1415

1516
class HttpClientRouterSpec extends ObjectBehavior
@@ -19,6 +20,11 @@ public function it_is_initializable()
1920
$this->shouldHaveType(HttpClientRouter::class);
2021
}
2122

23+
public function it_is_an_http_client_router()
24+
{
25+
$this->shouldImplement(HttpClientRouterInterface::class);
26+
}
27+
2228
public function it_is_an_http_client()
2329
{
2430
$this->shouldImplement(HttpClient::class);

Diff for: spec/HttpMethodsClientSpec.php

+38-85
Original file line numberDiff line numberDiff line change
@@ -2,135 +2,88 @@
22

33
namespace spec\Http\Client\Common;
44

5-
use GuzzleHttp\Psr7\Response;
65
use Http\Client\Common\HttpMethodsClient;
76
use Http\Client\HttpClient;
8-
use Http\Message\MessageFactory;
7+
use Http\Message\RequestFactory;
98
use PhpSpec\ObjectBehavior;
109
use Psr\Http\Message\RequestInterface;
1110
use Psr\Http\Message\ResponseInterface;
1211

1312
class HttpMethodsClientSpec extends ObjectBehavior
1413
{
15-
public function let(HttpClient $client, MessageFactory $messageFactory)
14+
private static $requestData = [
15+
'uri' => '/uri',
16+
'headers' => [
17+
'Content-Type' => 'text/plain',
18+
],
19+
'body' => 'body',
20+
];
21+
22+
public function let(HttpClient $client, RequestFactory $requestFactory)
1623
{
1724
$this->beAnInstanceOf(
18-
HttpMethodsClientStub::class, [
25+
HttpMethodsClient::class, [
1926
$client,
20-
$messageFactory,
27+
$requestFactory,
2128
]
2229
);
2330
}
2431

25-
public function it_sends_a_get_request()
32+
public function it_sends_a_get_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response)
2633
{
27-
$data = HttpMethodsClientStub::$requestData;
28-
29-
$this->get($data['uri'], $data['headers'])->shouldReturnAnInstanceOf(ResponseInterface::class);
34+
$this->assert($client, $requestFactory, $request, $response, 'get');
3035
}
3136

32-
public function it_sends_a_head_request()
37+
public function it_sends_a_head_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response)
3338
{
34-
$data = HttpMethodsClientStub::$requestData;
35-
36-
$this->head($data['uri'], $data['headers'])->shouldReturnAnInstanceOf(ResponseInterface::class);
39+
$this->assert($client, $requestFactory, $request, $response, 'head');
3740
}
3841

39-
public function it_sends_a_trace_request()
42+
public function it_sends_a_trace_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response)
4043
{
41-
$data = HttpMethodsClientStub::$requestData;
42-
43-
$this->trace($data['uri'], $data['headers'])->shouldReturnAnInstanceOf(ResponseInterface::class);
44+
$this->assert($client, $requestFactory, $request, $response, 'trace');
4445
}
4546

46-
public function it_sends_a_post_request()
47+
public function it_sends_a_post_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response)
4748
{
48-
$data = HttpMethodsClientStub::$requestData;
49-
50-
$this->post($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class);
49+
$this->assert($client, $requestFactory, $request, $response, 'post', self::$requestData['body']);
5150
}
5251

53-
public function it_sends_a_put_request()
52+
public function it_sends_a_put_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response)
5453
{
55-
$data = HttpMethodsClientStub::$requestData;
56-
57-
$this->put($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class);
54+
$this->assert($client, $requestFactory, $request, $response, 'put', self::$requestData['body']);
5855
}
5956

60-
public function it_sends_a_patch_request()
57+
public function it_sends_a_patch_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response)
6158
{
62-
$data = HttpMethodsClientStub::$requestData;
63-
64-
$this->patch($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class);
59+
$this->assert($client, $requestFactory, $request, $response, 'patch', self::$requestData['body']);
6560
}
6661

67-
public function it_sends_a_delete_request()
62+
public function it_sends_a_delete_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response)
6863
{
69-
$data = HttpMethodsClientStub::$requestData;
70-
71-
$this->delete($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class);
64+
$this->assert($client, $requestFactory, $request, $response, 'delete', self::$requestData['body']);
7265
}
7366

74-
public function it_sends_a_options_request()
67+
public function it_sends_an_options_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response)
7568
{
76-
$data = HttpMethodsClientStub::$requestData;
77-
78-
$this->options($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class);
69+
$this->assert($client, $requestFactory, $request, $response, 'options', self::$requestData['body']);
7970
}
8071

81-
public function it_sends_request_with_underlying_client(HttpClient $client, MessageFactory $messageFactory, RequestInterface $request, ResponseInterface $response)
72+
/**
73+
* Run the actual test.
74+
*
75+
* As there is no data provider in phpspec, we keep separate methods to get new mocks for each test.
76+
*/
77+
private function assert(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response, string $method, string $body = null)
8278
{
8379
$client->sendRequest($request)->shouldBeCalled()->willReturn($response);
80+
$this->mockFactory($requestFactory, $request, strtoupper($method), $body);
8481

85-
$this->beConstructedWith($client, $messageFactory);
86-
$this->sendRequest($request)->shouldReturn($response);
82+
$this->$method(self::$requestData['uri'], self::$requestData['headers'], self::$requestData['body'])->shouldReturnAnInstanceOf(ResponseInterface::class);
8783
}
88-
}
89-
90-
class HttpMethodsClientStub extends HttpMethodsClient
91-
{
92-
public static $requestData = [
93-
'uri' => '/uri',
94-
'headers' => [
95-
'Content-Type' => 'text/plain',
96-
],
97-
'body' => 'body',
98-
];
9984

100-
/**
101-
* {@inheritdoc}
102-
*/
103-
public function send($method, $uri, array $headers = [], $body = null): ResponseInterface
85+
private function mockFactory(RequestFactory $requestFactory, RequestInterface $request, string $method, string $body = null)
10486
{
105-
if ($uri !== self::$requestData['uri']) {
106-
throw new \InvalidArgumentException('Invalid URI: '.$uri);
107-
}
108-
109-
if ($headers !== self::$requestData['headers']) {
110-
throw new \InvalidArgumentException('Invalid headers: '.print_r($headers, true));
111-
}
112-
113-
switch ($method) {
114-
case 'GET':
115-
case 'HEAD':
116-
case 'TRACE':
117-
if (null !== $body) {
118-
throw new \InvalidArgumentException('Non-empty body');
119-
}
120-
121-
return new Response();
122-
case 'POST':
123-
case 'PUT':
124-
case 'PATCH':
125-
case 'DELETE':
126-
case 'OPTIONS':
127-
if ($body !== self::$requestData['body']) {
128-
throw new \InvalidArgumentException('Invalid body: '.print_r($body, true));
129-
}
130-
131-
return new Response();
132-
default:
133-
throw new \InvalidArgumentException('Invalid method: '.$method);
134-
}
87+
$requestFactory->createRequest($method, self::$requestData['uri'], self::$requestData['headers'], $body)->willReturn($request);
13588
}
13689
}

Diff for: spec/Plugin/AddPathPluginSpec.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function it_adds_path(
4646
$this->handleRequest($request, PluginStub::next(), function () {});
4747
}
4848

49-
function it_removes_ending_slashes(
49+
public function it_removes_ending_slashes(
5050
RequestInterface $request,
5151
UriInterface $host,
5252
UriInterface $host2,

Diff for: src/BatchClient.php

+1-25
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,7 @@
88
use Psr\Http\Message\RequestInterface;
99
use Psr\Http\Message\ResponseInterface;
1010

11-
/**
12-
* BatchClient allow to sends multiple request and retrieve a Batch Result.
13-
*
14-
* This implementation simply loops over the requests and uses sendRequest with each of them.
15-
*
16-
* @author Joel Wurtz <jwurtz@jolicode.com>
17-
*/
18-
class BatchClient implements HttpClient
11+
final class BatchClient implements BatchClientInterface
1912
{
2013
/**
2114
* @var HttpClient
@@ -27,28 +20,11 @@ public function __construct(HttpClient $client)
2720
$this->client = $client;
2821
}
2922

30-
/**
31-
* {@inheritdoc}
32-
*/
3323
public function sendRequest(RequestInterface $request): ResponseInterface
3424
{
3525
return $this->client->sendRequest($request);
3626
}
3727

38-
/**
39-
* Send several requests.
40-
*
41-
* You may not assume that the requests are executed in a particular order. If the order matters
42-
* for your application, use sendRequest sequentially.
43-
*
44-
* @param RequestInterface[] The requests to send
45-
*
46-
* @return BatchResult Containing one result per request
47-
*
48-
* @throws BatchException If one or more requests fails. The exception gives access to the
49-
* BatchResult with a map of request to result for success, request to
50-
* exception for failures
51-
*/
5228
public function sendRequests(array $requests): BatchResult
5329
{
5430
$batchResult = new BatchResult();

Diff for: src/BatchClientInterface.php

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Http\Client\Common;
4+
5+
use Http\Client\Exception;
6+
use Http\Client\HttpClient;
7+
use Http\Client\Common\Exception\BatchException;
8+
use Psr\Http\Message\RequestInterface;
9+
10+
/**
11+
* BatchClient allow to sends multiple request and retrieve a Batch Result.
12+
*
13+
* This implementation simply loops over the requests and uses sendRequest with each of them.
14+
*
15+
* @author Joel Wurtz <jwurtz@jolicode.com>
16+
*/
17+
interface BatchClientInterface extends HttpClient
18+
{
19+
/**
20+
* Send several requests.
21+
*
22+
* You may not assume that the requests are executed in a particular order. If the order matters
23+
* for your application, use sendRequest sequentially.
24+
*
25+
* @param RequestInterface[] The requests to send
26+
*
27+
* @return BatchResult Containing one result per request
28+
*
29+
* @throws BatchException If one or more requests fails. The exception gives access to the
30+
* BatchResult with a map of request to result for success, request to
31+
* exception for failures
32+
*/
33+
public function sendRequests(array $requests): BatchResult;
34+
}

Diff for: src/Deferred.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/**
1010
* A deferred allow to return a promise which has not been resolved yet.
1111
*/
12-
class Deferred implements Promise
12+
final class Deferred implements Promise
1313
{
1414
private $value;
1515

Diff for: src/EmulatedHttpAsyncClient.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@
66
use Http\Client\HttpClient;
77

88
/**
9-
* Emulates an async HTTP client.
10-
*
11-
* This should be replaced by an anonymous class in PHP 7.
9+
* Emulates an async HTTP client with the help of a synchronous client.
1210
*
1311
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
1412
*/
15-
class EmulatedHttpAsyncClient implements HttpClient, HttpAsyncClient
13+
final class EmulatedHttpAsyncClient implements HttpClient, HttpAsyncClient
1614
{
1715
use HttpAsyncClientEmulator;
1816
use HttpClientDecorator;

Diff for: src/EmulatedHttpClient.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@
66
use Http\Client\HttpClient;
77

88
/**
9-
* Emulates an HTTP client.
10-
*
11-
* This should be replaced by an anonymous class in PHP 7.
9+
* Emulates a synchronous HTTP client with the help of an asynchronous client.
1210
*
1311
* @author Márk Sági-Kazár <mark.sagikazar@gmail.com>
1412
*/
15-
class EmulatedHttpClient implements HttpClient, HttpAsyncClient
13+
final class EmulatedHttpClient implements HttpClient, HttpAsyncClient
1614
{
1715
use HttpAsyncClientDecorator;
1816
use HttpClientEmulator;

0 commit comments

Comments
 (0)