refactor: comments

This commit is contained in:
Nuno Maduro
2021-10-24 19:37:29 +01:00
parent 2b687a7269
commit 648c6c5a27
32 changed files with 151 additions and 133 deletions

View File

@ -1,12 +1,10 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php declare(strict_types=1); <?php declare(strict_types=1);
use NunoMaduro\Collision\Provider;
use Pest\Actions\ValidatesEnvironment; use Pest\Actions\ValidatesEnvironment;
use Pest\Support\Container; use Pest\Support\Container;
use Pest\Console\Kernel; use Pest\Kernel;
use Pest\TestSuite; use Pest\TestSuite;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;

View File

@ -1,50 +0,0 @@
<?php
declare(strict_types=1);
namespace Pest\Actions;
use Pest\Contracts\Plugins\AddsOutput;
use Pest\Contracts\Plugins\HandlesArguments;
use Pest\Plugin\Loader;
/**
* @internal
*/
final class InteractsWithPlugins
{
/**
* Transform the input arguments by passing it to the relevant plugins.
*
* @param array<int, string> $argv
*
* @return array<int, string>
*/
public static function handleArguments(array $argv): array
{
$plugins = Loader::getPlugins(HandlesArguments::class);
/** @var HandlesArguments $plugin */
foreach ($plugins as $plugin) {
$argv = $plugin->handleArguments($argv);
}
return $argv;
}
/**
* Provides an opportunity for any plugins that want
* to provide additional output after test execution.
*/
public static function addOutput(int $result): int
{
$plugins = Loader::getPlugins(AddsOutput::class);
/** @var AddsOutput $plugin */
foreach ($plugins as $plugin) {
$result = $plugin->addOutput($result);
}
return $result;
}
}

View File

@ -14,13 +14,13 @@ trait Expectable
/** /**
* @template TValue * @template TValue
* *
* Creates a new expectation. * Creates a new Expectation.
* *
* @param TValue $value * @param TValue $value
* *
* @return Expectation<TValue> * @return Expectation<TValue>
*/ */
public function expect($value): Expectation public function expect(mixed $value): Expectation
{ {
return new Expectation($value); return new Expectation($value);
} }

View File

@ -13,12 +13,14 @@ use Closure;
trait Extendable trait Extendable
{ {
/** /**
* The list of extends.
*
* @var array<string, Closure> * @var array<string, Closure>
*/ */
private static array $extends = []; private static array $extends = [];
/** /**
* Register a custom extend. * Register a new extend.
*/ */
public static function extend(string $name, Closure $extend): void public static function extend(string $name, Closure $extend): void
{ {
@ -26,7 +28,7 @@ trait Extendable
} }
/** /**
* Checks if extend is registered. * Checks if given extend name is registered.
*/ */
public static function hasExtend(string $name): bool public static function hasExtend(string $name): bool
{ {
@ -37,10 +39,8 @@ trait Extendable
* Dynamically handle calls to the class. * Dynamically handle calls to the class.
* *
* @param array<int, mixed> $parameters * @param array<int, mixed> $parameters
*
* @return mixed
*/ */
public function __call(string $method, array $parameters) public function __call(string $method, array $parameters): mixed
{ {
if (!static::hasExtend($method)) { if (!static::hasExtend($method)) {
throw new BadMethodCallException("$method is not a callable method name."); throw new BadMethodCallException("$method is not a callable method name.");

View File

@ -9,21 +9,33 @@ namespace Pest\Concerns\Logging;
*/ */
trait WritesToConsole trait WritesToConsole
{ {
/**
* Writes the given success message to the console.
*/
private function writeSuccess(string $message): void private function writeSuccess(string $message): void
{ {
$this->writePestTestOutput($message, 'fg-green, bold', '✓'); $this->writePestTestOutput($message, 'fg-green, bold', '✓');
} }
/**
* Writes the given error message to the console.
*/
private function writeError(string $message): void private function writeError(string $message): void
{ {
$this->writePestTestOutput($message, 'fg-red, bold', ''); $this->writePestTestOutput($message, 'fg-red, bold', '');
} }
/**
* Writes the given warning message to the console.
*/
private function writeWarning(string $message): void private function writeWarning(string $message): void
{ {
$this->writePestTestOutput($message, 'fg-yellow, bold', '-'); $this->writePestTestOutput($message, 'fg-yellow, bold', '-');
} }
/**
* Writes the give message to the console.
*/
private function writePestTestOutput(string $message, string $color, string $symbol): void private function writePestTestOutput(string $message, string $color, string $symbol): void
{ {
$this->writeWithColor($color, "$symbol ", false); $this->writeWithColor($color, "$symbol ", false);

View File

@ -19,7 +19,7 @@ trait RetrievesValues
* *
* @return TRetrievableValue|null * @return TRetrievableValue|null
*/ */
private function retrieve(string $key, $value, $default = null) private function retrieve(string $key, mixed $value, mixed $default = null): mixed
{ {
if (is_array($value)) { if (is_array($value)) {
return $value[$key] ?? $default; return $value[$key] ?? $default;

View File

@ -11,7 +11,11 @@ use Symfony\Component\Console\Output\OutputInterface;
*/ */
final class Help final class Help
{ {
/** @var array<int, string> */ /**
* The Command messages.
*
* @var array<int, string>
*/
private const HELP_MESSAGES = [ private const HELP_MESSAGES = [
'<comment>Pest Options:</comment>', '<comment>Pest Options:</comment>',
' <info>--init</info> Initialise a standard Pest configuration', ' <info>--init</info> Initialise a standard Pest configuration',
@ -20,11 +24,17 @@ final class Help
' <info>--group=<fg=cyan><name></></info> Only runs tests from the specified group(s)', ' <info>--group=<fg=cyan><name></></info> Only runs tests from the specified group(s)',
]; ];
/**
* Creates a new Console Command instance.
*/
public function __construct(private OutputInterface $output) public function __construct(private OutputInterface $output)
{ {
// .. // ..
} }
/**
* Executes the Console Command.
*/
public function __invoke(): void public function __invoke(): void
{ {
foreach (self::HELP_MESSAGES as $message) { foreach (self::HELP_MESSAGES as $message) {

View File

@ -14,7 +14,11 @@ use Symfony\Component\Console\Question\ConfirmationQuestion;
*/ */
final class Thanks final class Thanks
{ {
/** @var array<int, string> */ /**
* The Command messages.
*
* @var array<int, string>
*/
private const FUNDING_MESSAGES = [ private const FUNDING_MESSAGES = [
'', '',
' - Star or contribute to Pest:', ' - Star or contribute to Pest:',
@ -25,13 +29,16 @@ final class Thanks
' <options=bold>https://github.com/sponsors/nunomaduro</>', ' <options=bold>https://github.com/sponsors/nunomaduro</>',
]; ];
/**
* Creates a new Console Command instance.
*/
public function __construct(private OutputInterface $output) public function __construct(private OutputInterface $output)
{ {
// .. // ..
} }
/** /**
* Asks the user to support Pest. * Executes the Console Command.
*/ */
public function __invoke(): void public function __invoke(): void
{ {

View File

@ -4,18 +4,12 @@ declare(strict_types=1);
namespace Pest\Contracts; namespace Pest\Contracts;
if (interface_exists(\NunoMaduro\Collision\Contracts\Adapters\Phpunit\HasPrintableTestCaseName::class)) { use NunoMaduro\Collision\Contracts\Adapters\Phpunit\HasPrintableTestCaseName as BaseHasPrintableTestCaseName;
/**
/**
* @internal * @internal
*/ */
interface HasPrintableTestCaseName extends \NunoMaduro\Collision\Contracts\Adapters\Phpunit\HasPrintableTestCaseName interface HasPrintableTestCaseName extends BaseHasPrintableTestCaseName
{ {
} // ..
} else {
/**
* @internal
*/
interface HasPrintableTestCaseName
{
}
} }

View File

@ -10,7 +10,7 @@ namespace Pest\Contracts\Plugins;
interface AddsOutput interface AddsOutput
{ {
/** /**
* Allows to add custom output after the test suite was executed. * Adds output after the Test Suite execution.
*/ */
public function addOutput(int $testReturnCode): int; public function addOutput(int $exitCode): int;
} }

View File

@ -10,11 +10,11 @@ namespace Pest\Contracts\Plugins;
interface HandlesArguments interface HandlesArguments
{ {
/** /**
* Allows to handle custom command line arguments. * Adds arguments before of the Test Suite execution.
* *
* @param array<int, string> $arguments * @param array<int, string> $argv
* *
* @return array<int, string> the updated list of arguments * @return array<int, string>
*/ */
public function handleArguments(array $arguments): array; public function handleArguments(array $argv): array;
} }

View File

@ -19,6 +19,9 @@ use SebastianBergmann\GlobalState\Snapshot;
*/ */
final class DispatchingEmitter implements Emitter final class DispatchingEmitter implements Emitter
{ {
/**
* Creates a new Emitter instance.
*/
public function __construct(private Emitter $baseEmitter) public function __construct(private Emitter $baseEmitter)
{ {
// .. // ..

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class AfterAllAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class AfterAllAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of after all already exist exception. * Creates a new Exception instance.
*/ */
public function __construct(string $filename) public function __construct(string $filename)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class AfterEachAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class AfterEachAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of after each already exist exception. * Creates a new Exception instance.
*/ */
public function __construct(string $filename) public function __construct(string $filename)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class AttributeNotSupportedYet extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class AttributeNotSupportedYet extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of attribute not supported yet. * Creates a new Exception instance.
*/ */
public function __construct(string $attribute, string $value) public function __construct(string $attribute, string $value)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class BeforeEachAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class BeforeEachAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of before each already exist exception. * Creates a new Exception instance.
*/ */
public function __construct(string $filename) public function __construct(string $filename)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class DatasetAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class DatasetAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of dataset already exist. * Creates a new Exception instance.
*/ */
public function __construct(string $name) public function __construct(string $name)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class DatasetDoesNotExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class DatasetDoesNotExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of dataset does not exist. * Creates a new Exception instance.
*/ */
public function __construct(string $name) public function __construct(string $name)
{ {

View File

@ -10,24 +10,22 @@ use NunoMaduro\Collision\Contracts\RenderlessTrace;
use Symfony\Component\Console\Exception\ExceptionInterface; use Symfony\Component\Console\Exception\ExceptionInterface;
/** /**
* Creates a new instance of dataset is not present for test that has arguments.
*
* @internal * @internal
*/ */
final class DatasetMissing extends BadFunctionCallException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class DatasetMissing extends BadFunctionCallException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Create new exception instance. * Creates a new Exception instance.
* *
* @param array<string, string> $args A map of argument names to their typee * @param array<string, string> $arguments
*/ */
public function __construct(string $file, string $name, array $args) public function __construct(string $file, string $name, array $arguments)
{ {
parent::__construct(sprintf( parent::__construct(sprintf(
"A test with the description '%s' has %d argument(s) ([%s]) and no dataset(s) provided in %s", "A test with the description '%s' has %d argument(s) ([%s]) and no dataset(s) provided in %s",
$name, $name,
count($args), count($arguments),
implode(', ', array_map(static fn (string $arg, string $type): string => 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($arguments), $arguments)),
$file, $file,
)); ));
} }

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class FileOrFolderNotFound extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class FileOrFolderNotFound extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of file not found. * Creates a new Exception instance.
*/ */
public function __construct(string $filename) public function __construct(string $filename)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class InvalidConsoleArgument extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class InvalidConsoleArgument extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of should not happen. * Creates a new Exception instance.
*/ */
public function __construct(string $message) public function __construct(string $message)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class InvalidPestCommand extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class InvalidPestCommand extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of invalid pest command exception. * Creates a new Exception instance.
*/ */
public function __construct() public function __construct()
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class MissingDependency extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class MissingDependency extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of missing dependency. * Creates a new Exception instance.
*/ */
public function __construct(string $feature, string $dependency) public function __construct(string $feature, string $dependency)
{ {

View File

@ -13,7 +13,7 @@ use RuntimeException;
final class ShouldNotHappen extends RuntimeException final class ShouldNotHappen extends RuntimeException
{ {
/** /**
* Creates a new instance of should not happen. * Creates a new Exception instance.
*/ */
public function __construct(Exception $exception) public function __construct(Exception $exception)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class TestAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class TestAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of test already exist. * Creates a new Exception instance.
*/ */
public function __construct(string $fileName, string $description) public function __construct(string $fileName, string $description)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class TestCaseAlreadyInUse extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class TestCaseAlreadyInUse extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of test case already in use. * Creates a new Exception instance.
*/ */
public function __construct(string $inUse, string $newOne, string $folder) public function __construct(string $inUse, string $newOne, string $folder)
{ {

View File

@ -15,7 +15,7 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
final class TestCaseClassOrTraitNotFound extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace final class TestCaseClassOrTraitNotFound extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{ {
/** /**
* Creates a new instance of after each already exist exception. * Creates a new Exception instance.
*/ */
public function __construct(string $testCaseClass) public function __construct(string $testCaseClass)
{ {

View File

@ -24,15 +24,11 @@ final class TestCaseFactory
{ {
/** /**
* Marks this test case as only. * Marks this test case as only.
*
* @readonly
*/ */
public bool $only = false; public bool $only = false;
/** /**
* Holds the test closure. * Holds the test closure.
*
* @readonly
*/ */
public Closure $test; public Closure $test;
@ -53,7 +49,7 @@ final class TestCaseFactory
/** /**
* An array of FQN of the class traits. * An array of FQN of the class traits.
* *
* @var array <int, string> * @var array <int, class-string>
*/ */
public array $traits = [ public array $traits = [
Concerns\Testable::class, Concerns\Testable::class,
@ -61,12 +57,12 @@ final class TestCaseFactory
]; ];
/** /**
* Holds the higher order messages for the factory that are proxyble. * Holds the higher order messages for the factory that are proxyable.
*/ */
public HigherOrderMessageCollection $factoryProxies; public HigherOrderMessageCollection $factoryProxies;
/** /**
* Holds the higher order messages that are proxyble. * Holds the higher order messages that are proxyable.
*/ */
public HigherOrderMessageCollection $proxies; public HigherOrderMessageCollection $proxies;
@ -80,14 +76,10 @@ final class TestCaseFactory
*/ */
public function __construct( public function __construct(
public string $filename, public string $filename,
public ?string $description = null, public ?string $description,
Closure $closure = null) Closure $closure = null)
{ {
$this->test = $closure ?? function (): void { $this->test = $closure ?? fn () => Assert::getCount() > 0 ?: self::markTestIncomplete();
if (Assert::getCount() === 0) {
self::markTestIncomplete(); // @phpstan-ignore-line
}
};
$this->factoryProxies = new HigherOrderMessageCollection(); $this->factoryProxies = new HigherOrderMessageCollection();
$this->proxies = new HigherOrderMessageCollection(); $this->proxies = new HigherOrderMessageCollection();

View File

@ -2,10 +2,8 @@
declare(strict_types=1); declare(strict_types=1);
namespace Pest\Console; namespace Pest;
use Pest\Actions\InteractsWithPlugins;
use Pest\Bootstrappers;
use PHPUnit\TextUI\Application; use PHPUnit\TextUI\Application;
/** /**
@ -53,13 +51,13 @@ final class Kernel
*/ */
public function handle(array $argv): int public function handle(array $argv): int
{ {
$argv = InteractsWithPlugins::handleArguments($argv); $argv = (new Plugins\Actions\HandleArguments())->__invoke($argv);
$result = $this->application->run( $result = $this->application->run(
$argv, false, $argv, false,
); );
return InteractsWithPlugins::addOutput($result); return (new Plugins\Actions\AddsOutput())->__invoke($result);
} }
/** /**

View File

@ -0,0 +1,30 @@
<?php
namespace Pest\Plugins\Actions;
use Pest\Contracts\Plugins;
use Pest\Plugin\Loader;
/**
* @internal
*/
final class AddsOutput
{
/**
* Executes the Plugin action.
*
* Provides an opportunity for any plugins that want
* to provide additional output after test execution.
*/
public function __invoke(int $exitCode): int
{
$plugins = Loader::getPlugins(Plugins\AddsOutput::class);
/** @var Plugins\AddsOutpu $plugin */
foreach ($plugins as $plugin) {
$exitCode = $plugin->addOutput($exitCode);
}
return $exitCode;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Pest\Plugins\Actions;
use Pest\Contracts\Plugins;
use Pest\Plugin\Loader;
/**
* @internal
*/
final class HandleArguments
{
/**
* Executes the Plugin action.
*
* Transform the input arguments by passing it to the relevant plugins.
*
* @param array<int, string> $argv
*
* @return array<int, string>
*/
public function __invoke(array $argv): array
{
$plugins = Loader::getPlugins(Plugins\HandlesArguments::class);
/** @var Plugins\HandlesArguments $plugin */
foreach ($plugins as $plugin) {
$argv = $plugin->handleArguments($argv);
}
return $argv;
}
}

View File

@ -5,16 +5,12 @@ declare(strict_types=1);
namespace Pest\Support; namespace Pest\Support;
/** /**
* Credits: most of this class methods and implementations
* belongs to the Arr helper of laravel/framework project
* (https://github.com/laravel/framework).
*
* @internal * @internal
*/ */
final class Arr final class Arr
{ {
/** /**
* @param array<mixed> $array * Checks if the given array has the given key.
*/ */
public static function has(array $array, string|int $key): bool public static function has(array $array, string|int $key): bool
{ {
@ -36,12 +32,9 @@ final class Arr
} }
/** /**
* @param array<mixed> $array * Gets the given key value.
* @param null $default
*
* @return array|mixed|null
*/ */
public static function get(array $array, string|int $key, $default = null) public static function get(array $array, string|int $key, mixed $default = null): mixed
{ {
$key = (string) $key; $key = (string) $key;