diff --git a/phpstan.neon b/phpstan.neon index d5dc4ef6..0a1cba5c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,7 +9,6 @@ parameters: - src checkMissingIterableValueType: true - checkGenericClassInNonGenericObjectType: false reportUnmatchedIgnoredErrors: true ignoreErrors: diff --git a/src/Concerns/RetrievesValues.php b/src/Concerns/RetrievesValues.php index 56f3d2c8..c7c6cdd9 100644 --- a/src/Concerns/RetrievesValues.php +++ b/src/Concerns/RetrievesValues.php @@ -14,6 +14,8 @@ trait RetrievesValues * * Safely retrieve the value at the given key from an object or array. * + * @template TRetrievableValue + * * @param array|object $value * @param TRetrievableValue|null $default * diff --git a/src/Each.php b/src/Each.php index e16933be..6a8a499d 100644 --- a/src/Each.php +++ b/src/Each.php @@ -7,7 +7,9 @@ namespace Pest; /** * @internal * - * @mixin Expectation + * @template TEachValue + * + * @mixin Expectation */ final class Each { @@ -15,14 +17,21 @@ final class Each /** * Creates an expectation on each item of the iterable "value". + * + * @param Expectation $original */ public function __construct(private Expectation $original) { - // .. } /** * Creates a new expectation. + * + * @template TValue + * + * @param TValue $value + * + * @return Expectation */ public function and(mixed $value): Expectation { @@ -31,6 +40,8 @@ final class Each /** * Creates the opposite expectation for the value. + * + * @return self */ public function not(): Each { @@ -43,6 +54,8 @@ final class Each * Dynamically calls methods on the class with the given arguments on each item. * * @param array $arguments + * + * @return self */ public function __call(string $name, array $arguments): Each { @@ -58,6 +71,8 @@ final class Each /** * Dynamically calls methods on the class without any arguments on each item. + * + * @return self */ public function __get(string $name): Each { diff --git a/src/Expectation.php b/src/Expectation.php index 54ad80e2..8d47d7dc 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -46,18 +46,18 @@ final class Expectation * * @param TValue $value */ - public function __construct( - public mixed $value - ) { - // .. + public function __construct(public mixed $value) + { } /** * Creates a new expectation. * - * @param TValue $value + * @template TAndValue * - * @return Expectation + * @param TAndValue $value + * + * @return self */ public function and(mixed $value): Expectation { @@ -66,6 +66,8 @@ final class Expectation /** * Creates a new expectation with the decoded JSON value. + * + * @return self */ public function json(): Expectation { @@ -94,6 +96,8 @@ final class Expectation /** * Send the expectation value to Ray along with all given arguments. + * + * @return self */ public function ray(mixed ...$arguments): self { @@ -106,6 +110,8 @@ final class Expectation /** * Creates the opposite expectation for the value. + * + * @return OppositeExpectation */ public function not(): OppositeExpectation { @@ -114,6 +120,8 @@ final class Expectation /** * Creates an expectation on each item of the iterable "value". + * + * @return Each */ public function each(callable $callback = null): Each { @@ -135,7 +143,9 @@ final class Expectation * * @template TSequenceValue * - * @param (callable(self, self): void)|TSequenceValue ...$callbacks + * @param (callable(self, self): void)|TSequenceValue ...$callbacks + * + * @return self */ public function sequence(mixed ...$callbacks): Expectation { @@ -177,15 +187,13 @@ final class Expectation * @template TMatchSubject of array-key * * @param (callable(): TMatchSubject)|TMatchSubject $subject - * @param array): mixed)|TValue> $expressions + * @param array): mixed)|TValue> $expressions + * + * @return self */ public function match(mixed $subject, array $expressions): Expectation { - $subject = is_callable($subject) - ? $subject - : fn () => $subject; - - $subject = $subject(); + $subject = $subject instanceof Closure ? $subject() : $subject; $matched = false; @@ -218,6 +226,8 @@ final class Expectation * * @param (callable(): bool)|bool $condition * @param callable(Expectation): mixed $callback + * + * @return self */ public function unless(callable|bool $condition, callable $callback): Expectation { @@ -234,7 +244,9 @@ final class Expectation * Apply the callback if the given "condition" is truthy. * * @param (callable(): bool)|bool $condition - * @param callable(Expectation): mixed $callback + * @param callable(self): mixed $callback + * + * @return self */ public function when(callable|bool $condition, callable $callback): Expectation { @@ -255,6 +267,8 @@ final class Expectation * Asserts that two variables have the same type and * value. Used on objects, it asserts that two * variables reference the same object. + * + * @return self */ public function toBe(mixed $expected): Expectation { @@ -265,6 +279,8 @@ final class Expectation /** * Asserts that the value is empty. + * + * @return self */ public function toBeEmpty(): Expectation { @@ -275,6 +291,8 @@ final class Expectation /** * Asserts that the value is true. + * + * @return self */ public function toBeTrue(): Expectation { @@ -285,6 +303,8 @@ final class Expectation /** * Asserts that the value is truthy. + * + * @return self */ public function toBeTruthy(): Expectation { @@ -295,6 +315,8 @@ final class Expectation /** * Asserts that the value is false. + * + * @return self */ public function toBeFalse(): Expectation { @@ -305,6 +327,8 @@ final class Expectation /** * Asserts that the value is falsy. + * + * @return self */ public function toBeFalsy(): Expectation { @@ -315,6 +339,8 @@ final class Expectation /** * Asserts that the value is greater than $expected. + * + * @return self */ public function toBeGreaterThan(int|float $expected): Expectation { @@ -325,6 +351,8 @@ final class Expectation /** * Asserts that the value is greater than or equal to $expected. + * + * @return self */ public function toBeGreaterThanOrEqual(int|float $expected): Expectation { @@ -335,6 +363,8 @@ final class Expectation /** * Asserts that the value is less than or equal to $expected. + * + * @return self */ public function toBeLessThan(int|float $expected): Expectation { @@ -345,6 +375,8 @@ final class Expectation /** * Asserts that the value is less than $expected. + * + * @return self */ public function toBeLessThanOrEqual(int|float $expected): Expectation { @@ -355,6 +387,8 @@ final class Expectation /** * Asserts that $needle is an element of the value. + * + * @return self */ public function toContain(mixed ...$needles): Expectation { @@ -377,6 +411,8 @@ final class Expectation * Asserts that the value starts with $expected. * * @param non-empty-string $expected + * + * @return self */ public function toStartWith(string $expected): Expectation { @@ -393,6 +429,8 @@ final class Expectation * Asserts that the value ends with $expected. * * @param non-empty-string $expected + * + * @return self */ public function toEndWith(string $expected): Expectation { @@ -407,6 +445,8 @@ final class Expectation /** * Asserts that $number matches value's Length. + * + * @return self */ public function toHaveLength(int $number): Expectation { @@ -437,6 +477,8 @@ final class Expectation /** * Asserts that $count matches the number of elements of the value. + * + * @return self */ public function toHaveCount(int $count): Expectation { @@ -451,6 +493,8 @@ final class Expectation /** * Asserts that the value contains the property $name. + * + * @return self */ public function toHaveProperty(string $name, mixed $value = null): Expectation { @@ -471,6 +515,8 @@ final class Expectation * Asserts that the value contains the provided properties $names. * * @param iterable $names + * + * @return self */ public function toHaveProperties(iterable $names): Expectation { @@ -483,6 +529,8 @@ final class Expectation /** * Asserts that two variables have the same value. + * + * @return self */ public function toEqual(mixed $expected): Expectation { @@ -499,6 +547,8 @@ final class Expectation * are sorted before they are compared. When $expected and $this->value * are objects, each object is converted to an array containing all * private, protected and public attributes. + * + * @return self */ public function toEqualCanonicalizing(mixed $expected): Expectation { @@ -510,6 +560,8 @@ final class Expectation /** * Asserts that the absolute difference between the value and $expected * is lower than $delta. + * + * @return self */ public function toEqualWithDelta(mixed $expected, float $delta): Expectation { @@ -522,6 +574,8 @@ final class Expectation * Asserts that the value is one of the given values. * * @param iterable $values + * + * @return self */ public function toBeIn(iterable $values): Expectation { @@ -532,6 +586,8 @@ final class Expectation /** * Asserts that the value is infinite. + * + * @return self */ public function toBeInfinite(): Expectation { @@ -544,6 +600,8 @@ final class Expectation * Asserts that the value is an instance of $class. * * @param class-string $class + * + * @return self */ public function toBeInstanceOf(string $class): Expectation { @@ -554,6 +612,8 @@ final class Expectation /** * Asserts that the value is an array. + * + * @return self */ public function toBeArray(): Expectation { @@ -564,6 +624,8 @@ final class Expectation /** * Asserts that the value is of type bool. + * + * @return self */ public function toBeBool(): Expectation { @@ -574,6 +636,8 @@ final class Expectation /** * Asserts that the value is of type callable. + * + * @return self */ public function toBeCallable(): Expectation { @@ -584,6 +648,8 @@ final class Expectation /** * Asserts that the value is of type float. + * + * @return self */ public function toBeFloat(): Expectation { @@ -594,6 +660,8 @@ final class Expectation /** * Asserts that the value is of type int. + * + * @return self */ public function toBeInt(): Expectation { @@ -604,6 +672,8 @@ final class Expectation /** * Asserts that the value is of type iterable. + * + * @return self */ public function toBeIterable(): Expectation { @@ -614,6 +684,8 @@ final class Expectation /** * Asserts that the value is of type numeric. + * + * @return self */ public function toBeNumeric(): Expectation { @@ -624,6 +696,8 @@ final class Expectation /** * Asserts that the value is of type object. + * + * @return self */ public function toBeObject(): Expectation { @@ -634,6 +708,8 @@ final class Expectation /** * Asserts that the value is of type resource. + * + * @return self */ public function toBeResource(): Expectation { @@ -644,6 +720,8 @@ final class Expectation /** * Asserts that the value is of type scalar. + * + * @return self */ public function toBeScalar(): Expectation { @@ -654,6 +732,8 @@ final class Expectation /** * Asserts that the value is of type string. + * + * @return self */ public function toBeString(): Expectation { @@ -664,6 +744,8 @@ final class Expectation /** * Asserts that the value is a JSON string. + * + * @return self */ public function toBeJson(): Expectation { @@ -677,6 +759,8 @@ final class Expectation /** * Asserts that the value is NAN. + * + * @return self */ public function toBeNan(): Expectation { @@ -687,6 +771,8 @@ final class Expectation /** * Asserts that the value is null. + * + * @return self */ public function toBeNull(): Expectation { @@ -697,6 +783,8 @@ final class Expectation /** * Asserts that the value array has the provided $key. + * + * @return self */ public function toHaveKey(string|int $key, mixed $value = null): Expectation { @@ -725,6 +813,8 @@ final class Expectation * Asserts that the value array has the provided $keys. * * @param array $keys + * + * @return self */ public function toHaveKeys(array $keys): Expectation { @@ -737,6 +827,8 @@ final class Expectation /** * Asserts that the value is a directory. + * + * @return self */ public function toBeDirectory(): Expectation { @@ -751,6 +843,8 @@ final class Expectation /** * Asserts that the value is a directory and is readable. + * + * @return self */ public function toBeReadableDirectory(): Expectation { @@ -765,6 +859,8 @@ final class Expectation /** * Asserts that the value is a directory and is writable. + * + * @return self */ public function toBeWritableDirectory(): Expectation { @@ -779,6 +875,8 @@ final class Expectation /** * Asserts that the value is a file. + * + * @return self */ public function toBeFile(): Expectation { @@ -793,6 +891,8 @@ final class Expectation /** * Asserts that the value is a file and is readable. + * + * @return self */ public function toBeReadableFile(): Expectation { @@ -807,6 +907,8 @@ final class Expectation /** * Asserts that the value is a file and is writable. + * + * @return self */ public function toBeWritableFile(): Expectation { @@ -822,6 +924,8 @@ final class Expectation * Asserts that the value array matches the given array subset. * * @param iterable $array + * + * @return self */ public function toMatchArray(iterable|object $array): Expectation { @@ -853,6 +957,8 @@ final class Expectation * of the properties of an given object. * * @param iterable|object $object + * + * @return self */ public function toMatchObject(iterable|object $object): Expectation { @@ -881,6 +987,8 @@ final class Expectation /** * Asserts that the value matches a regular expression. + * + * @return self */ public function toMatch(string $expression): Expectation { @@ -894,6 +1002,8 @@ final class Expectation /** * Asserts that the value matches a constraint. + * + * @return self */ public function toMatchConstraint(Constraint $constraint): Expectation { @@ -906,6 +1016,8 @@ final class Expectation * Asserts that executing value throws an exception. * * @param (Closure(Throwable): mixed)|string $exception + * + * @return self */ public function toThrow(callable|string $exception, string $exceptionMessage = null): Expectation { @@ -970,7 +1082,7 @@ final class Expectation * * @param array $parameters * - * @return HigherOrderExpectation|mixed + * @return HigherOrderExpectation|self|mixed */ public function __call(string $method, array $parameters) { @@ -985,6 +1097,8 @@ final class Expectation /** * Dynamically calls methods on the class without any arguments * or creates a new higher order expectation. + * + * @return self|OppositeExpectation|Each|HigherOrderExpectation */ public function __get(string $name): Expectation|OppositeExpectation|Each|HigherOrderExpectation { diff --git a/src/Functions.php b/src/Functions.php index fe1dd39a..80e0d9e0 100644 --- a/src/Functions.php +++ b/src/Functions.php @@ -18,7 +18,11 @@ if (!function_exists('expect')) { /** * Creates a new expectation. * - * @param mixed $value the Value + * @template TValue + * + * @param TValue $value the Value + * + * @return Expectation|Extendable */ function expect($value = null): Expectation|Extendable { diff --git a/src/HigherOrderExpectation.php b/src/HigherOrderExpectation.php index eb959cd4..ed54e09b 100644 --- a/src/HigherOrderExpectation.php +++ b/src/HigherOrderExpectation.php @@ -4,19 +4,23 @@ declare(strict_types=1); namespace Pest; -use Pest\Concerns\Expectable; use Pest\Concerns\RetrievesValues; /** * @internal * - * @mixin Expectation + * @template TOriginalValue + * @template TValue + * + * @mixin Expectation */ final class HigherOrderExpectation { - use Expectable; use RetrievesValues; + /** + * @var Expectation|Each + */ private Expectation|Each $expectation; private bool $opposite = false; @@ -25,6 +29,9 @@ final class HigherOrderExpectation /** * Creates a new higher order expectation. + * + * @param Expectation $original + * @param TValue $value */ public function __construct(private Expectation $original, mixed $value) { @@ -33,6 +40,8 @@ final class HigherOrderExpectation /** * Creates the opposite expectation for the value. + * + * @return self */ public function not(): HigherOrderExpectation { @@ -41,14 +50,28 @@ final class HigherOrderExpectation return $this; } + /** + * Creates a new Expectation. + * + * @template TExpectValue + * + * @param TExpectValue $value + * + * @return Expectation + */ + public function expect(mixed $value): Expectation + { + return new Expectation($value); + } + /** * Creates a new expectation. * - * @template TValue + * @template TExpectValue * - * @param TValue $value + * @param TExpectValue $value * - * @return Expectation + * @return Expectation */ public function and(mixed $value): Expectation { @@ -59,6 +82,8 @@ final class HigherOrderExpectation * Dynamically calls methods on the class with the given arguments. * * @param array $arguments + * + * @return self|self */ public function __call(string $name, array $arguments): self { @@ -72,6 +97,8 @@ final class HigherOrderExpectation /** * Accesses properties in the value or in the expectation. + * + * @return self|self */ public function __get(string $name): self { @@ -99,6 +126,8 @@ final class HigherOrderExpectation /** * Retrieve the applicable value based on the current reset condition. + * + * @return TOriginalValue|TValue */ private function getValue(): mixed { @@ -109,6 +138,8 @@ final class HigherOrderExpectation * Performs the given assertion with the current expectation. * * @param array $arguments + * + * @return self */ private function performAssertion(string $name, array $arguments): self { diff --git a/src/OppositeExpectation.php b/src/OppositeExpectation.php index da9ec6ab..e2062e75 100644 --- a/src/OppositeExpectation.php +++ b/src/OppositeExpectation.php @@ -10,29 +10,34 @@ use SebastianBergmann\Exporter\Exporter; /** * @internal * - * @mixin Expectation + * @template TValue + * + * @mixin Expectation */ final class OppositeExpectation { /** * Creates a new opposite expectation. + * + * @param Expectation $original */ public function __construct(private Expectation $original) { - // .. } /** * Asserts that the value array not has the provided $keys. * * @param array $keys + * + * @return Expectation */ public function toHaveKeys(array $keys): Expectation { foreach ($keys as $key) { try { $this->original->toHaveKey($key); - } catch (ExpectationFailedException $exception) { + } catch (ExpectationFailedException) { continue; } @@ -47,14 +52,14 @@ final class OppositeExpectation * * @param array $arguments * - * @return Expectation|never + * @return Expectation|Expectation|never */ public function __call(string $name, array $arguments): Expectation { try { /* @phpstan-ignore-next-line */ $this->original->{$name}(...$arguments); - } catch (ExpectationFailedException $exception) { + } catch (ExpectationFailedException) { return $this->original; } @@ -64,13 +69,13 @@ final class OppositeExpectation /** * Handle dynamic properties gets into the original expectation. * - * @return Expectation|never + * @return Expectation|Expectation|never */ public function __get(string $name): Expectation { try { $this->original->{$name}; // @phpstan-ignore-line - } catch (ExpectationFailedException $exception) { // @phpstan-ignore-line + } catch (ExpectationFailedException) { // @phpstan-ignore-line return $this->original; } diff --git a/src/Support/HigherOrderMessage.php b/src/Support/HigherOrderMessage.php index 575eaf98..766a9743 100644 --- a/src/Support/HigherOrderMessage.php +++ b/src/Support/HigherOrderMessage.php @@ -38,6 +38,10 @@ final class HigherOrderMessage /** * Re-throws the given `$throwable` with the good line and filename. + * + * @template TValue of object + * + * @param TValue $target */ public function call(object $target): mixed { @@ -59,7 +63,7 @@ final class HigherOrderMessage Reflection::setPropertyValue($throwable, 'line', $this->line); if ($throwable->getMessage() === self::getUndefinedMethodMessage($target, $this->name)) { - /** @var ReflectionClass $reflection */ + /** @var ReflectionClass $reflection */ $reflection = new ReflectionClass($target); /* @phpstan-ignore-next-line */ $reflection = $reflection->getParentClass() ?: $reflection; diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index 479a86f6..b1d6216b 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -118,11 +118,14 @@ final class Reflection /** * Sets the property value of the given object. * - * @param mixed $value + * @template TValue of object + * + * @param TValue $object + * @param mixed $value */ public static function setPropertyValue(object $object, string $property, $value): void { - /** @var ReflectionClass $reflectionClass */ + /** @var ReflectionClass $reflectionClass */ $reflectionClass = new ReflectionClass($object); $reflectionProperty = null;