mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
Merge pull request #662 from pestphp/2.x_parallel_cleanup
2.x Parallel todo support
This commit is contained in:
@ -1 +0,0 @@
|
||||
["P\\Tests\\Temporary\\A::it_can_run_a_test_5#(3)","P\\Tests\\Temporary\\A::it_can_run_a_test_5#(4)"]
|
||||
File diff suppressed because one or more lines are too long
@ -7,7 +7,6 @@ use ParaTest\WrapperRunner\WrapperWorker;
|
||||
use Pest\ConfigLoader;
|
||||
use Pest\Kernel;
|
||||
use Pest\Plugins\Actions\CallsHandleArguments;
|
||||
use Pest\TestCaseMethodFilters\TodoTestCaseFilter;
|
||||
use Pest\TestSuite;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
@ -15,7 +14,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
$bootPest = (static function (): void {
|
||||
$workerArgv = new ArgvInput();
|
||||
$masterArgv = new ArgvInput(json_decode($_SERVER['PEST_PARALLEL_ARGV']));
|
||||
|
||||
$rootPath = dirname(PHPUNIT_COMPOSER_INSTALL, 2);
|
||||
$testSuite = TestSuite::getInstance($rootPath, $workerArgv->getParameterOption(
|
||||
@ -23,10 +21,6 @@ $bootPest = (static function (): void {
|
||||
(new ConfigLoader($rootPath))->getTestsDirectory()
|
||||
));
|
||||
|
||||
if ($masterArgv->hasParameterOption('--todo')) {
|
||||
$testSuite->tests->addTestCaseMethodFilter(new TodoTestCaseFilter());
|
||||
}
|
||||
|
||||
$input = new ArgvInput();
|
||||
|
||||
$output = new ConsoleOutput(OutputInterface::VERBOSITY_NORMAL, true);
|
||||
@ -45,9 +39,6 @@ $bootPest = (static function (): void {
|
||||
'phpunit-argv:',
|
||||
]);
|
||||
|
||||
require_once __DIR__.'/../overrides/Runner/TestSuiteLoader.php';
|
||||
require_once __DIR__.'/../overrides/Runner/Filter/NameFilterIterator.php';
|
||||
|
||||
$composerAutoloadFiles = [
|
||||
dirname(__DIR__, 3).DIRECTORY_SEPARATOR.'autoload.php',
|
||||
dirname(__DIR__, 2).DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'autoload.php',
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* This file is part of PHPUnit.
|
||||
*
|
||||
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace PHPUnit\TextUI\Output\Default\ProgressPrinter;
|
||||
|
||||
use PHPUnit\Event\Test\Skipped;
|
||||
use PHPUnit\Event\Test\SkippedSubscriber;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* @internal This class is not covered by the backward compatibility promise for PHPUnit
|
||||
*
|
||||
* This file is overridden to allow Pest Parallel to show todo items in the progress output.
|
||||
*/
|
||||
final class TestSkippedSubscriber extends Subscriber implements SkippedSubscriber
|
||||
{
|
||||
/**
|
||||
* Notifies the printer that a test was skipped.
|
||||
*/
|
||||
public function notify(Skipped $event): void
|
||||
{
|
||||
str_contains($event->message(), '__TODO__')
|
||||
? $this->printTodoItem()
|
||||
: $this->printer()->testSkipped();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a "T" to the standard PHPUnit output to indicate a todo item.
|
||||
*/
|
||||
private function printTodoItem(): void
|
||||
{
|
||||
$mirror = new ReflectionClass($this->printer());
|
||||
$printerMirror = $mirror->getMethod('printProgress');
|
||||
$printerMirror->invoke($this->printer(), 'T');
|
||||
}
|
||||
}
|
||||
@ -20,6 +20,7 @@ final class BootOverrides implements Bootstrapper
|
||||
private const FILES = [
|
||||
'Runner/Filter/NameFilterIterator.php',
|
||||
'Runner/TestSuiteLoader.php',
|
||||
'TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace Pest\Plugins;
|
||||
|
||||
use JsonException;
|
||||
use ParaTest\ParaTestCommand;
|
||||
use Pest\Contracts\Plugins\HandlesArguments;
|
||||
use Pest\Plugins\Actions\CallsAddsOutput;
|
||||
@ -29,24 +28,25 @@ final class Parallel implements HandlesArguments
|
||||
Parallel\Handlers\Pest::class,
|
||||
Parallel\Handlers\Laravel::class,
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const UNSUPPORTED_ARGUMENTS = ['--todo', '--retry'];
|
||||
|
||||
/**
|
||||
* If the
|
||||
* Whether the given command line arguments indicate that the test suite should be run in parallel.
|
||||
*/
|
||||
public static function isCommand(): bool
|
||||
public static function isEnabled(): bool
|
||||
{
|
||||
// get binary name
|
||||
Arr::get($_SERVER, 'argv.0');
|
||||
|
||||
$argvValue = Arr::get($_ENV, 'PARATEST');
|
||||
|
||||
assert(is_string($argvValue) || is_int($argvValue) || is_null($argvValue));
|
||||
|
||||
return ((int) $argvValue) === 1;
|
||||
$argv = new ArgvInput();
|
||||
if ($argv->hasParameterOption('--parallel')) {
|
||||
return true;
|
||||
}
|
||||
return $argv->hasParameterOption('-p');
|
||||
}
|
||||
|
||||
/**
|
||||
* If the
|
||||
* If this code is running in a worker process rather than the main process.
|
||||
*/
|
||||
public static function isWorker(): bool
|
||||
{
|
||||
@ -57,35 +57,30 @@ final class Parallel implements HandlesArguments
|
||||
return ((int) $argvValue) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handleArguments(array $arguments): array
|
||||
{
|
||||
if ($this->argumentsContainParallelFlags($arguments)) {
|
||||
if ($this->hasArgumentsThatWouldBeFasterWithoutParallel()) {
|
||||
return $this->runTestSuiteInSeries($arguments);
|
||||
}
|
||||
|
||||
if (self::isEnabled()) {
|
||||
exit($this->runTestSuiteInParallel($arguments));
|
||||
}
|
||||
|
||||
if (self::isWorker()) {
|
||||
return $this->runWorkersHandlers($arguments);
|
||||
return $this->runWorkerHandlers($arguments);
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $arguments
|
||||
*/
|
||||
private function argumentsContainParallelFlags(array $arguments): bool
|
||||
{
|
||||
if ($this->hasArgument('--parallel', $arguments)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->hasArgument('-p', $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $arguments
|
||||
* Runs the test suite in parallel. This method will exit the process upon completion.
|
||||
*
|
||||
* @throws JsonException
|
||||
* @param array<int, string> $arguments
|
||||
*/
|
||||
private function runTestSuiteInParallel(array $arguments): int
|
||||
{
|
||||
@ -95,8 +90,6 @@ final class Parallel implements HandlesArguments
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$_ENV['PEST_PARALLEL_ARGV'] = json_encode($_SERVER['argv'], JSON_THROW_ON_ERROR);
|
||||
|
||||
$handlers = array_filter(
|
||||
array_map(fn ($handler): object|string => Container::getInstance()->get($handler), self::HANDLERS),
|
||||
fn ($handler): bool => $handler instanceof HandlesArguments,
|
||||
@ -114,10 +107,12 @@ final class Parallel implements HandlesArguments
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs any handlers that have been registered to handle worker arguments, and returns the modified arguments.
|
||||
*
|
||||
* @param array<int, string> $arguments
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function runWorkersHandlers(array $arguments): array
|
||||
private function runWorkerHandlers(array $arguments): array
|
||||
{
|
||||
$handlers = array_filter(
|
||||
array_map(fn ($handler): object|string => Container::getInstance()->get($handler), self::HANDLERS),
|
||||
@ -131,6 +126,9 @@ final class Parallel implements HandlesArguments
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a message to the user asking them to install ParaTest as a dev dependency.
|
||||
*/
|
||||
private function askUserToInstallParatest(): void
|
||||
{
|
||||
/** @var OutputInterface $output */
|
||||
@ -142,6 +140,9 @@ final class Parallel implements HandlesArguments
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an instance of the Paratest command.
|
||||
*/
|
||||
private function paratestCommand(): Application
|
||||
{
|
||||
/** @var non-empty-string $rootPath */
|
||||
@ -154,4 +155,34 @@ final class Parallel implements HandlesArguments
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the command line arguments contain any arguments that are
|
||||
* not supported or are suboptimal when running in parallel.
|
||||
*/
|
||||
private function hasArgumentsThatWouldBeFasterWithoutParallel(): bool
|
||||
{
|
||||
$arguments = new ArgvInput();
|
||||
|
||||
foreach (self::UNSUPPORTED_ARGUMENTS as $unsupportedArgument) {
|
||||
if ($arguments->hasParameterOption($unsupportedArgument)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any parallel arguments.
|
||||
*
|
||||
* @param array<int, string> $arguments
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function runTestSuiteInSeries(array $arguments): array
|
||||
{
|
||||
$arguments = $this->popArgument('--parallel', $arguments);
|
||||
|
||||
return $this->popArgument('-p', $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,9 @@ final class Laravel implements HandlesArguments
|
||||
{
|
||||
use HandleArguments;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handleArguments(array $arguments): array
|
||||
{
|
||||
return self::whenUsingLaravel($arguments, function (array $arguments): array {
|
||||
@ -43,10 +46,8 @@ final class Laravel implements HandlesArguments
|
||||
{
|
||||
$isLaravelApplication = InstalledVersions::isInstalled('laravel/framework', false);
|
||||
$isLaravelPackage = class_exists(\Orchestra\Testbench\TestCase::class);
|
||||
if ($isLaravelApplication) {
|
||||
return $closure($arguments);
|
||||
}
|
||||
if ($isLaravelPackage) {
|
||||
|
||||
if ($isLaravelApplication && ! $isLaravelPackage) {
|
||||
return $closure($arguments);
|
||||
}
|
||||
|
||||
|
||||
@ -22,10 +22,11 @@ final class Parallel implements HandlesArguments
|
||||
'--parallel',
|
||||
'-p',
|
||||
'--no-output',
|
||||
'--cache-result',
|
||||
];
|
||||
|
||||
/**
|
||||
* Handles the arguments, removing the ones that are not needed, and adding the "runner" argument.
|
||||
* Handles the arguments, removing the ones that are not needed, and adds the "runner" argument.
|
||||
*/
|
||||
public function handleArguments(array $arguments): array
|
||||
{
|
||||
|
||||
@ -152,8 +152,6 @@ final class ResultPrinter
|
||||
return;
|
||||
}
|
||||
|
||||
$this->compactPrinter->newLine();
|
||||
|
||||
$state = (new StateGenerator())->fromPhpUnitTestResult($testResult);
|
||||
|
||||
$this->compactPrinter->errors($state);
|
||||
|
||||
@ -34,6 +34,7 @@ final class CompactPrinter
|
||||
private const LOOKUP_TABLE = [
|
||||
'.' => ['gray', '.'],
|
||||
'S' => ['yellow', 's'],
|
||||
'T' => ['cyan', 't'],
|
||||
'I' => ['yellow', 'i'],
|
||||
'N' => ['yellow', 'i'],
|
||||
'R' => ['yellow', '!'],
|
||||
|
||||
@ -5,7 +5,6 @@ declare(strict_types=1);
|
||||
namespace Pest\Plugins;
|
||||
|
||||
use Pest\Contracts\Plugins\HandlesArguments;
|
||||
use Pest\Exceptions\InvalidOption;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -19,18 +18,14 @@ final class Retry implements HandlesArguments
|
||||
*/
|
||||
public function handleArguments(array $arguments): array
|
||||
{
|
||||
if ($this->hasArgument('--retry', $arguments)) {
|
||||
if ($this->hasArgument('--parallel', $arguments)) {
|
||||
throw new InvalidOption('The --retry option is not supported when running in parallel.');
|
||||
}
|
||||
|
||||
$arguments = $this->popArgument('--retry', $arguments);
|
||||
|
||||
$arguments = $this->pushArgument('--order-by=defects', $arguments);
|
||||
|
||||
$arguments = $this->pushArgument('--stop-on-failure', $arguments);
|
||||
if (! $this->hasArgument('--retry', $arguments)) {
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
$arguments = $this->popArgument('--retry', $arguments);
|
||||
|
||||
$arguments = $this->pushArgument('--order-by=defects', $arguments);
|
||||
|
||||
return $this->pushArgument('--stop-on-failure', $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ final class AfterEachRepository
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a after each closure by the given filename.
|
||||
* Gets an after each closure by the given filename.
|
||||
*/
|
||||
public function get(string $filename): Closure
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user