diff --git a/src/Concerns/Extendable.php b/src/Concerns/Extendable.php index ee87f9ab..0d689452 100644 --- a/src/Concerns/Extendable.php +++ b/src/Concerns/Extendable.php @@ -15,7 +15,7 @@ trait Extendable /** * @var array */ - private static $extends = []; + private static array $extends = []; /** * Register a custom extend. diff --git a/src/Concerns/Testable.php b/src/Concerns/Testable.php index 7244c4f5..d90229cd 100644 --- a/src/Concerns/Testable.php +++ b/src/Concerns/Testable.php @@ -13,61 +13,42 @@ use PHPUnit\Framework\ExecutionOrderDependency; use Throwable; /** - * To avoid inheritance conflicts, all the fields related to Pest only will be prefixed by double underscore. - * * @internal */ trait Testable { /** - * The test case description. Contains the first - * argument of global functions like `it` and `test`. - * - * @var string + * The Test Case description. */ - private $__description; + private string $__description; /** - * Holds the test closure function. - * - * @var Closure + * The Test Case "test" closure. */ - private $__test; + private Closure $__test; /** - * Holds a global/shared beforeEach ("set up") closure if one has been - * defined. - * - * @var Closure|null + * The Test Case "setUp" closure. */ - private $__beforeEach = null; + private ?Closure $__beforeEach = null; /** - * Holds a global/shared afterEach ("tear down") closure if one has been - * defined. - * - * @var Closure|null + * The Test Case "tearDown" closure. */ - private $__afterEach = null; + private ?Closure $__afterEach = null; /** - * Holds a global/shared beforeAll ("set up before") closure if one has been - * defined. - * - * @var Closure|null + * The Test Case "setUpBeforeClass" closure. */ - private static $__beforeAll = null; + private static ?Closure $__beforeAll = null; /** - * Holds a global/shared afterAll ("tear down after") closure if one has - * been defined. - * - * @var Closure|null + * The test "tearDownAfterClass" closure. */ - private static $__afterAll = null; + private static ?Closure $__afterAll = null; /** - * Creates a new instance of the test case. + * Creates a new Test Case instance. */ public function __construct(Closure $test, string $description, array $data) { @@ -82,7 +63,7 @@ trait Testable } /** - * Adds the groups to the current test case. + * Adds groups to the Test Case. */ public function addGroups(array $groups): void { @@ -92,14 +73,14 @@ trait Testable } /** - * Add dependencies to the test case and map them to instances of ExecutionOrderDependency. + * Adds dependencies to the Test Case. */ public function addDependencies(array $tests): void { - $className = get_class($this); + $className = $this::class; - $tests = array_map(function (string $test) use ($className): ExecutionOrderDependency { - if (strpos($test, '::') === false) { + $tests = array_map(static function (string $test) use ($className): ExecutionOrderDependency { + if (!str_contains($test, '::')) { $test = "{$className}::{$test}"; } @@ -110,8 +91,7 @@ trait Testable } /** - * Add a shared/"global" before all test hook that will execute **before** - * the test defined `beforeAll` hook(s). + * Adds a new "setUpBeforeClass" to the Test Case. */ public function __addBeforeAll(?Closure $hook): void { @@ -125,8 +105,7 @@ trait Testable } /** - * Add a shared/"global" after all test hook that will execute **before** - * the test defined `afterAll` hook(s). + * Adds a new "tearDownAfterClass" to the Test Case. */ public function __addAfterAll(?Closure $hook): void { @@ -140,8 +119,7 @@ trait Testable } /** - * Add a shared/"global" before each test hook that will execute **before** - * the test defined `beforeEach` hook. + * Adds a new "setUp" to the Test Case. */ public function __addBeforeEach(?Closure $hook): void { @@ -149,8 +127,7 @@ trait Testable } /** - * Add a shared/"global" after each test hook that will execute **before** - * the test defined `afterEach` hook. + * Adds a new "tearDown" to the Test Case. */ public function __addAfterEach(?Closure $hook): void { @@ -158,7 +135,7 @@ trait Testable } /** - * Add a shared/global hook and compose them if more than one is passed. + * Adds a new "hook" to the Test Case. */ private function __addHook(string $property, ?Closure $hook): void { @@ -172,9 +149,7 @@ trait Testable } /** - * Returns the test case name. Note that, in Pest - * we ignore withDataset argument as the description - * already contains the dataset description. + * Gets the Test Case name. */ public function getName(bool $withDataSet = true): string { @@ -183,13 +158,16 @@ trait Testable : $this->__description; } - public static function __getFileName(): string + /** + * Gets the Test Case filename. + */ + public static function __getFilename(): string { return self::$__filename; } /** - * This method is called before the first test of this test class is run. + * This method is called before the first test of this Test Case is run. */ public static function setUpBeforeClass(): void { @@ -205,7 +183,7 @@ trait Testable } /** - * This method is called after the last test of this test class is run. + * This method is called after the last test of this Test Case is run. */ public static function tearDownAfterClass(): void { @@ -221,7 +199,7 @@ trait Testable } /** - * Gets executed before the test. + * Gets executed before the Test Case. */ protected function setUp(): void { @@ -239,7 +217,7 @@ trait Testable } /** - * Gets executed after the test. + * Gets executed after the Test Case. */ protected function tearDown(): void { @@ -257,7 +235,7 @@ trait Testable } /** - * Returns the test case as string. + * Gets the Test Case filename and description. */ public function toString(): string { @@ -269,13 +247,11 @@ trait Testable } /** - * Runs the test. - * - * @return mixed + * Executes the Test Case current test. * * @throws Throwable */ - public function __test() + public function __test(): mixed { return $this->__callClosure($this->__test, $this->__resolveTestArguments(func_get_args())); } @@ -287,23 +263,20 @@ trait Testable */ private function __resolveTestArguments(array $arguments): array { - return array_map(function ($data) { - return $data instanceof Closure ? $this->__callClosure($data, []) : $data; - }, $arguments); + return array_map(fn ($data) => $data instanceof Closure ? $this->__callClosure($data, []) : $data, $arguments); } /** - * @return mixed - * * @throws Throwable */ - private function __callClosure(Closure $closure, array $arguments) + private function __callClosure(Closure $closure, array $arguments): mixed { - return ExceptionTrace::ensure(function () use ($closure, $arguments) { - return call_user_func_array(Closure::bind($closure, $this, get_class($this)), $arguments); - }); + return ExceptionTrace::ensure(fn () => call_user_func_array(Closure::bind($closure, $this, $this::class), $arguments)); } + /** + * Gets the Test Case name that should be used by printers. + */ public function getPrintableTestCaseName(): string { return ltrim(self::class, 'P\\'); diff --git a/src/Console/Help.php b/src/Console/Help.php index 4554b728..0bb43477 100644 --- a/src/Console/Help.php +++ b/src/Console/Help.php @@ -20,12 +20,9 @@ final class Help ' --group= Only runs tests from the specified group(s)', ]; - /** @var OutputInterface */ - private $output; - - public function __construct(OutputInterface $output) + public function __construct(private OutputInterface $output) { - $this->output = $output; + // .. } public function __invoke(): void diff --git a/src/Console/Thanks.php b/src/Console/Thanks.php index 4e3791dc..5ae807ec 100644 --- a/src/Console/Thanks.php +++ b/src/Console/Thanks.php @@ -25,12 +25,9 @@ final class Thanks ' https://github.com/sponsors/nunomaduro', ]; - /** @var OutputInterface */ - private $output; - - public function __construct(OutputInterface $output) + public function __construct(private OutputInterface $output) { - $this->output = $output; + // .. } /** diff --git a/src/Datasets.php b/src/Datasets.php index 89725107..0a245079 100644 --- a/src/Datasets.php +++ b/src/Datasets.php @@ -20,14 +20,14 @@ final class Datasets * * @var array> */ - private static $datasets = []; + private static array $datasets = []; /** * Sets the given. * * @param Closure|iterable $data */ - public static function set(string $name, $data): void + public static function set(string $name, Closure|iterable $data): void { if (array_key_exists($name, self::$datasets)) { throw new DatasetAlreadyExist($name); @@ -39,7 +39,7 @@ final class Datasets /** * @return Closure|iterable */ - public static function get(string $name) + public static function get(string $name): Closure|iterable { if (!array_key_exists($name, self::$datasets)) { throw new DatasetDoesNotExist($name); @@ -161,10 +161,9 @@ final class Datasets } /** - * @param int|string $key * @param array $data */ - private static function getDataSetDescription($key, array $data): string + private static function getDataSetDescription(int|string $key, array $data): string { $exporter = new Exporter(); diff --git a/src/Each.php b/src/Each.php index f02a8e1e..08c8f753 100644 --- a/src/Each.php +++ b/src/Each.php @@ -11,22 +11,14 @@ namespace Pest; */ final class Each { - /** - * @var Expectation - */ - private $original; - - /** - * @var bool - */ - private $opposite = false; + private bool $opposite = false; /** * Creates an expectation on each item of the iterable "value". */ - public function __construct(Expectation $original) + public function __construct(private Expectation $original) { - $this->original = $original; + // .. } /** diff --git a/src/Exceptions/DatasetMissing.php b/src/Exceptions/DatasetMissing.php index b8f0cb2d..023487e8 100644 --- a/src/Exceptions/DatasetMissing.php +++ b/src/Exceptions/DatasetMissing.php @@ -27,9 +27,7 @@ final class DatasetMissing extends BadFunctionCallException implements Exception "A test with the description '%s' has %d argument(s) ([%s]) and no dataset(s) provided in %s", $name, count($args), - implode(', ', array_map(static function (string $arg, string $type): string { - return sprintf('%s $%s', $type, $arg); - }, array_keys($args), $args)), + implode(', ', array_map(static fn (string $arg, string $type): string => sprintf('%s $%s', $type, $arg), array_keys($args), $args)), $file, )); } diff --git a/src/Expectation.php b/src/Expectation.php index a973c760..28ea26af 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -29,37 +29,26 @@ use Throwable; */ final class Expectation { - use Extendable { + use RetrievesValues, Extendable { __call as __extendsCall; } - use RetrievesValues; - - /** - * The expectation value. - * - * @readonly - * - * @var mixed - */ - public $value; /** * The exporter instance, if any. * * @readonly - * - * @var Exporter|null */ - private $exporter; + private ?Exporter $exporter = null; /** * Creates a new expectation. * * @param TValue $value */ - public function __construct($value) - { - $this->value = $value; + public function __construct( + public mixed $value + ) { + // .. } /** @@ -69,7 +58,7 @@ final class Expectation * * @return Expectation */ - public function and($value): Expectation + public function and(mixed $value): Expectation { return new self($value); } @@ -103,9 +92,9 @@ final class Expectation /** * Send the expectation value to Ray along with all given arguments. * - * @param mixed $arguments + * @param ...mixed $arguments */ - public function ray(...$arguments): self + public function ray(mixed ...$arguments): self { if (function_exists('ray')) { // @phpstan-ignore-next-line @@ -146,9 +135,9 @@ final class Expectation * * @template TSequenceValue * - * @param callable(self, self): void|TSequenceValue ...$callbacks + * @param (callable(self, self): void)|TSequenceValue ...$callbacks */ - public function sequence(...$callbacks): Expectation + public function sequence(mixed ...$callbacks): Expectation { if (!is_iterable($this->value)) { throw new BadMethodCallException('Expectation value is not iterable.'); @@ -187,16 +176,14 @@ final class Expectation * * @template TMatchSubject of array-key * - * @param callable(): TMatchSubject|TMatchSubject $subject + * @param (callable(): TMatchSubject)|TMatchSubject $subject * @param array): mixed)|TValue> $expressions */ - public function match($subject, array $expressions): Expectation + public function match(mixed $subject, array $expressions): Expectation { $subject = is_callable($subject) ? $subject - : function () use ($subject) { - return $subject; - }; + : fn () => $subject; $subject = $subject(); @@ -229,15 +216,15 @@ final class Expectation /** * Apply the callback if the given "condition" is falsy. * - * @param (callable(): bool)|bool $condition + * @param (callable(): bool)|bool $condition * @param callable(Expectation): mixed $callback */ - public function unless($condition, callable $callback): Expectation + public function unless(callable|bool $condition, callable $callback): Expectation { $condition = is_callable($condition) ? $condition : static function () use ($condition): bool { - return (bool) $condition; // @phpstan-ignore-line + return $condition; // @phpstan-ignore-line }; return $this->when(!$condition(), $callback); @@ -246,15 +233,15 @@ final class Expectation /** * Apply the callback if the given "condition" is truthy. * - * @param (callable(): bool)|bool $condition + * @param (callable(): bool)|bool $condition * @param callable(Expectation): mixed $callback */ - public function when($condition, callable $callback): Expectation + public function when(callable|bool $condition, callable $callback): Expectation { $condition = is_callable($condition) ? $condition : static function () use ($condition): bool { - return (bool) $condition; // @phpstan-ignore-line + return $condition; // @phpstan-ignore-line }; if ($condition()) { @@ -268,10 +255,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. - * - * @param mixed $expected */ - public function toBe($expected): Expectation + public function toBe(mixed $expected): Expectation { Assert::assertSame($expected, $this->value); @@ -330,10 +315,8 @@ final class Expectation /** * Asserts that the value is greater than $expected. - * - * @param int|float $expected */ - public function toBeGreaterThan($expected): Expectation + public function toBeGreaterThan(int|float $expected): Expectation { Assert::assertGreaterThan($expected, $this->value); @@ -342,10 +325,8 @@ final class Expectation /** * Asserts that the value is greater than or equal to $expected. - * - * @param int|float $expected */ - public function toBeGreaterThanOrEqual($expected): Expectation + public function toBeGreaterThanOrEqual(int|float $expected): Expectation { Assert::assertGreaterThanOrEqual($expected, $this->value); @@ -354,10 +335,8 @@ final class Expectation /** * Asserts that the value is less than or equal to $expected. - * - * @param int|float $expected */ - public function toBeLessThan($expected): Expectation + public function toBeLessThan(int|float $expected): Expectation { Assert::assertLessThan($expected, $this->value); @@ -366,10 +345,8 @@ final class Expectation /** * Asserts that the value is less than $expected. - * - * @param int|float $expected */ - public function toBeLessThanOrEqual($expected): Expectation + public function toBeLessThanOrEqual(int|float $expected): Expectation { Assert::assertLessThanOrEqual($expected, $this->value); @@ -378,10 +355,8 @@ final class Expectation /** * Asserts that $needle is an element of the value. - * - * @param mixed $needles */ - public function toContain(...$needles): Expectation + public function toContain(mixed ...$needles): Expectation { foreach ($needles as $needle) { if (is_string($this->value)) { @@ -456,10 +431,8 @@ final class Expectation /** * Asserts that the value contains the property $name. - * - * @param mixed $value */ - public function toHaveProperty(string $name, $value = null): Expectation + public function toHaveProperty(string $name, mixed $value = null): Expectation { $this->toBeObject(); @@ -489,10 +462,8 @@ final class Expectation /** * Asserts that two variables have the same value. - * - * @param mixed $expected */ - public function toEqual($expected): Expectation + public function toEqual(mixed $expected): Expectation { Assert::assertEquals($expected, $this->value); @@ -507,10 +478,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. - * - * @param mixed $expected */ - public function toEqualCanonicalizing($expected): Expectation + public function toEqualCanonicalizing(mixed $expected): Expectation { Assert::assertEqualsCanonicalizing($expected, $this->value); @@ -520,10 +489,8 @@ final class Expectation /** * Asserts that the absolute difference between the value and $expected * is lower than $delta. - * - * @param mixed $expected */ - public function toEqualWithDelta($expected, float $delta): Expectation + public function toEqualWithDelta(mixed $expected, float $delta): Expectation { Assert::assertEqualsWithDelta($expected, $this->value, $delta); @@ -555,9 +522,9 @@ final class Expectation /** * Asserts that the value is an instance of $class. * - * @param string $class + * @param class-string $class */ - public function toBeInstanceOf($class): Expectation + public function toBeInstanceOf(string $class): Expectation { /* @phpstan-ignore-next-line */ Assert::assertInstanceOf($class, $this->value); @@ -708,11 +675,8 @@ final class Expectation /** * Asserts that the value array has the provided $key. - * - * @param string|int $key - * @param mixed $value */ - public function toHaveKey($key, $value = null): Expectation + public function toHaveKey(string|int $key, mixed $value = null): Expectation { if (is_object($this->value) && method_exists($this->value, 'toArray')) { $array = $this->value->toArray(); @@ -812,9 +776,9 @@ final class Expectation /** * Asserts that the value array matches the given array subset. * - * @param array $array + * @param iterable $array */ - public function toMatchArray($array): Expectation + public function toMatchArray(iterable|object $array): Expectation { if (is_object($this->value) && method_exists($this->value, 'toArray')) { $valueAsArray = $this->value->toArray(); @@ -843,9 +807,9 @@ final class Expectation * Asserts that the value object matches a subset * of the properties of an given object. * - * @param array|object $object + * @param iterable|object $object */ - public function toMatchObject($object): Expectation + public function toMatchObject(iterable|object $object): Expectation { foreach ((array) $object as $property => $value) { Assert::assertTrue(property_exists($this->value, $property)); @@ -891,7 +855,7 @@ final class Expectation * * @param (Closure(Throwable): mixed)|string $exception */ - public function toThrow($exception, string $exceptionMessage = null): Expectation + public function toThrow(callable|string $exception, string $exceptionMessage = null): Expectation { $callback = NullClosure::create(); @@ -938,10 +902,8 @@ final class Expectation /** * Exports the given value. - * - * @param mixed $value */ - private function export($value): string + private function export(mixed $value): string { if ($this->exporter === null) { $this->exporter = new Exporter(); @@ -971,10 +933,8 @@ final class Expectation /** * Dynamically calls methods on the class without any arguments * or creates a new higher order expectation. - * - * @return Expectation|HigherOrderExpectation */ - public function __get(string $name) + public function __get(string $name): Expectation|OppositeExpectation|Each|HigherOrderExpectation { if (!method_exists($this, $name) && !static::hasExtend($name)) { return new HigherOrderExpectation($this, $this->retrieve($name, $this->value)); diff --git a/src/Factories/TestCaseFactory.php b/src/Factories/TestCaseFactory.php index fc2fade2..e9c288c1 100644 --- a/src/Factories/TestCaseFactory.php +++ b/src/Factories/TestCaseFactory.php @@ -22,97 +22,68 @@ use RuntimeException; */ final class TestCaseFactory { - /** - * Holds the test filename. - * - * @readonly - * - * @var string - */ - public $filename; - /** * Marks this test case as only. * * @readonly - * - * @var bool */ - public $only = false; - - /** - * Holds the test description. - * - * If the description is null, means that it - * will be created with the given assertions. - * - * @var string|null - */ - public $description; + public bool $only = false; /** * Holds the test closure. * * @readonly - * - * @var Closure */ - public $test; + public Closure $test; /** * Holds the dataset, if any. * * @var array|string> */ - public $datasets = []; + public array $datasets = []; /** * The FQN of the test case class. * - * @var string + * @var class-string */ - public $class = TestCase::class; + public string $class = TestCase::class; /** * An array of FQN of the class traits. * * @var array */ - public $traits = [ + public array $traits = [ Concerns\Testable::class, Concerns\Expectable::class, ]; /** - * Holds the higher order messages - * for the factory that are proxyble. - * - * @var HigherOrderMessageCollection + * Holds the higher order messages for the factory that are proxyble. */ - public $factoryProxies; + public HigherOrderMessageCollection $factoryProxies; /** * Holds the higher order messages that are proxyble. - * - * @var HigherOrderMessageCollection */ - public $proxies; + public HigherOrderMessageCollection $proxies; /** * Holds the higher order messages that are chainable. - * - * @var HigherOrderMessageCollection */ - public $chains; + public HigherOrderMessageCollection $chains; /** * Creates a new anonymous test case pending object. */ - public function __construct(string $filename, string $description = null, Closure $closure = null) + public function __construct( + public string $filename, + public ?string $description = null, + Closure $closure = null) { - $this->filename = $filename; - $this->description = $description; - $this->test = $closure ?? function (): void { + $this->test = $closure ?? function (): void { if (Assert::getCount() === 0) { self::markTestIncomplete(); // @phpstan-ignore-line } @@ -146,7 +117,7 @@ final class TestCaseFactory $chains->chain($this); /* @phpstan-ignore-next-line */ - return call_user_func(Closure::bind($factoryTest, $this, get_class($this)), ...func_get_args()); + return call_user_func(Closure::bind($factoryTest, $this, $this::class), ...func_get_args()); }; $className = $this->makeClassFromFilename($this->filename); @@ -170,9 +141,7 @@ final class TestCaseFactory { if ('\\' === DIRECTORY_SEPARATOR) { // In case Windows, strtolower drive name, like in UsesCall. - $filename = (string) preg_replace_callback('~^(?P[a-z]+:\\\)~i', function ($match): string { - return strtolower($match['drive']); - }, $filename); + $filename = (string) preg_replace_callback('~^(?P[a-z]+:\\\)~i', fn ($match): string => strtolower($match['drive']), $filename); } $filename = str_replace('\\\\', '\\', addslashes((string) realpath($filename))); @@ -184,9 +153,7 @@ final class TestCaseFactory // Strip out any %-encoded octets. $relativePath = (string) preg_replace('|%[a-fA-F0-9][a-fA-F0-9]|', '', $relativePath); // Remove escaped quote sequences (maintain namespace) - $relativePath = str_replace(array_map(function (string $quote): string { - return sprintf('\\%s', $quote); - }, ['\'', '"']), '', $relativePath); + $relativePath = str_replace(array_map(fn (string $quote): string => sprintf('\\%s', $quote), ['\'', '"']), '', $relativePath); // Limit to A-Z, a-z, 0-9, '_', '-'. $relativePath = (string) preg_replace('/[^A-Za-z0-9\\\\]/', '', $relativePath); @@ -196,9 +163,7 @@ final class TestCaseFactory } $hasPrintableTestCaseClassFQN = sprintf('\%s', HasPrintableTestCaseName::class); - $traitsCode = sprintf('use %s;', implode(', ', array_map(function ($trait): string { - return sprintf('\%s', $trait); - }, $this->traits))); + $traitsCode = sprintf('use %s;', implode(', ', array_map(fn ($trait): string => sprintf('\%s', $trait), $this->traits))); $partsFQN = explode('\\', $classFQN); $className = array_pop($partsFQN); diff --git a/src/Functions.php b/src/Functions.php index e7a230dc..855e415e 100644 --- a/src/Functions.php +++ b/src/Functions.php @@ -18,10 +18,8 @@ use PHPUnit\Framework\TestCase; * Creates a new expectation. * * @param mixed $value the Value - * - * @return Expectation|Extendable */ -function expect($value = null) +function expect($value = null): Expectation|Extendable { if (func_num_args() === 0) { return new Extendable(Expectation::class); @@ -60,7 +58,7 @@ if (!function_exists('dataset')) { * * @param Closure|iterable $dataset */ - function dataset(string $name, $dataset): void + function dataset(string $name, Closure|iterable $dataset): void { Datasets::set($name, $dataset); } diff --git a/src/HigherOrderExpectation.php b/src/HigherOrderExpectation.php index e436da0c..839f3311 100644 --- a/src/HigherOrderExpectation.php +++ b/src/HigherOrderExpectation.php @@ -17,39 +17,17 @@ final class HigherOrderExpectation use Expectable; use RetrievesValues; - /** - * @var Expectation - */ - private $original; + private Expectation|Each $expectation; - /** - * @var Expectation|Each - */ - private $expectation; + private bool $opposite = false; - /** - * @var bool - */ - private $opposite = false; - - /** - * @var bool - */ - private $shouldReset = false; - - /** - * @var string - */ - private $name; + private bool $shouldReset = false; /** * Creates a new higher order expectation. - * - * @param mixed $value */ - public function __construct(Expectation $original, $value) + public function __construct(private Expectation $original, mixed $value) { - $this->original = $original; $this->expectation = $this->expect($value); } @@ -72,7 +50,7 @@ final class HigherOrderExpectation * * @return Expectation */ - public function and($value): Expectation + public function and(mixed $value): Expectation { return $this->expect($value); } @@ -118,10 +96,8 @@ final class HigherOrderExpectation /** * Retrieve the applicable value based on the current reset condition. - * - * @return mixed */ - private function getValue() + private function getValue(): mixed { return $this->shouldReset ? $this->original->value : $this->expectation->value; } diff --git a/src/Logging/JUnit.php b/src/Logging/JUnit.php index da15a9b9..14595bbc 100644 --- a/src/Logging/JUnit.php +++ b/src/Logging/JUnit.php @@ -16,7 +16,6 @@ use function class_exists; use DOMDocument; use DOMElement; use Exception; -use function get_class; use function method_exists; use Pest\Concerns\Testable; use PHPUnit\Framework\AssertionFailedError; @@ -42,65 +41,50 @@ use function trim; */ final class JUnit extends Printer implements TestListener { - /** - * @var DOMDocument - */ - private $document; + private DOMDocument $document; + + private DOMElement $root; /** - * @var DOMElement + * @var array */ - private $root; - - /** - * @var DOMElement[] - */ - private $testSuites = []; + private array $testSuites = []; /** * @var int[] */ - private $testSuiteTests = [0]; + private array $testSuiteTests = [0]; /** * @var int[] */ - private $testSuiteAssertions = [0]; + private array $testSuiteAssertions = [0]; /** * @var int[] */ - private $testSuiteErrors = [0]; + private array $testSuiteErrors = [0]; /** * @var int[] */ - private $testSuiteWarnings = [0]; + private array $testSuiteWarnings = [0]; /** * @var int[] */ - private $testSuiteFailures = [0]; + private array $testSuiteFailures = [0]; /** * @var int[] */ - private $testSuiteSkipped = [0]; + private array $testSuiteSkipped = [0]; - /** - * @var int[]|float[] - */ - private $testSuiteTimes = [0]; + private array $testSuiteTimes = [0]; - /** - * @var int - */ - private $testSuiteLevel = 0; + private int $testSuiteLevel = 0; - /** - * @var DOMElement|null - */ - private $currentTestCase; + private ?DOMElement $currentTestCase = null; public function __construct(string $out) { @@ -190,7 +174,7 @@ final class JUnit extends Printer implements TestListener } $testSuite->setAttribute('file', $fileName); - } catch (ReflectionException $e) { + } catch (ReflectionException) { // @ignoreException } } @@ -313,7 +297,7 @@ final class JUnit extends Printer implements TestListener $testCase->setAttribute('class', $test->getPrintableTestCaseName()); $testCase->setAttribute('classname', str_replace('\\', '.', $test->getPrintableTestCaseName())); // @phpstan-ignore-next-line - $testCase->setAttribute('file', $test->__getFileName()); + $testCase->setAttribute('file', $test->__getFilename()); } $this->currentTestCase = $testCase; @@ -409,7 +393,7 @@ final class JUnit extends Printer implements TestListener if ($t instanceof ExceptionWrapper) { $fault->setAttribute('type', $t->getClassName()); } else { - $fault->setAttribute('type', get_class($t)); + $fault->setAttribute('type', $t::class); } $this->currentTestCase->appendChild($fault); diff --git a/src/Logging/TeamCity.php b/src/Logging/TeamCity.php index bfd732fb..051bfa4c 100644 --- a/src/Logging/TeamCity.php +++ b/src/Logging/TeamCity.php @@ -16,9 +16,9 @@ use PHPUnit\Framework\TestResult; use PHPUnit\Framework\TestSuite; use PHPUnit\Framework\Warning; use PHPUnit\TextUI\DefaultResultPrinter; +use PHPUnit\TextUI\XmlConfiguration\Logging\TeamCity as BaseTeamCity; use function round; use function str_replace; -use function strlen; use Throwable; final class TeamCity extends DefaultResultPrinter @@ -34,22 +34,19 @@ final class TeamCity extends DefaultResultPrinter private const TEST_STARTED = 'testStarted'; private const TEST_FINISHED = 'testFinished'; - /** @var int */ - private $flowId; + private ?int $flowId = null; - /** @var bool */ - private $isSummaryTestCountPrinted = false; + private bool $isSummaryTestCountPrinted = false; - /** @var \PHPUnit\Util\Log\TeamCity */ - private $phpunitTeamCity; + private BaseTeamCity $phpunitTeamCity; /** - * @param resource|string|null $out + * Creates a new printer instance. */ - public function __construct($out, bool $verbose, string $colors) + public function __construct(resource|string|null $out, bool $verbose, string $colors) { parent::__construct($out, $verbose, $colors); - $this->phpunitTeamCity = new \PHPUnit\Util\Log\TeamCity($out, $verbose, $colors); + $this->phpunitTeamCity = new BaseTeamCity($out, $verbose, $colors); $this->logo(); } @@ -74,9 +71,7 @@ final class TeamCity extends DefaultResultPrinter 'passed' => ['count' => $this->successfulTestCount($result), 'color' => 'fg-green'], ]; - $filteredResults = array_filter($results, function ($item): bool { - return $item['count'] > 0; - }); + $filteredResults = array_filter($results, fn ($item): bool => $item['count'] > 0); foreach ($filteredResults as $key => $info) { $this->writeWithColor($info['color'], $info['count'] . " $key", false); @@ -203,7 +198,7 @@ final class TeamCity extends DefaultResultPrinter */ private static function isPestTestSuite(TestSuite $suite): bool { - return strncmp($suite->getName(), 'P\\', strlen('P\\')) === 0; + return str_starts_with($suite->getName(), 'P\\'); } /** diff --git a/src/OppositeExpectation.php b/src/OppositeExpectation.php index 0473e2b6..7a17162c 100644 --- a/src/OppositeExpectation.php +++ b/src/OppositeExpectation.php @@ -14,17 +14,12 @@ use SebastianBergmann\Exporter\Exporter; */ final class OppositeExpectation { - /** - * @var Expectation - */ - private $original; - /** * Creates a new opposite expectation. */ - public function __construct(Expectation $original) + public function __construct(private Expectation $original) { - $this->original = $original; + // .. } /** @@ -37,7 +32,7 @@ final class OppositeExpectation foreach ($keys as $key) { try { $this->original->toHaveKey($key); - } catch (ExpectationFailedException $e) { + } catch (ExpectationFailedException) { continue; } @@ -57,7 +52,7 @@ final class OppositeExpectation try { /* @phpstan-ignore-next-line */ $this->original->{$name}(...$arguments); - } catch (ExpectationFailedException $e) { + } catch (ExpectationFailedException) { return $this->original; } @@ -73,7 +68,7 @@ final class OppositeExpectation try { /* @phpstan-ignore-next-line */ $this->original->{$name}; - } catch (ExpectationFailedException $e) { + } catch (ExpectationFailedException) { return $this->original; } @@ -90,10 +85,8 @@ final class OppositeExpectation { $exporter = new Exporter(); - $toString = function ($argument) use ($exporter): string { - return $exporter->shortenedExport($argument); - }; + $toString = fn ($argument): string => $exporter->shortenedExport($argument); - throw new ExpectationFailedException(sprintf('Expecting %s not %s %s.', $toString($this->original->value), strtolower((string) preg_replace('/(?original->value), strtolower((string) preg_replace('/(? $toString($argument), $arguments)))); } } diff --git a/src/PendingObjects/AfterEachCall.php b/src/PendingObjects/AfterEachCall.php index 0f021f82..6702dcb5 100644 --- a/src/PendingObjects/AfterEachCall.php +++ b/src/PendingObjects/AfterEachCall.php @@ -16,42 +16,24 @@ use Pest\TestSuite; */ final class AfterEachCall { - /** - * Holds the test suite. - * - * @var TestSuite - */ - private $testSuite; - - /** - * Holds the filename. - * - * @var string - */ - private $filename; - /** * Holds the before each closure. - * - * @var Closure */ - private $closure; + private Closure $closure; /** * Holds calls that should be proxied. - * - * @var HigherOrderMessageCollection */ - private $proxies; + private HigherOrderMessageCollection $proxies; /** * Creates a new instance of before each call. */ - public function __construct(TestSuite $testSuite, string $filename, Closure $closure = null) - { - $this->testSuite = $testSuite; - $this->filename = $filename; - $this->closure = $closure instanceof Closure ? $closure : NullClosure::create(); + public function __construct( + private TestSuite $testSuite, + private string $filename, Closure $closure = null + ) { + $this->closure = $closure instanceof Closure ? $closure : NullClosure::create(); $this->proxies = new HigherOrderMessageCollection(); } diff --git a/src/PendingObjects/BeforeEachCall.php b/src/PendingObjects/BeforeEachCall.php index b5df9cba..ff637d52 100644 --- a/src/PendingObjects/BeforeEachCall.php +++ b/src/PendingObjects/BeforeEachCall.php @@ -16,42 +16,25 @@ use Pest\TestSuite; */ final class BeforeEachCall { - /** - * Holds the test suite. - * - * @var TestSuite - */ - private $testSuite; - - /** - * Holds the filename. - * - * @var string - */ - private $filename; - /** * Holds the before each closure. - * - * @var Closure */ - private $closure; + private \Closure $closure; /** * Holds calls that should be proxied. - * - * @var HigherOrderMessageCollection */ - private $proxies; + private HigherOrderMessageCollection $proxies; /** * Creates a new instance of before each call. */ - public function __construct(TestSuite $testSuite, string $filename, Closure $closure = null) - { - $this->testSuite = $testSuite; - $this->filename = $filename; - $this->closure = $closure instanceof Closure ? $closure : NullClosure::create(); + public function __construct( + private TestSuite $testSuite, + private string $filename, + Closure $closure = null + ) { + $this->closure = $closure instanceof Closure ? $closure : NullClosure::create(); $this->proxies = new HigherOrderMessageCollection(); } diff --git a/src/PendingObjects/TestCall.php b/src/PendingObjects/TestCall.php index 88928876..235c1750 100644 --- a/src/PendingObjects/TestCall.php +++ b/src/PendingObjects/TestCall.php @@ -19,40 +19,30 @@ use SebastianBergmann\Exporter\Exporter; */ final class TestCall { - /** - * Holds the test suite. - * - * @readonly - * - * @var TestSuite - */ - private $testSuite; - /** * Holds the test case factory. * * @readonly - * - * @var TestCaseFactory */ - private $testCaseFactory; + private TestCaseFactory $testCaseFactory; /** * If test call is descriptionLess. * * @readonly - * - * @var bool */ - private $descriptionLess = false; + private bool $descriptionLess = false; /** * Creates a new instance of a pending test call. */ - public function __construct(TestSuite $testSuite, string $filename, string $description = null, Closure $closure = null) - { + public function __construct( + private TestSuite $testSuite, + string $filename, + string $description = null, + Closure $closure = null + ) { $this->testCaseFactory = new TestCaseFactory($filename, $description, $closure); - $this->testSuite = $testSuite; $this->descriptionLess = $description === null; } @@ -83,12 +73,12 @@ final class TestCall * * @param (callable(): bool)|bool $condition */ - public function throwsIf($condition, string $exception, string $exceptionMessage = null): TestCall + public function throwsIf(callable|bool $condition, string $exception, string $exceptionMessage = null): TestCall { $condition = is_callable($condition) ? $condition : static function () use ($condition): bool { - return (bool) $condition; // @phpstan-ignore-line + return $condition; // @phpstan-ignore-line }; if ($condition()) { @@ -149,10 +139,8 @@ final class TestCall /** * Skips the current test. - * - * @param Closure|bool|string $conditionOrMessage */ - public function skip($conditionOrMessage = true, string $message = ''): TestCall + public function skip(Closure|bool|string $conditionOrMessage = true, string $message = ''): TestCall { $condition = is_string($conditionOrMessage) ? NullClosure::create() @@ -160,9 +148,7 @@ final class TestCall $condition = is_callable($condition) ? $condition - : function () use ($condition) { /* @phpstan-ignore-line */ - return $condition; - }; + : fn () => $condition; $message = is_string($conditionOrMessage) ? $conditionOrMessage diff --git a/src/PendingObjects/UsesCall.php b/src/PendingObjects/UsesCall.php index 4b1fd77e..8a954dbf 100644 --- a/src/PendingObjects/UsesCall.php +++ b/src/PendingObjects/UsesCall.php @@ -24,46 +24,32 @@ final class UsesCall * * @var array */ - private $hooks = []; - - /** - * Holds the class and traits. - * - * @var array - */ - private $classAndTraits; - - /** - * Holds the base dirname here the uses call was performed. - * - * @var string - */ - private $filename; + private array $hooks = []; /** * Holds the targets of the uses. * * @var array */ - private $targets; + private array $targets; /** * Holds the groups of the uses. * * @var array */ - private $groups = []; + private array $groups = []; /** * Creates a new instance of a pending test uses. * * @param array $classAndTraits */ - public function __construct(string $filename, array $classAndTraits) - { - $this->classAndTraits = $classAndTraits; - $this->filename = $filename; - $this->targets = [$filename]; + public function __construct( + private string $filename, + private array $classAndTraits + ) { + $this->targets = [$filename]; } /** @@ -76,14 +62,12 @@ final class UsesCall $startChar = DIRECTORY_SEPARATOR; if ('\\' === DIRECTORY_SEPARATOR || preg_match('~\A[A-Z]:(?![^/\\\\])~i', $path) > 0) { - $path = (string) preg_replace_callback('~^(?P[a-z]+:\\\)~i', function ($match): string { - return strtolower($match['drive']); - }, $path); + $path = (string) preg_replace_callback('~^(?P[a-z]+:\\\)~i', fn ($match): string => strtolower($match['drive']), $path); $startChar = strtolower((string) preg_replace('~^([a-z]+:\\\).*$~i', '$1', __DIR__)); } - return 0 === strpos($path, $startChar) + return str_starts_with($path, $startChar) ? $path : implode(DIRECTORY_SEPARATOR, [ dirname($this->filename), diff --git a/src/Plugin.php b/src/Plugin.php index 3b9256b4..9de1f707 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -14,7 +14,7 @@ final class Plugin * * @internal */ - public static $callables = []; + public static array $callables = []; /** * Lazy loads an `uses` call on the context of plugins. diff --git a/src/Plugins/Coverage.php b/src/Plugins/Coverage.php index 6d993717..667c0571 100644 --- a/src/Plugins/Coverage.php +++ b/src/Plugins/Coverage.php @@ -29,31 +29,30 @@ final class Coverage implements AddsOutput, HandlesArguments /** * Whether should show the coverage or not. - * - * @var bool */ - public $coverage = false; + public bool $coverage = false; /** * The minimum coverage. - * - * @var float */ - public $coverageMin = 0.0; + public float $coverageMin = 0.0; /** - * @var OutputInterface + * Creates a new Plugin instance. */ - private $output; - - public function __construct(OutputInterface $output) + public function __construct(private OutputInterface $output) { - $this->output = $output; + // .. } + /** + * @param array $originals + * + * @return array + */ public function handleArguments(array $originals): array { - $arguments = array_merge([''], array_values(array_filter($originals, function ($original): bool { + $arguments = [...[''], ...array_values(array_filter($originals, function ($original): bool { foreach ([self::COVERAGE_OPTION, self::MIN_OPTION] as $option) { if ($original === sprintf('--%s', $option) || Str::startsWith($original, sprintf('--%s=', $option))) { return true; @@ -61,7 +60,7 @@ final class Coverage implements AddsOutput, HandlesArguments } return false; - }))); + }))]; $originals = array_flip($originals); foreach ($arguments as $argument) { @@ -75,9 +74,9 @@ final class Coverage implements AddsOutput, HandlesArguments $input = new ArgvInput($arguments, new InputDefinition($inputs)); if ((bool) $input->getOption(self::COVERAGE_OPTION)) { - $this->coverage = true; - $originals[] = '--coverage-php'; - $originals[] = \Pest\Support\Coverage::getPath(); + $this->coverage = true; + $originals[] = '--coverage-php'; + $originals[] = \Pest\Support\Coverage::getPath(); } if ($input->getOption(self::MIN_OPTION) !== null) { diff --git a/src/Plugins/Environment.php b/src/Plugins/Environment.php index 4bb80a0e..52ad75ae 100644 --- a/src/Plugins/Environment.php +++ b/src/Plugins/Environment.php @@ -21,17 +21,10 @@ final class Environment implements HandlesArguments */ public const LOCAL = 'local'; - /** - * @var \Pest\Plugins\Environment|null - */ - private static $instance; - /** * The current environment. - * - * @var string|null */ - private static $name; + private static ?string $name = null; /** * Allows to handle custom command line arguments. diff --git a/src/Plugins/Init.php b/src/Plugins/Init.php index 06d3cd41..abe9f966 100644 --- a/src/Plugins/Init.php +++ b/src/Plugins/Init.php @@ -28,23 +28,14 @@ final class Init implements HandlesArguments 'ExampleTest.php' => 'tests/ExampleTest.php', ]; - /** - * @var OutputInterface - */ - private $output; - - /** - * @var TestSuite - */ - private $testSuite; - /** * Creates a new Plugin instance. */ - public function __construct(TestSuite $testSuite, OutputInterface $output) - { - $this->testSuite = $testSuite; - $this->output = $output; + public function __construct( + private TestSuite $testSuite, + private OutputInterface $output + ) { + // .. } public function handleArguments(array $arguments): array diff --git a/src/Plugins/Version.php b/src/Plugins/Version.php index 000bb3a3..f86a6cd1 100644 --- a/src/Plugins/Version.php +++ b/src/Plugins/Version.php @@ -13,17 +13,13 @@ use Symfony\Component\Console\Output\OutputInterface; */ final class Version implements HandlesArguments { - /** - * @var OutputInterface - */ - private $output; - /** * Creates a new instance of the plugin. */ - public function __construct(OutputInterface $output) - { - $this->output = $output; + public function __construct( + private OutputInterface $output + ) { + // .. } public function handleArguments(array $arguments): array diff --git a/src/Repositories/AfterAllRepository.php b/src/Repositories/AfterAllRepository.php index e0666da1..d2896ed6 100644 --- a/src/Repositories/AfterAllRepository.php +++ b/src/Repositories/AfterAllRepository.php @@ -17,7 +17,7 @@ final class AfterAllRepository /** * @var array */ - private $state = []; + private array $state = []; /** * Runs the given closure for each after all. diff --git a/src/Repositories/AfterEachRepository.php b/src/Repositories/AfterEachRepository.php index b0357e86..6c8f5afd 100644 --- a/src/Repositories/AfterEachRepository.php +++ b/src/Repositories/AfterEachRepository.php @@ -18,7 +18,7 @@ final class AfterEachRepository /** * @var array */ - private $state = []; + private array $state = []; /** * Sets a after each closure. diff --git a/src/Repositories/BeforeAllRepository.php b/src/Repositories/BeforeAllRepository.php index fa5b0b80..26e18c5f 100644 --- a/src/Repositories/BeforeAllRepository.php +++ b/src/Repositories/BeforeAllRepository.php @@ -17,7 +17,7 @@ final class BeforeAllRepository /** * @var array */ - private $state = []; + private array $state = []; /** * Runs one before all closure, and unsets it from the repository. diff --git a/src/Repositories/BeforeEachRepository.php b/src/Repositories/BeforeEachRepository.php index f9bbb1ad..0e800a79 100644 --- a/src/Repositories/BeforeEachRepository.php +++ b/src/Repositories/BeforeEachRepository.php @@ -16,7 +16,7 @@ final class BeforeEachRepository /** * @var array */ - private $state = []; + private array $state = []; /** * Sets a before each closure. diff --git a/src/Repositories/TestRepository.php b/src/Repositories/TestRepository.php index 486078d0..9eafa001 100644 --- a/src/Repositories/TestRepository.php +++ b/src/Repositories/TestRepository.php @@ -30,12 +30,12 @@ final class TestRepository /** * @var array */ - private $state = []; + private array $state = []; /** * @var array>> */ - private $uses = []; + private array $uses = []; /** * Counts the number of test cases. @@ -54,9 +54,7 @@ final class TestRepository { $testsWithOnly = $this->testsUsingOnly(); - return array_values(array_map(function (TestCaseFactory $factory): string { - return $factory->filename; - }, count($testsWithOnly) > 0 ? $testsWithOnly : $this->state)); + return array_values(array_map(fn (TestCaseFactory $factory): string => $factory->filename, count($testsWithOnly) > 0 ? $testsWithOnly : $this->state)); } /** @@ -64,9 +62,7 @@ final class TestRepository */ public function build(TestSuite $testSuite, callable $each): void { - $startsWith = function (string $target, string $directory): bool { - return Str::startsWith($target, $directory . DIRECTORY_SEPARATOR); - }; + $startsWith = fn (string $target, string $directory): bool => Str::startsWith($target, $directory . DIRECTORY_SEPARATOR); foreach ($this->uses as $path => $uses) { [$classOrTraits, $groups, $hooks] = $uses; @@ -123,9 +119,7 @@ final class TestRepository return []; } - return array_filter($this->state, function ($testFactory): bool { - return $testFactory->only; - }); + return array_filter($this->state, fn ($testFactory): bool => $testFactory->only); } /** @@ -147,8 +141,8 @@ final class TestRepository foreach ($paths as $path) { if (array_key_exists($path, $this->uses)) { $this->uses[$path] = [ - array_merge($this->uses[$path][0], $classOrTraits), - array_merge($this->uses[$path][1], $groups), + [...$this->uses[$path][0], ...$classOrTraits], + [...$this->uses[$path][1], ...$groups], $this->uses[$path][2] + $hooks, // NOTE: array_merge will destroy numeric indices ]; } else { diff --git a/src/Subscribers/EnsureConfigurationDefaults.php b/src/Subscribers/EnsureConfigurationDefaults.php index 12b1948e..ce94089d 100644 --- a/src/Subscribers/EnsureConfigurationDefaults.php +++ b/src/Subscribers/EnsureConfigurationDefaults.php @@ -17,6 +17,6 @@ final class EnsureConfigurationDefaults implements ConfiguredSubscriber */ public function notify(Configured $event): void { - $configuration = $event->configuration(); + // TODO... } } diff --git a/src/Subscribers/EnsureTestsAreLoaded.php b/src/Subscribers/EnsureTestsAreLoaded.php index 16ef72c2..12396941 100644 --- a/src/Subscribers/EnsureTestsAreLoaded.php +++ b/src/Subscribers/EnsureTestsAreLoaded.php @@ -18,7 +18,7 @@ final class EnsureTestsAreLoaded implements LoadedSubscriber /** * The current test suite, if any. */ - private static ?TestSuite $testSuite; + private static ?TestSuite $testSuite = null; /** * Runs the subscriber. @@ -31,7 +31,7 @@ final class EnsureTestsAreLoaded implements LoadedSubscriber $testSuite = \Pest\TestSuite::getInstance(); $testSuite->tests->build($testSuite, function (TestCase $testCase) use (&$testSuites): void { - $testCaseClass = get_class($testCase); + $testCaseClass = $testCase::class; if (!array_key_exists($testCaseClass, $testSuites)) { $testSuites[$testCaseClass] = []; } diff --git a/src/Support/Arr.php b/src/Support/Arr.php index ef20f862..a55764d5 100644 --- a/src/Support/Arr.php +++ b/src/Support/Arr.php @@ -15,9 +15,8 @@ final class Arr { /** * @param array $array - * @param string|int $key */ - public static function has(array $array, $key): bool + public static function has(array $array, string|int $key): bool { $key = (string) $key; @@ -38,12 +37,11 @@ final class Arr /** * @param array $array - * @param string|int $key * @param null $default * * @return array|mixed|null */ - public static function get(array $array, $key, $default = null) + public static function get(array $array, string|int $key, $default = null) { $key = (string) $key; @@ -51,7 +49,7 @@ final class Arr return $array[$key]; } - if (strpos($key, '.') === false) { + if (!str_contains($key, '.')) { return $array[$key] ?? $default; } diff --git a/src/Support/Backtrace.php b/src/Support/Backtrace.php index fa02e239..09d9e438 100644 --- a/src/Support/Backtrace.php +++ b/src/Support/Backtrace.php @@ -26,7 +26,6 @@ final class Backtrace $current = null; foreach (debug_backtrace(self::BACKTRACE_OPTIONS) as $trace) { - if (Str::endsWith($trace[self::FILE], 'overrides/Runner/TestSuiteLoader.php')) { break; } diff --git a/src/Support/ChainableClosure.php b/src/Support/ChainableClosure.php index 0dc40275..5ce0f756 100644 --- a/src/Support/ChainableClosure.php +++ b/src/Support/ChainableClosure.php @@ -18,9 +18,9 @@ final class ChainableClosure { return function () use ($closure, $next): void { /* @phpstan-ignore-next-line */ - call_user_func_array(Closure::bind($closure, $this, get_class($this)), func_get_args()); + call_user_func_array(Closure::bind($closure, $this, $this::class), func_get_args()); /* @phpstan-ignore-next-line */ - call_user_func_array(Closure::bind($next, $this, get_class($this)), func_get_args()); + call_user_func_array(Closure::bind($next, $this, $this::class), func_get_args()); }; } diff --git a/src/Support/Container.php b/src/Support/Container.php index 7685472f..6be1a4e1 100644 --- a/src/Support/Container.php +++ b/src/Support/Container.php @@ -13,15 +13,12 @@ use ReflectionParameter; */ final class Container { - /** - * @var self - */ - private static $instance; + private static ?Container $instance = null; /** * @var array */ - private $instances = []; + private array $instances = []; /** * Gets a new or already existing container. diff --git a/src/Support/Coverage.php b/src/Support/Coverage.php index 42f31242..17b75862 100644 --- a/src/Support/Coverage.php +++ b/src/Support/Coverage.php @@ -162,7 +162,7 @@ final class Coverage $lastKey = count($array) - 1; - if (array_key_exists($lastKey, $array) && strpos($array[$lastKey], '..') !== false) { + if (array_key_exists($lastKey, $array) && str_contains($array[$lastKey], '..')) { [$from] = explode('..', $array[$lastKey]); $array[$lastKey] = $line > $from ? sprintf('%s..%s', $from, $line) : sprintf('%s..%s', $line, $from); diff --git a/src/Support/Extendable.php b/src/Support/Extendable.php index dcbb7a5a..094d7007 100644 --- a/src/Support/Extendable.php +++ b/src/Support/Extendable.php @@ -8,19 +8,13 @@ use Closure; final class Extendable { - /** - * The extendable class. - * - * @var string - */ - private $extendableClass; - /** * Creates a new extendable instance. */ - public function __construct(string $extendableClass) - { - $this->extendableClass = $extendableClass; + public function __construct( + private string $extendableClass + ) { + // .. } /** diff --git a/src/Support/HigherOrderCallables.php b/src/Support/HigherOrderCallables.php index b3bb633e..ea032a88 100644 --- a/src/Support/HigherOrderCallables.php +++ b/src/Support/HigherOrderCallables.php @@ -6,8 +6,6 @@ namespace Pest\Support; use Closure; use Pest\Expectation; -use Pest\PendingObjects\TestCall; -use PHPUnit\Framework\TestCase; /** * @internal @@ -15,13 +13,11 @@ use PHPUnit\Framework\TestCase; final class HigherOrderCallables { /** - * @var object + * Creates a new Higher Order Callables instances. */ - private $target; - - public function __construct(object $target) + public function __construct(private object $target) { - $this->target = $target; + // .. } /** @@ -33,7 +29,7 @@ final class HigherOrderCallables * * @return Expectation */ - public function expect($value) + public function expect(mixed $value): Expectation { return new Expectation($value instanceof Closure ? Reflection::bindCallableWithData($value) : $value); } @@ -47,17 +43,15 @@ final class HigherOrderCallables * * @return Expectation */ - public function and($value) + public function and(mixed $value) { return $this->expect($value); } /** * Tap into the test case to perform an action and return the test case. - * - * @return TestCall|TestCase|object */ - public function tap(callable $callable) + public function tap(callable $callable): object { Reflection::bindCallableWithData($callable); diff --git a/src/Support/HigherOrderMessage.php b/src/Support/HigherOrderMessage.php index 67993bc5..99f444f0 100644 --- a/src/Support/HigherOrderMessage.php +++ b/src/Support/HigherOrderMessage.php @@ -15,68 +15,31 @@ final class HigherOrderMessage { public const UNDEFINED_METHOD = 'Method %s does not exist'; - /** - * The filename where the function was originally called. - * - * @readonly - * - * @var string - */ - public $filename; - - /** - * The line where the function was originally called. - * - * @readonly - * - * @var int - */ - public $line; - - /** - * The method or property name to access. - * - * @readonly - * - * @var string - */ - public $name; - - /** - * The arguments. - * - * @var array|null - * - * @readonly - */ - public $arguments; - /** * An optional condition that will determine if the message will be executed. * - * @var callable(): bool|null + * @var (callable(): bool)|null */ - public $condition = null; + public $condition; /** * Creates a new higher order message. * * @param array|null $arguments */ - public function __construct(string $filename, int $line, string $methodName, $arguments) - { - $this->filename = $filename; - $this->line = $line; - $this->name = $methodName; - $this->arguments = $arguments; + public function __construct( + public string $filename, + public int $line, + public string $name, + public ?array $arguments + ) { + // .. } /** * Re-throws the given `$throwable` with the good line and filename. - * - * @return mixed */ - public function call(object $target) + public function call(object $target): mixed { /* @phpstan-ignore-next-line */ if (is_callable($this->condition) && call_user_func(Closure::bind($this->condition, $target)) === false) { @@ -91,7 +54,8 @@ final class HigherOrderMessage try { return is_array($this->arguments) ? Reflection::call($target, $this->name, $this->arguments) - : $target->{$this->name}; /* @phpstan-ignore-line */ + : $target->{$this->name}; + /* @phpstan-ignore-line */ } catch (Throwable $throwable) { Reflection::setPropertyValue($throwable, 'file', $this->filename); Reflection::setPropertyValue($throwable, 'line', $this->line); @@ -122,10 +86,8 @@ final class HigherOrderMessage /** * Determines whether or not there exists a higher order callable with the message name. - * - * @return bool */ - private function hasHigherOrderCallable() + private function hasHigherOrderCallable(): bool { return in_array($this->name, get_class_methods(HigherOrderCallables::class), true); } @@ -133,7 +95,7 @@ final class HigherOrderMessage private static function getUndefinedMethodMessage(object $target, string $methodName): string { if (\PHP_MAJOR_VERSION >= 8) { - return sprintf(sprintf(self::UNDEFINED_METHOD, sprintf('%s::%s()', get_class($target), $methodName))); + return sprintf(sprintf(self::UNDEFINED_METHOD, sprintf('%s::%s()', $target::class, $methodName))); } return sprintf(self::UNDEFINED_METHOD, $methodName); diff --git a/src/Support/HigherOrderMessageCollection.php b/src/Support/HigherOrderMessageCollection.php index a6634685..b0adf7b4 100644 --- a/src/Support/HigherOrderMessageCollection.php +++ b/src/Support/HigherOrderMessageCollection.php @@ -12,7 +12,7 @@ final class HigherOrderMessageCollection /** * @var array */ - private $messages = []; + private array $messages = []; /** * Adds a new higher order message to the collection. @@ -63,9 +63,7 @@ final class HigherOrderMessageCollection { return array_reduce( $this->messages, - static function (int $total, HigherOrderMessage $message) use ($name): int { - return $total + (int) ($name === $message->name); - }, + static fn (int $total, HigherOrderMessage $message): int => $total + (int) ($name === $message->name), 0, ); } diff --git a/src/Support/HigherOrderTapProxy.php b/src/Support/HigherOrderTapProxy.php index 3c4f3968..f76026ae 100644 --- a/src/Support/HigherOrderTapProxy.php +++ b/src/Support/HigherOrderTapProxy.php @@ -15,19 +15,13 @@ final class HigherOrderTapProxy { private const UNDEFINED_PROPERTY = 'Undefined property: P\\'; - /** - * The target being tapped. - * - * @var TestCase - */ - public $target; - /** * Create a new tap proxy instance. */ - public function __construct(TestCase $target) - { - $this->target = $target; + public function __construct( + public TestCase $target + ) { + // .. } /** diff --git a/src/Support/Reflection.php b/src/Support/Reflection.php index 44cd754c..479a86f6 100644 --- a/src/Support/Reflection.php +++ b/src/Support/Reflection.php @@ -193,9 +193,7 @@ final class Reflection } $arguments[$parameter->getName()] = implode('|', array_map( - static function (ReflectionNamedType $type): string { - return $type->getName(); - }, + static fn (ReflectionNamedType $type): string => $type->getName(), ($types instanceof ReflectionNamedType) ? [$types] // NOTE: normalize as list of to handle unions : $types->getTypes(), diff --git a/src/Support/Str.php b/src/Support/Str.php index 7a07a105..a3b7a3ab 100644 --- a/src/Support/Str.php +++ b/src/Support/Str.php @@ -33,7 +33,7 @@ final class Str */ public static function startsWith(string $target, string $search): bool { - return substr($target, 0, strlen($search)) === $search; + return str_starts_with($target, $search); } /** diff --git a/src/TestSuite.php b/src/TestSuite.php index dc2c5a5a..94797263 100644 --- a/src/TestSuite.php +++ b/src/TestSuite.php @@ -19,71 +19,51 @@ final class TestSuite { /** * Holds the current test case. - * - * @var TestCase|null */ - public $test; + public ?TestCase $test = null; /** * Holds the tests repository. - * - * @var TestRepository */ - public $tests; + public TestRepository $tests; /** * Holds the before each repository. - * - * @var BeforeEachRepository */ - public $beforeEach; + public BeforeEachRepository $beforeEach; /** * Holds the before all repository. - * - * @var BeforeAllRepository */ - public $beforeAll; + public BeforeAllRepository $beforeAll; /** * Holds the after each repository. - * - * @var AfterEachRepository */ - public $afterEach; + public AfterEachRepository $afterEach; /** * Holds the after all repository. - * - * @var AfterAllRepository */ - public $afterAll; + public AfterAllRepository $afterAll; /** * Holds the root path. - * - * @var string */ - public $rootPath; - - /** - * Holds the test path. - * - * @var string - */ - public $testPath; + public string $rootPath; /** * Holds an instance of the test suite. - * - * @var TestSuite */ - private static $instance; + private static ?TestSuite $instance = null; /** * Creates a new instance of the test suite. */ - public function __construct(string $rootPath, string $testPath) + public function __construct(string $rootPath, /** + * Holds the test path. + */ + public string $testPath) { $this->beforeAll = new BeforeAllRepository(); $this->beforeEach = new BeforeEachRepository(); @@ -92,7 +72,6 @@ final class TestSuite $this->afterAll = new AfterAllRepository(); $this->rootPath = (string) realpath($rootPath); - $this->testPath = $testPath; } /**