Fix unit test deprecations, remove unnecessary docblocks, general clean up

This commit is contained in:
Daniel Winning 2025-05-05 14:39:36 +01:00
parent 7dcdb01136
commit a09f953058
9 changed files with 49 additions and 380 deletions

View file

@ -2,7 +2,7 @@
"name": "loomlabs/http-component",
"description": "A component for handling HTTP Requests/Responses",
"scripts": {
"test": "php -d xdebug.mode=coverage ./vendor/bin/phpunit --testdox --colors=always --coverage-html coverage --coverage-clover coverage/coverage.xml --testdox-html coverage/testdox.html && npx badger --phpunit ./coverage/coverage.xml && npx badger --version ./composer.json && npx badger --license ./composer.json"
"test": "php -d xdebug.mode=coverage ./vendor/bin/phpunit --testdox --colors=always --coverage-html coverage --coverage-clover coverage/coverage.xml --testdox-html coverage/testdox.html && npx badger --version ./composer.json && npx badger --license ./composer.json"
},
"license": "GPL-3.0-or-later",
"require": {

View file

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Loom\HttpComponent;
use Loom\HttpComponent\Traits\ResolveHeadersTrait;
@ -12,39 +14,24 @@ class Request implements RequestInterface
{
use ResolveHeadersTrait;
private UriInterface $uri;
private StreamInterface $body;
private string $method;
private array $headers;
private string $protocolVersion;
public function __construct(
string $method,
UriInterface $uri,
array $headers = [],
StreamInterface $body = null,
string $protocolVersion = '1.1'
private string $method,
private UriInterface $uri,
private array $headers = [],
?StreamInterface $body = null,
private string $protocolVersion = '1.1'
) {
$this->method = $method;
$this->uri = $uri;
$this->headers = $this->setHeaders($headers);
$this->body = $body ?? new Stream(fopen('php://temp', 'r+'));
$this->protocolVersion = $protocolVersion;
}
/**
* @return string
*/
public function getProtocolVersion(): string
{
return $this->protocolVersion;
}
/**
* @param string $version
*
* @return MessageInterface
*/
public function withProtocolVersion(string $version): MessageInterface
{
$request = clone $this;
@ -53,50 +40,29 @@ class Request implements RequestInterface
return $request;
}
/**
* @return array
*/
public function getHeaders(): array
{
return $this->headers;
}
/**
* @param string $name
*
* @return bool
*/
public function hasHeader(string $name): bool
{
return isset($this->headers[strtolower($name)]);
}
/**
* @param string $name
*
* @return array|string[]
* @return string[]
*/
public function getHeader(string $name): array
{
return $this->headers[strtolower($name)] ?? [];
}
/**
* @param string $name
*
* @return string
*/
public function getHeaderLine(string $name): string
{
return implode(', ', $this->getHeader($name));
}
/**
* @param string $name
* @param $value
*
* @return MessageInterface
*/
public function withHeader(string $name, $value): MessageInterface
{
$request = clone $this;
@ -105,12 +71,6 @@ class Request implements RequestInterface
return $request;
}
/**
* @param string $name
* @param $value
*
* @return MessageInterface
*/
public function withAddedHeader(string $name, $value): MessageInterface
{
$name = strtolower($name);
@ -120,11 +80,6 @@ class Request implements RequestInterface
return $request;
}
/**
* @param string $name
*
* @return MessageInterface
*/
public function withoutHeader(string $name): MessageInterface
{
$request = clone $this;
@ -133,19 +88,11 @@ class Request implements RequestInterface
return $request;
}
/**
* @return StreamInterface
*/
public function getBody(): StreamInterface
{
return $this->body;
}
/**
* @param StreamInterface $body
*
* @return MessageInterface
*/
public function withBody(StreamInterface $body): MessageInterface
{
$request = clone $this;
@ -154,9 +101,6 @@ class Request implements RequestInterface
return $request;
}
/**
* @return string
*/
public function getRequestTarget(): string
{
$path = $this->uri->getPath();
@ -167,11 +111,6 @@ class Request implements RequestInterface
: ($query ? sprintf('/?%s', $query) : '/');
}
/**
* @param string $requestTarget
*
* @return RequestInterface
*/
public function withRequestTarget(string $requestTarget): RequestInterface
{
$request = clone $this;
@ -181,19 +120,11 @@ class Request implements RequestInterface
return $request;
}
/**
* @return string
*/
public function getMethod(): string
{
return $this->method;
}
/**
* @param string $method
*
* @return RequestInterface
*/
public function withMethod(string $method): RequestInterface
{
$request = clone $this;
@ -202,20 +133,11 @@ class Request implements RequestInterface
return $request;
}
/**
* @return UriInterface
*/
public function getUri(): UriInterface
{
return $this->uri;
}
/**
* @param UriInterface $uri
* @param bool $preserveHost
*
* @return RequestInterface
*/
public function withUri(UriInterface $uri, bool $preserveHost = false): RequestInterface
{
$request = clone $this;
@ -228,9 +150,6 @@ class Request implements RequestInterface
return $request;
}
/**
* @return array
*/
public function getFlatHeaders(): array
{
$headerStrings = [];
@ -244,9 +163,6 @@ class Request implements RequestInterface
return $headerStrings;
}
/**
* @return array
*/
public function getData(): array
{
$contentType = $this->getHeaderLine('Content-Type');
@ -263,30 +179,16 @@ class Request implements RequestInterface
return $data;
}
/**
* @param string $key
*
* @return mixed
*/
public function get(string $key): mixed
{
return $this->getData()[$key] ?? null;
}
/**
* @param string $name
* @param string|null $default
*
* @return string|null
*/
public function getQueryParam(string $name, ?string $default = null): ?string
{
return $this->getQueryParams()[$name] ?? $default;
}
/**
* @return array
*/
protected function getQueryParams(): array
{
$queryParams = [];

View file

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Loom\HttpComponent;
use Loom\HttpComponent\Traits\ResolveHeadersTrait;
@ -10,39 +12,24 @@ class Response implements ResponseInterface
{
use ResolveHeadersTrait;
private int $statusCode;
private string $reasonPhrase;
private array $headers;
private StreamInterface $body;
private string $protocolVersion;
public function __construct(
int $statusCode = 200,
string $reasonPhrase = '',
array $headers = [],
StreamInterface $body = null,
string $protocolVersion = '1.1'
private int $statusCode = 200,
private string $reasonPhrase = 'OK',
private array $headers = [],
?StreamInterface $body = null,
private string $protocolVersion = '1.1'
) {
$this->statusCode = $statusCode;
$this->reasonPhrase = $reasonPhrase;
$this->headers = $this->setHeaders($headers);
$this->body = $body ?? new Stream(fopen('php://temp', 'r+'));
$this->protocolVersion = $protocolVersion;
}
/**
* @return string
*/
public function getProtocolVersion(): string
{
return $this->protocolVersion;
}
/**
* @param string $version
*
* @return ResponseInterface
*/
public function withProtocolVersion(string $version): ResponseInterface
{
$response = clone $this;
@ -51,50 +38,26 @@ class Response implements ResponseInterface
return $response;
}
/**
* @return array
*/
public function getHeaders(): array
{
return $this->headers;
}
/**
* @param string $name
*
* @return bool
*/
public function hasHeader(string $name): bool
{
return isset($this->headers[strtolower($name)]);
}
/**
* @param string $name
*
* @return array|string[]
*/
public function getHeader(string $name): array
{
return $this->headers[strtolower($name)] ?? [];
}
/**
* @param string $name
*
* @return string
*/
public function getHeaderLine(string $name): string
{
return implode(', ', $this->getHeader($name));
}
/**
* @param string $name
* @param $value
*
* @return ResponseInterface
*/
public function withHeader(string $name, $value): ResponseInterface
{
$response = clone $this;
@ -104,12 +67,6 @@ class Response implements ResponseInterface
return $response;
}
/**
* @param string $name
* @param $value
*
* @return ResponseInterface
*/
public function withAddedHeader(string $name, $value): ResponseInterface
{
$response = clone $this;
@ -119,11 +76,6 @@ class Response implements ResponseInterface
return $response;
}
/**
* @param string $name
*
* @return ResponseInterface
*/
public function withoutHeader(string $name): ResponseInterface
{
$response = clone $this;
@ -133,19 +85,11 @@ class Response implements ResponseInterface
return $response;
}
/**
* @return StreamInterface
*/
public function getBody(): StreamInterface
{
return $this->body;
}
/**
* @param StreamInterface $body
*
* @return ResponseInterface
*/
public function withBody(StreamInterface $body): ResponseInterface
{
$response = clone $this;
@ -154,20 +98,11 @@ class Response implements ResponseInterface
return $response;
}
/**
* @return int
*/
public function getStatusCode(): int
{
return $this->statusCode;
}
/**
* @param $code
* @param $reasonPhrase
*
* @return ResponseInterface
*/
public function withStatus($code, $reasonPhrase = ''): ResponseInterface
{
$response = clone $this;
@ -177,9 +112,6 @@ class Response implements ResponseInterface
return $response;
}
/**
* @return string
*/
public function getReasonPhrase(): string
{
return $this->reasonPhrase;

View file

@ -14,7 +14,7 @@ class Uri implements UriInterface
private string $fragment;
private string $userInfo;
public function __construct(string $scheme, string $host, string $path, string $query, string|int $port = null)
public function __construct(string $scheme, string $host, string $path, string $query, string|int|null $port = null)
{
$this->scheme = $scheme;
$this->host = $host;

View file

@ -1,114 +0,0 @@
<?php
namespace Loom\HttpComponentTests;
use Loom\HttpComponent\HttpClient;
use Loom\HttpComponent\Request;
use Loom\HttpComponent\Uri;
use Loom\HttpComponentTests\Traits\ProvidesHeaderDataTrait;
use PHPUnit\Framework\TestCase;
class HttpClientTest extends TestCase
{
use ProvidesHeaderDataTrait;
private static mixed $serverProcess;
/**
* @return void
*/
public static function setUpBeforeClass(): void
{
self::$serverProcess = proc_open('php -S localhost:8000', [], $pipes);
}
/**
* @return void
*/
public static function tearDownAfterClass(): void
{
proc_terminate(self::$serverProcess);
proc_close(self::$serverProcess);
}
/**
* @return void
*/
public function testNotFound(): void
{
$uri = new Uri('http', 'localhost', '/', '', 8000);
$request = new Request('GET', $uri, []);
$response = (new HttpClient())->sendRequest($request);
$this->assertEquals(404, $response->getStatusCode());
}
/**
* @param string $method
*
* @dataProvider methodProvider
*
* @return void
*/
public function testItSendsRequest(string $method): void
{
$uri = new Uri('http', 'localhost', '/tests/api.php', '', 8000);
$request = new Request($method, $uri, []);
$response = (new HttpClient())->sendRequest($request);
$this->assertEquals(200, $response->getStatusCode());
}
/**
* @return void
*/
public function testGet(): void
{
$this->assertEquals(200, (new HttpClient())->get(...$this->getDummyRequestData())->getStatusCode());
}
/**
* @return void
*/
public function testPost(): void
{
$this->assertEquals(200, (new HttpClient())->post(...$this->getDummyRequestData())->getStatusCode());
}
/**
* @return void
*/
public function testPut(): void
{
$this->assertEquals(200, (new HttpClient())->put(...$this->getDummyRequestData())->getStatusCode());
}
/**
* @return void
*/
public function testPatch(): void
{
$this->assertEquals(200, (new HttpClient())->patch(...$this->getDummyRequestData())->getStatusCode());
}
/**
* @return void
*/
public function testDelete(): void
{
$this->assertEquals(200, (new HttpClient())->delete(...$this->getDummyRequestData())->getStatusCode());
}
private function getDummyRequestData(): array
{
return [
'http://localhost:8000/tests/api.php',
[
'Content-Type' => 'application/json',
],
''
];
}
}

View file

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace Loom\HttpComponentTests;
use Loom\HttpComponent\Request;
@ -7,6 +9,7 @@ use Loom\HttpComponent\Stream;
use Loom\HttpComponent\StreamBuilder;
use Loom\HttpComponent\Uri;
use Loom\HttpComponentTests\Traits\ProvidesHeaderDataTrait;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\Exception as MockObjectException;
use PHPUnit\Framework\TestCase;
@ -15,8 +18,6 @@ class RequestTest extends TestCase
use ProvidesHeaderDataTrait;
/**
* @return void
*
* @throws MockObjectException
*/
public function testGetHeaders(): void
@ -27,8 +28,6 @@ class RequestTest extends TestCase
}
/**
* @return void
*
* @throws MockObjectException
*/
public function testMultipleHeaders(): void
@ -41,8 +40,6 @@ class RequestTest extends TestCase
}
/**
* @return void
*
* @throws MockObjectException
*/
public function testWithHeader(): void
@ -55,8 +52,6 @@ class RequestTest extends TestCase
}
/**
* @return void
*
* @throws MockObjectException
*/
public function testWithAddedHeader(): void
@ -69,14 +64,9 @@ class RequestTest extends TestCase
}
/**
* @param string $key
*
* @dataProvider headerKeyProvider
*
* @return void
*
* @throws MockObjectException
*/
#[DataProvider('headerKeyProvider')]
public function testHasHeader(string $key): void
{
$request = $this->simpleGetRequest();
@ -85,8 +75,6 @@ class RequestTest extends TestCase
}
/**
* @return void
*
* @throws MockObjectException
*/
public function testWithoutHeader(): void
@ -99,8 +87,6 @@ class RequestTest extends TestCase
}
/**
* @return void
*
* @throws MockObjectException
*/
public function testGetHeaderLine(): void
@ -111,14 +97,9 @@ class RequestTest extends TestCase
}
/**
* @param string $method
*
* @dataProvider methodProvider
*
* @return void
*
* @throws MockObjectException
*/
#[DataProvider('methodProvider')]
public function testWithMethod(string $method): void
{
$request = $this->simpleGetRequest();
@ -128,9 +109,6 @@ class RequestTest extends TestCase
$this->assertEquals($method, $request->getMethod());
}
/**
* @return void
*/
public function testGetRequestTarget(): void
{
$uri = new Uri('https', 'localhost', '/test', 'hello=world');
@ -140,9 +118,6 @@ class RequestTest extends TestCase
$this->assertEquals('/test?hello=world', $request->getRequestTarget());
}
/**
* @return void
*/
public function testWithRequestTarget(): void
{
$uri = new Uri('https', 'localhost', '/test', 'hello=world');
@ -155,8 +130,6 @@ class RequestTest extends TestCase
}
/**
* @return void
*
* @throws MockObjectException
*/
public function testWithUri(): void
@ -170,8 +143,6 @@ class RequestTest extends TestCase
}
/**
* @return void
*
* @throws MockObjectException
*/
public function testGetData(): void
@ -193,9 +164,16 @@ class RequestTest extends TestCase
$this->assertEquals([], $request->getData());
}
public function testWithProtocolVersion(): void
{
$request = new Request('GET', $this->createMock(Uri::class));
$request = $request->withProtocolVersion('2.0');
$this->assertEquals('2.0', $request->getProtocolVersion());
}
/**
* @return array
*
* @throws MockObjectException
*/
private function getMockObjects(): array
@ -207,8 +185,6 @@ class RequestTest extends TestCase
}
/**
* @return Request
*
* @throws MockObjectException
*/
private function simpleGetRequest(): Request

View file

@ -1,9 +1,12 @@
<?php
declare(strict_types=1);
namespace Loom\HttpComponentTests;
use Loom\HttpComponent\Response;
use Loom\HttpComponentTests\Traits\ProvidesHeaderDataTrait;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class ResponseTest extends TestCase
@ -15,9 +18,6 @@ class ResponseTest extends TestCase
$this->assertEquals('1.1', (new Response())->getProtocolVersion());
}
/**
* @return void
*/
public function testWithProtocolVersion(): void
{
$response = new Response();
@ -26,37 +26,22 @@ class ResponseTest extends TestCase
$this->assertEquals('2.0', $response->getProtocolVersion());
}
/**
* @return void
*/
public function testGetHeaders(): void
{
$this->assertEquals(['content-type' => ['application/json']], ($this->getSimpleResponse())->getHeaders());
}
/**
* @param string $key
*
* @dataProvider headerKeyProvider
*
* @return void
*/
#[DataProvider('headerKeyProvider')]
public function testHasHeader(string $key): void
{
$this->assertTrue(($this->getSimpleResponse())->hasHeader($key));
}
/**
* @return void
*/
public function testGetHeader(): void
{
$this->assertEquals(['application/json'], ($this->getSimpleResponse())->getHeader('CONTENT-TYPE'));
}
/**
* @return void
*/
public function testWithHeader(): void
{
$response = $this->getSimpleResponse();
@ -65,9 +50,6 @@ class ResponseTest extends TestCase
$this->assertEquals(['text/html'], $response->getHeader('content-type'));
}
/**
* @return void
*/
public function testWithAddedHeader(): void
{
$response = $this->getSimpleResponse();
@ -76,9 +58,6 @@ class ResponseTest extends TestCase
$this->assertEquals(['application/json', 'text/html'], $response->getHeader('content-type'));
}
/**
* @return void
*/
public function testGetHeaderLine(): void
{
$response = $this->getSimpleResponse();
@ -87,9 +66,6 @@ class ResponseTest extends TestCase
$this->assertEquals('application/json, text/html', $response->getHeaderLine('content-type'));
}
/**
* @return void
*/
public function testWithoutHeader(): void
{
$response = $this->getSimpleResponse();
@ -98,9 +74,6 @@ class ResponseTest extends TestCase
$this->assertEquals([], $response->getHeaders());
}
/**
* @return void
*/
public function testWithStatus(): void
{
$response = $this->getSimpleResponse();
@ -109,9 +82,13 @@ class ResponseTest extends TestCase
$this->assertEquals(404, $response->getStatusCode());
}
/**
* @return Response
*/
public function testGetReasonPhrase(): void
{
$response = $this->getSimpleResponse();
$this->assertEquals('OK', $response->getReasonPhrase());
}
private function getSimpleResponse(): Response
{
return new Response(200, 'OK', ['Content-Type' => 'application/json']);

View file

@ -1,29 +1,28 @@
<?php
declare(strict_types=1);
namespace Loom\HttpComponentTests\Traits;
trait ProvidesHeaderDataTrait
{
/**
* @return array
*/
public static function methodProvider(): array
{
return [
'POST' => [
'POST',
'method' => 'POST',
],
'PUT' => [
'PUT',
'method' => 'PUT',
],
'DELETE' => [
'DELETE',
'method' => 'DELETE',
],
'GET' => [
'GET',
'method' => 'GET',
],
'PATCH' => [
'PATCH',
'method' => 'PATCH',
]
];
}

View file

@ -1,3 +0,0 @@
<?php
echo 'Test API endpoint';