From f53e87a9589995e159a605b483f04da4fbe32e1f Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Tue, 7 Mar 2023 15:40:02 +0100 Subject: [PATCH 1/8] Install and init Psalm --- composer.json | 3 ++- psalm.xml | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 psalm.xml diff --git a/composer.json b/composer.json index 468f8bd..cb3817e 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "require-dev": { "guzzlehttp/psr7": "^2.4", "mockery/mockery": "^1.4.1", - "phpunit/phpunit": "^8.0 || ^9.0 || ^10.0" + "phpunit/phpunit": "^8.0 || ^9.0 || ^10.0", + "vimeo/psalm": "^5.7.7" }, "conflict": { "phpunit/phpunit": "<8.0 || >= 11.0" diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..483973b --- /dev/null +++ b/psalm.xml @@ -0,0 +1,16 @@ + + + + + + + + + From 064e7c68ec13ce5c3ad80d61e8ca7cb1690c6083 Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Tue, 7 Mar 2023 15:40:04 +0100 Subject: [PATCH 2/8] Fix warning --- src/Constraint/UrlEncodedMatchesMany.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Constraint/UrlEncodedMatchesMany.php b/src/Constraint/UrlEncodedMatchesMany.php index 9fef96c..8bd8ef1 100644 --- a/src/Constraint/UrlEncodedMatchesMany.php +++ b/src/Constraint/UrlEncodedMatchesMany.php @@ -29,7 +29,7 @@ protected function matches($other): bool public function toString(): string { - return join(" and ", array_map(function(HasQueryParameterConstraint $c) { + return join(" and ", array_map(function(UrlEncodedMatches $c) { return $c->toString(); }, $this->constraints)); } From c6f120b0e4f51ebbe4d104ce09a9cad9f855e3ee Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Tue, 7 Mar 2023 15:46:13 +0100 Subject: [PATCH 3/8] Use property type hints where possible --- src/Constraint/BodyMatchesConstraint.php | 2 +- src/Constraint/HasHeaderConstraint.php | 9 +++---- src/Constraint/HasMethodConstraint.php | 3 +-- .../HasQueryParameterConstraint.php | 5 ++-- .../HasQueryParametersConstraint.php | 2 +- src/Constraint/HasStatusConstraint.php | 5 ++-- src/Constraint/HasUriConstraint.php | 3 +-- src/Constraint/UrlEncodedMatches.php | 6 ++--- src/Constraint/UrlEncodedMatchesMany.php | 2 +- src/Psr7Assertions.php | 26 ++++--------------- 10 files changed, 20 insertions(+), 43 deletions(-) diff --git a/src/Constraint/BodyMatchesConstraint.php b/src/Constraint/BodyMatchesConstraint.php index 9a724fe..45193aa 100644 --- a/src/Constraint/BodyMatchesConstraint.php +++ b/src/Constraint/BodyMatchesConstraint.php @@ -9,7 +9,7 @@ class BodyMatchesConstraint extends Constraint { /** @var Constraint */ - private $constraint; + private Constraint $constraint; public function __construct(Constraint $constraint) { diff --git a/src/Constraint/HasHeaderConstraint.php b/src/Constraint/HasHeaderConstraint.php index 0205388..d0084a5 100644 --- a/src/Constraint/HasHeaderConstraint.php +++ b/src/Constraint/HasHeaderConstraint.php @@ -9,13 +9,10 @@ class HasHeaderConstraint extends Constraint { - /** @var string */ - private $name; + private string $name; + private Constraint $constraint; - /** @var Constraint */ - private $constraint; - - public function __construct(string $name, $constraint = null) + public function __construct(string $name, mixed $constraint = null) { if ($constraint === null) { $constraint = Assert::logicalNot(Assert::isEmpty()); diff --git a/src/Constraint/HasMethodConstraint.php b/src/Constraint/HasMethodConstraint.php index 77c736c..2dd094d 100644 --- a/src/Constraint/HasMethodConstraint.php +++ b/src/Constraint/HasMethodConstraint.php @@ -8,8 +8,7 @@ class HasMethodConstraint extends Constraint { - /** @var string */ - private $method; + private string $method; public function __construct(string $method) { diff --git a/src/Constraint/HasQueryParameterConstraint.php b/src/Constraint/HasQueryParameterConstraint.php index f4485a7..17b402c 100644 --- a/src/Constraint/HasQueryParameterConstraint.php +++ b/src/Constraint/HasQueryParameterConstraint.php @@ -8,10 +8,9 @@ class HasQueryParameterConstraint extends Constraint { - /** @var UrlEncodedMatches */ - private $inner; + private UrlEncodedMatches $inner; - public function __construct($nameMatcher, $valueMatcher = null) + public function __construct(mixed $nameMatcher, mixed $valueMatcher = null) { $this->inner = new UrlEncodedMatches($nameMatcher, $valueMatcher); } diff --git a/src/Constraint/HasQueryParametersConstraint.php b/src/Constraint/HasQueryParametersConstraint.php index b177fad..6a2617d 100644 --- a/src/Constraint/HasQueryParametersConstraint.php +++ b/src/Constraint/HasQueryParametersConstraint.php @@ -6,7 +6,7 @@ class HasQueryParametersConstraint extends Constraint { /** @var HasQueryParameterConstraint[] */ - private $constraints = []; + private array $constraints = []; public function __construct(array $constraints) { diff --git a/src/Constraint/HasStatusConstraint.php b/src/Constraint/HasStatusConstraint.php index 7848173..8743889 100644 --- a/src/Constraint/HasStatusConstraint.php +++ b/src/Constraint/HasStatusConstraint.php @@ -9,10 +9,9 @@ class HasStatusConstraint extends Constraint { - /** @var Constraint */ - private $status; + private Constraint $status; - public function __construct($status) + public function __construct(mixed $status) { if (!$status instanceof Constraint) { $status = Assert::equalTo($status); diff --git a/src/Constraint/HasUriConstraint.php b/src/Constraint/HasUriConstraint.php index 28d09ea..80fa131 100644 --- a/src/Constraint/HasUriConstraint.php +++ b/src/Constraint/HasUriConstraint.php @@ -8,8 +8,7 @@ class HasUriConstraint extends Constraint { - /** @var string */ - private $uri; + private string $uri; public function __construct(string $uri) { diff --git a/src/Constraint/UrlEncodedMatches.php b/src/Constraint/UrlEncodedMatches.php index 4cf1403..7ab336a 100644 --- a/src/Constraint/UrlEncodedMatches.php +++ b/src/Constraint/UrlEncodedMatches.php @@ -7,10 +7,10 @@ class UrlEncodedMatches extends Constraint { - private $nameMatcher; - private $valueMatcher; + private mixed $nameMatcher; + private mixed $valueMatcher; - public function __construct($nameMatcher, $valueMatcher = null) + public function __construct(mixed $nameMatcher, mixed $valueMatcher = null) { if (!($nameMatcher instanceof Constraint)) { $nameMatcher = new IsEqual($nameMatcher); diff --git a/src/Constraint/UrlEncodedMatchesMany.php b/src/Constraint/UrlEncodedMatchesMany.php index 8bd8ef1..503fba3 100644 --- a/src/Constraint/UrlEncodedMatchesMany.php +++ b/src/Constraint/UrlEncodedMatchesMany.php @@ -6,7 +6,7 @@ class UrlEncodedMatchesMany extends Constraint { /** @var UrlEncodedMatches[] */ - private $constraints = []; + private array $constraints = []; public function __construct(array $constraints) { diff --git a/src/Psr7Assertions.php b/src/Psr7Assertions.php index 43349cb..048e5d6 100644 --- a/src/Psr7Assertions.php +++ b/src/Psr7Assertions.php @@ -38,7 +38,7 @@ public static function assertMessageHasHeaders(MessageInterface $message, array Assert::assertThat($message, static::hasHeaders($constraints)); } - public static function assertMessageBodyMatches(MessageInterface $message, $constraint): void + public static function assertMessageBodyMatches(MessageInterface $message, mixed $constraint): void { Assert::assertThat($message, static::bodyMatches($constraint)); } @@ -103,25 +103,17 @@ public static function assertRequestIsDelete(RequestInterface $request): void Assert::assertThat($request, static::isDelete()); } - /** - * @param string $uri - */ public static function assertStringIsAbsoluteUri(string $uri): void { Assert::assertThat($uri, static::isAbsoluteUri()); } - /** - * @param string|UriInterface|RequestInterface $uriOrRequest - * @param string|Constraint $name - * @param string|Constraint|null $value - */ - public static function assertHasQueryParameter($uriOrRequest, $name, $value = null): void + public static function assertHasQueryParameter(string|UriInterface|RequestInterface $uriOrRequest, string|Constraint $name, string|Constraint|null $value = null): void { Assert::assertThat($uriOrRequest, static::hasQueryParameter($name, $value)); } - public static function assertHasQueryParameters($uriOrRequest, array $parameters): void + public static function assertHasQueryParameters(string|UriInterface|RequestInterface $uriOrRequest, array $parameters): void { Assert::assertThat($uriOrRequest, static::hasQueryParameters($parameters)); } @@ -181,7 +173,7 @@ public static function isDelete(): Constraint return static::hasMethod('DELETE'); } - public static function hasHeader(string $name, $constraint = null): Constraint + public static function hasHeader(string $name, mixed $constraint = null): Constraint { return new HasHeaderConstraint($name, $constraint); } @@ -206,12 +198,7 @@ public static function bodyMatches(Constraint $constraint): Constraint return new BodyMatchesConstraint($constraint); } - /** - * @param string|Constraint $name - * @param string|Constraint|null $value - * @return Constraint - */ - public static function hasQueryParameter($name, $value = null): Constraint + public static function hasQueryParameter(string|Constraint $name, string|Constraint|null $value = null): Constraint { return new HasQueryParameterConstraint($name, $value); } @@ -242,9 +229,6 @@ public static function bodyMatchesForm(array $constraints): Constraint ); } - /** - * @return Constraint - */ public static function isAbsoluteUri(): Constraint { return new IsAbsoluteUriConstraint(); From 637f7f560ffa665450c91e4661a371467cd93b3d Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Tue, 7 Mar 2023 15:55:25 +0100 Subject: [PATCH 4/8] Fix Psalm lvl. 5 warnings --- psalm.xml | 2 +- src/Constraint/BodyMatchesConstraint.php | 2 +- src/Constraint/HasQueryParameterConstraint.php | 2 +- src/Constraint/HasStatusConstraint.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/psalm.xml b/psalm.xml index 483973b..6c3444c 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,6 +1,6 @@ getBody()->rewind(); $body = $other->getBody()->getContents(); - return $this->constraint->evaluate($body, '', true); + return (bool)$this->constraint->evaluate($body, '', true); } } diff --git a/src/Constraint/HasQueryParameterConstraint.php b/src/Constraint/HasQueryParameterConstraint.php index 17b402c..a11e402 100644 --- a/src/Constraint/HasQueryParameterConstraint.php +++ b/src/Constraint/HasQueryParameterConstraint.php @@ -50,7 +50,7 @@ private function matchesString(string $other): bool private function matchesQueryString(string $query): bool { - return $this->inner->evaluate($query, "", true); + return (bool)$this->inner->evaluate($query, "", true); } diff --git a/src/Constraint/HasStatusConstraint.php b/src/Constraint/HasStatusConstraint.php index 8743889..1957e93 100644 --- a/src/Constraint/HasStatusConstraint.php +++ b/src/Constraint/HasStatusConstraint.php @@ -36,7 +36,7 @@ protected function matches($other): bool return false; } - return $this->status->evaluate($other->getStatusCode(), '', true); + return (bool)$this->status->evaluate($other->getStatusCode(), '', true); } protected function additionalFailureDescription($other): string From bf81a38eaea71d3878093747bf539d9fe5a34514 Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Tue, 7 Mar 2023 16:02:58 +0100 Subject: [PATCH 5/8] Fix psalm error level 4 --- psalm.xml | 2 +- src/Constraint/BodyMatchesConstraint.php | 1 + src/Constraint/HasHeaderConstraint.php | 1 + src/Constraint/HasStatusConstraint.php | 1 + src/Constraint/IsAbsoluteUriConstraint.php | 2 +- 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/psalm.xml b/psalm.xml index 6c3444c..6a2b6bb 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,6 +1,6 @@ constraint->toString(); } diff --git a/src/Constraint/HasHeaderConstraint.php b/src/Constraint/HasHeaderConstraint.php index d0084a5..7b3c58b 100644 --- a/src/Constraint/HasHeaderConstraint.php +++ b/src/Constraint/HasHeaderConstraint.php @@ -31,6 +31,7 @@ public function __construct(string $name, mixed $constraint = null) */ public function toString(): string { + /** @psalm-suppress InternalMethod */ return "has header '{$this->name}' that {$this->constraint->toString()}"; } diff --git a/src/Constraint/HasStatusConstraint.php b/src/Constraint/HasStatusConstraint.php index 1957e93..de75db6 100644 --- a/src/Constraint/HasStatusConstraint.php +++ b/src/Constraint/HasStatusConstraint.php @@ -27,6 +27,7 @@ public function __construct(mixed $status) */ public function toString(): string { + /** @psalm-suppress InternalMethod */ return "response status {$this->status->toString()}"; } diff --git a/src/Constraint/IsAbsoluteUriConstraint.php b/src/Constraint/IsAbsoluteUriConstraint.php index f095a0b..3eb116f 100644 --- a/src/Constraint/IsAbsoluteUriConstraint.php +++ b/src/Constraint/IsAbsoluteUriConstraint.php @@ -26,6 +26,6 @@ protected function matches($other): bool return false; } - return $parts !== false; + return true; } } \ No newline at end of file From a37e015f17b44682324e4e188d925d448c6773e8 Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Tue, 7 Mar 2023 16:39:56 +0100 Subject: [PATCH 6/8] Fix psalm levels 2+3 --- psalm.xml | 2 +- src/Constraint/BodyMatchesConstraint.php | 2 +- src/Constraint/HasHeaderConstraint.php | 4 ++-- src/Constraint/HasMethodConstraint.php | 2 +- src/Constraint/HasQueryParameterConstraint.php | 2 +- src/Constraint/HasQueryParametersConstraint.php | 2 +- src/Constraint/HasStatusConstraint.php | 4 ++-- src/Constraint/HasUriConstraint.php | 2 +- src/Constraint/IsAbsoluteUriConstraint.php | 2 +- src/Constraint/UrlEncodedMatches.php | 2 +- src/Constraint/UrlEncodedMatchesMany.php | 2 +- src/Functions.php | 10 +++++----- src/Psr7Assertions.php | 4 ++-- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/psalm.xml b/psalm.xml index 6a2b6bb..6a7331d 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,6 +1,6 @@ constraint->toString(); } - protected function matches($other): bool + protected function matches(mixed $other): bool { if (!$other instanceof MessageInterface) { return false; diff --git a/src/Constraint/HasHeaderConstraint.php b/src/Constraint/HasHeaderConstraint.php index 7b3c58b..64dfc20 100644 --- a/src/Constraint/HasHeaderConstraint.php +++ b/src/Constraint/HasHeaderConstraint.php @@ -12,7 +12,7 @@ class HasHeaderConstraint extends Constraint private string $name; private Constraint $constraint; - public function __construct(string $name, mixed $constraint = null) + public function __construct(string $name, Constraint|string $constraint = null) { if ($constraint === null) { $constraint = Assert::logicalNot(Assert::isEmpty()); @@ -35,7 +35,7 @@ public function toString(): string return "has header '{$this->name}' that {$this->constraint->toString()}"; } - protected function matches($other): bool + protected function matches(mixed $other): bool { if (!$other instanceof MessageInterface) { return false; diff --git a/src/Constraint/HasMethodConstraint.php b/src/Constraint/HasMethodConstraint.php index 2dd094d..00a1653 100644 --- a/src/Constraint/HasMethodConstraint.php +++ b/src/Constraint/HasMethodConstraint.php @@ -25,7 +25,7 @@ public function toString(): string return "has request method {$this->method}"; } - protected function matches($other): bool + protected function matches(mixed $other): bool { if (!$other instanceof RequestInterface) { return false; diff --git a/src/Constraint/HasQueryParameterConstraint.php b/src/Constraint/HasQueryParameterConstraint.php index a11e402..0e9c02e 100644 --- a/src/Constraint/HasQueryParameterConstraint.php +++ b/src/Constraint/HasQueryParameterConstraint.php @@ -15,7 +15,7 @@ public function __construct(mixed $nameMatcher, mixed $valueMatcher = null) $this->inner = new UrlEncodedMatches($nameMatcher, $valueMatcher); } - protected function matches($other): bool + protected function matches(mixed $other): bool { if (is_string($other)) { return $this->matchesString($other); diff --git a/src/Constraint/HasQueryParametersConstraint.php b/src/Constraint/HasQueryParametersConstraint.php index 6a2617d..cacc866 100644 --- a/src/Constraint/HasQueryParametersConstraint.php +++ b/src/Constraint/HasQueryParametersConstraint.php @@ -15,7 +15,7 @@ public function __construct(array $constraints) } } - public function matches($other): bool + public function matches(mixed $other): bool { foreach ($this->constraints as $constraint) { if (!$constraint->evaluate($other, "", true)) { diff --git a/src/Constraint/HasStatusConstraint.php b/src/Constraint/HasStatusConstraint.php index de75db6..f1da7b9 100644 --- a/src/Constraint/HasStatusConstraint.php +++ b/src/Constraint/HasStatusConstraint.php @@ -31,7 +31,7 @@ public function toString(): string return "response status {$this->status->toString()}"; } - protected function matches($other): bool + protected function matches(mixed $other): bool { if (!$other instanceof ResponseInterface) { return false; @@ -40,7 +40,7 @@ protected function matches($other): bool return (bool)$this->status->evaluate($other->getStatusCode(), '', true); } - protected function additionalFailureDescription($other): string + protected function additionalFailureDescription(mixed $other): string { if ($other instanceof ResponseInterface) { return 'Actual status is ' . $other->getStatusCode() . ' and the body contains: ' . $other->getBody(); diff --git a/src/Constraint/HasUriConstraint.php b/src/Constraint/HasUriConstraint.php index 80fa131..7c3e14f 100644 --- a/src/Constraint/HasUriConstraint.php +++ b/src/Constraint/HasUriConstraint.php @@ -25,7 +25,7 @@ public function toString(): string return "has request URI '{$this->uri}'"; } - protected function matches($other): bool + protected function matches(mixed $other): bool { if (!$other instanceof RequestInterface) { return false; diff --git a/src/Constraint/IsAbsoluteUriConstraint.php b/src/Constraint/IsAbsoluteUriConstraint.php index 3eb116f..a1a2707 100644 --- a/src/Constraint/IsAbsoluteUriConstraint.php +++ b/src/Constraint/IsAbsoluteUriConstraint.php @@ -11,7 +11,7 @@ public function toString(): string return "is valid URI"; } - protected function matches($other): bool + protected function matches(mixed $other): bool { $parts = parse_url($other); if ($parts === false) { diff --git a/src/Constraint/UrlEncodedMatches.php b/src/Constraint/UrlEncodedMatches.php index 7ab336a..4b9ea0b 100644 --- a/src/Constraint/UrlEncodedMatches.php +++ b/src/Constraint/UrlEncodedMatches.php @@ -26,7 +26,7 @@ public function __construct(mixed $nameMatcher, mixed $valueMatcher = null) $this->valueMatcher = $valueMatcher; } - protected function matches($other): bool + protected function matches(mixed $other): bool { parse_str($other, $parsedQuery); diff --git a/src/Constraint/UrlEncodedMatchesMany.php b/src/Constraint/UrlEncodedMatchesMany.php index 503fba3..eb8207e 100644 --- a/src/Constraint/UrlEncodedMatchesMany.php +++ b/src/Constraint/UrlEncodedMatchesMany.php @@ -15,7 +15,7 @@ public function __construct(array $constraints) } } - protected function matches($other): bool + protected function matches(mixed $other): bool { foreach ($this->constraints as $constraint) { if (!$constraint->evaluate($other, "", true)) { diff --git a/src/Functions.php b/src/Functions.php index c033b59..b813260 100644 --- a/src/Functions.php +++ b/src/Functions.php @@ -15,7 +15,7 @@ function hasUri(string $uri): HasUriConstraint return new HasUriConstraint($uri); } -function hasHeader(string $name, $constraint = null): HasHeaderConstraint +function hasHeader(string $name, Constraint|string $constraint = null): HasHeaderConstraint { return new HasHeaderConstraint($name, $constraint); } @@ -25,12 +25,12 @@ function hasHeaders(array $constraints): Constraint return Psr7AssertionsClass::hasHeaders($constraints); } -function hasStatus($status): Constraint +function hasStatus(Constraint|int $status): Constraint { return Psr7AssertionsClass::hasStatus($status); } -function hasQueryParameter($name, $value = null): Constraint +function hasQueryParameter(Constraint|string $name, Constraint|string $value = null): Constraint { return Psr7AssertionsClass::hasQueryParameter($name, $value); } @@ -93,12 +93,12 @@ function isDelete(): Constraint return Psr7AssertionsClass::isDelete(); } -function bodyMatches($constraint): Constraint +function bodyMatches(Constraint $constraint): Constraint { return new BodyMatchesConstraint($constraint); } -function bodyMatchesJson($constraints): Constraint +function bodyMatchesJson(array $constraints): Constraint { return Assert::logicalAnd( hasContentType('application/json'), diff --git a/src/Psr7Assertions.php b/src/Psr7Assertions.php index 048e5d6..d95720b 100644 --- a/src/Psr7Assertions.php +++ b/src/Psr7Assertions.php @@ -28,7 +28,7 @@ public static function assertRequestHasUri(RequestInterface $request, string $ur Assert::assertThat($request, static::hasUri($uri)); } - public static function assertMessageHasHeader(MessageInterface $message, string $headerName, $headerValue = null): void + public static function assertMessageHasHeader(MessageInterface $message, string $headerName, mixed $headerValue = null): void { Assert::assertThat($message, static::hasHeader($headerName, $headerValue)); } @@ -128,7 +128,7 @@ public static function hasMethod(string $method): Constraint return new HasMethodConstraint($method); } - public static function hasStatus($status): Constraint + public static function hasStatus(Constraint|int $status): Constraint { return new HasStatusConstraint($status); } From d5e525b094fc782521a93e7e5cc4a8674ea115ee Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Tue, 7 Mar 2023 16:57:26 +0100 Subject: [PATCH 7/8] Fix psalm errors level 1 --- psalm.xml | 2 +- src/Constraint/HasHeaderConstraint.php | 2 +- .../HasQueryParameterConstraint.php | 2 +- .../HasQueryParametersConstraint.php | 3 ++ src/Constraint/IsAbsoluteUriConstraint.php | 4 +++ src/Constraint/UrlEncodedMatches.php | 12 +++++-- src/Constraint/UrlEncodedMatchesMany.php | 3 ++ src/Functions.php | 15 ++++++++- src/Psr7Assertions.php | 33 +++++++++++++++++-- 9 files changed, 66 insertions(+), 10 deletions(-) diff --git a/psalm.xml b/psalm.xml index 6a7331d..bb222f1 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,6 +1,6 @@ inner = new UrlEncodedMatches($nameMatcher, $valueMatcher); } diff --git a/src/Constraint/HasQueryParametersConstraint.php b/src/Constraint/HasQueryParametersConstraint.php index cacc866..32c1a19 100644 --- a/src/Constraint/HasQueryParametersConstraint.php +++ b/src/Constraint/HasQueryParametersConstraint.php @@ -8,6 +8,9 @@ class HasQueryParametersConstraint extends Constraint /** @var HasQueryParameterConstraint[] */ private array $constraints = []; + /** + * @param array $constraints + */ public function __construct(array $constraints) { foreach ($constraints as $key => $value) { diff --git a/src/Constraint/IsAbsoluteUriConstraint.php b/src/Constraint/IsAbsoluteUriConstraint.php index a1a2707..9407012 100644 --- a/src/Constraint/IsAbsoluteUriConstraint.php +++ b/src/Constraint/IsAbsoluteUriConstraint.php @@ -13,6 +13,10 @@ public function toString(): string protected function matches(mixed $other): bool { + if (!is_string($other)) { + return false; + } + $parts = parse_url($other); if ($parts === false) { return false; diff --git a/src/Constraint/UrlEncodedMatches.php b/src/Constraint/UrlEncodedMatches.php index 4b9ea0b..0ce4eb6 100644 --- a/src/Constraint/UrlEncodedMatches.php +++ b/src/Constraint/UrlEncodedMatches.php @@ -7,10 +7,10 @@ class UrlEncodedMatches extends Constraint { - private mixed $nameMatcher; - private mixed $valueMatcher; + private Constraint $nameMatcher; + private Constraint $valueMatcher; - public function __construct(mixed $nameMatcher, mixed $valueMatcher = null) + public function __construct(Constraint|string $nameMatcher, Constraint|string|null $valueMatcher = null) { if (!($nameMatcher instanceof Constraint)) { $nameMatcher = new IsEqual($nameMatcher); @@ -28,8 +28,13 @@ public function __construct(mixed $nameMatcher, mixed $valueMatcher = null) protected function matches(mixed $other): bool { + if (!is_string($other)) { + return false; + } + parse_str($other, $parsedQuery); + /** @var array $parsedQuery */ foreach ($parsedQuery as $key => $value) { $nameMatches = $this->nameMatcher->evaluate($key, "", true); $valueMatches = $this->valueMatcher->evaluate($value, "", true); @@ -44,6 +49,7 @@ protected function matches(mixed $other): bool public function toString(): string { + /** @psalm-suppress InternalMethod */ return 'contains a name matching ' . $this->nameMatcher->toString() . ' and value matching ' . $this->valueMatcher->toString(); } diff --git a/src/Constraint/UrlEncodedMatchesMany.php b/src/Constraint/UrlEncodedMatchesMany.php index eb8207e..54b0c60 100644 --- a/src/Constraint/UrlEncodedMatchesMany.php +++ b/src/Constraint/UrlEncodedMatchesMany.php @@ -8,6 +8,9 @@ class UrlEncodedMatchesMany extends Constraint /** @var UrlEncodedMatches[] */ private array $constraints = []; + /** + * @param array $constraints + */ public function __construct(array $constraints) { foreach ($constraints as $key => $value) { diff --git a/src/Functions.php b/src/Functions.php index b813260..d2e8cbd 100644 --- a/src/Functions.php +++ b/src/Functions.php @@ -4,6 +4,7 @@ use Helmich\JsonAssert\Constraint\JsonValueMatchesMany; use Helmich\Psr7Assert\Constraint\BodyMatchesConstraint; use Helmich\Psr7Assert\Constraint\HasHeaderConstraint; +use Helmich\Psr7Assert\Constraint\HasQueryParameterConstraint; use Helmich\Psr7Assert\Constraint\HasUriConstraint; use Helmich\Psr7Assert\Constraint\IsAbsoluteUriConstraint; use Helmich\Psr7Assert\Psr7AssertionsClass; @@ -15,11 +16,15 @@ function hasUri(string $uri): HasUriConstraint return new HasUriConstraint($uri); } -function hasHeader(string $name, Constraint|string $constraint = null): HasHeaderConstraint +function hasHeader(string $name, Constraint|string|int $constraint = null): HasHeaderConstraint { return new HasHeaderConstraint($name, $constraint); } +/** + * @param array $constraints + * @return Constraint + */ function hasHeaders(array $constraints): Constraint { return Psr7AssertionsClass::hasHeaders($constraints); @@ -35,6 +40,10 @@ function hasQueryParameter(Constraint|string $name, Constraint|string $value = n return Psr7AssertionsClass::hasQueryParameter($name, $value); } +/** + * @param array $constraints + * @return Constraint + */ function hasQueryParameters(array $constraints): Constraint { return Psr7AssertionsClass::hasQueryParameters($constraints); @@ -111,6 +120,10 @@ function bodyMatchesJson(array $constraints): Constraint ); } +/** + * @param array $constraints + * @return Constraint + */ function bodyMatchesForm(array $constraints): Constraint { return Psr7AssertionsClass::bodyMatchesForm($constraints); diff --git a/src/Psr7Assertions.php b/src/Psr7Assertions.php index d95720b..ba2f267 100644 --- a/src/Psr7Assertions.php +++ b/src/Psr7Assertions.php @@ -28,17 +28,22 @@ public static function assertRequestHasUri(RequestInterface $request, string $ur Assert::assertThat($request, static::hasUri($uri)); } - public static function assertMessageHasHeader(MessageInterface $message, string $headerName, mixed $headerValue = null): void + public static function assertMessageHasHeader(MessageInterface $message, string $headerName, Constraint|string $headerValue = null): void { Assert::assertThat($message, static::hasHeader($headerName, $headerValue)); } + /** + * @param MessageInterface $message + * @param array $constraints + * @return void + */ public static function assertMessageHasHeaders(MessageInterface $message, array $constraints): void { Assert::assertThat($message, static::hasHeaders($constraints)); } - public static function assertMessageBodyMatches(MessageInterface $message, mixed $constraint): void + public static function assertMessageBodyMatches(MessageInterface $message, Constraint $constraint): void { Assert::assertThat($message, static::bodyMatches($constraint)); } @@ -48,6 +53,11 @@ public static function assertMessageBodyMatchesJson(MessageInterface $message, a Assert::assertThat($message, static::bodyMatchesJson($jsonConstraints)); } + /** + * @param MessageInterface $message + * @param array $formConstraints + * @return void + */ public static function assertMessageBodyMatchesForm(MessageInterface $message, array $formConstraints): void { Assert::assertThat($message, static::bodyMatchesForm($formConstraints)); @@ -113,6 +123,11 @@ public static function assertHasQueryParameter(string|UriInterface|RequestInterf Assert::assertThat($uriOrRequest, static::hasQueryParameter($name, $value)); } + /** + * @param string|UriInterface|RequestInterface $uriOrRequest + * @param array $parameters + * @return void + */ public static function assertHasQueryParameters(string|UriInterface|RequestInterface $uriOrRequest, array $parameters): void { Assert::assertThat($uriOrRequest, static::hasQueryParameters($parameters)); @@ -173,11 +188,15 @@ public static function isDelete(): Constraint return static::hasMethod('DELETE'); } - public static function hasHeader(string $name, mixed $constraint = null): Constraint + public static function hasHeader(string $name, Constraint|string|int $constraint = null): Constraint { return new HasHeaderConstraint($name, $constraint); } + /** + * @param array $constraints + * @return Constraint + */ public static function hasHeaders(array $constraints): Constraint { $headerConstraints = []; @@ -203,6 +222,10 @@ public static function hasQueryParameter(string|Constraint $name, string|Constra return new HasQueryParameterConstraint($name, $value); } + /** + * @param array $parameters + * @return Constraint + */ public static function hasQueryParameters(array $parameters): Constraint { return new HasQueryParametersConstraint($parameters); @@ -221,6 +244,10 @@ public static function bodyMatchesJson(array $constraints): Constraint ); } + /** + * @param array $constraints + * @return Constraint + */ public static function bodyMatchesForm(array $constraints): Constraint { return Assert::logicalAnd( From 2645a7338fb5a2e6eddf5802853731874c374197 Mon Sep 17 00:00:00 2001 From: Martin Helmich Date: Tue, 7 Mar 2023 16:58:03 +0100 Subject: [PATCH 8/8] Enable type checker in workflow --- .github/workflows/php.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index fbe0112..780da6b 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -42,8 +42,8 @@ jobs: - name: Install dependencies run: composer install --prefer-dist --no-progress --no-suggest - #- name: Run type checker - # run: ./vendor/bin/psalm + - name: Run type checker + run: ./vendor/bin/psalm - name: Run unit tests run: ./vendor/bin/phpunit --testdox --no-coverage