fix: --dirty when no tests found

This commit is contained in:
Nuno Maduro
2023-01-11 21:32:15 +00:00
parent 217fae0967
commit d305f4dca0
4 changed files with 60 additions and 8 deletions

View File

@ -84,7 +84,7 @@ use Symfony\Component\Console\Output\OutputInterface;
$kernel = Kernel::boot(); $kernel = Kernel::boot();
$result = $kernel->handle($args); $result = $kernel->handle($output, $args);
$kernel->shutdown(); $kernel->shutdown();

View File

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Pest\Exceptions;
use InvalidArgumentException;
use NunoMaduro\Collision\Contracts\RenderlessEditor;
use NunoMaduro\Collision\Contracts\RenderlessTrace;
use Symfony\Component\Console\Exception\ExceptionInterface;
/**
* @internal
*/
final class NoTestsFound extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
{
/**
* Creates a new Exception instance.
*/
public function __construct()
{
parent::__construct('No tests found.');
// ...
}
}

View File

@ -5,12 +5,14 @@ declare(strict_types=1);
namespace Pest; namespace Pest;
use Pest\Contracts\Bootstrapper; use Pest\Contracts\Bootstrapper;
use Pest\Exceptions\NoTestsFound;
use Pest\Plugins\Actions\CallsAddsOutput; use Pest\Plugins\Actions\CallsAddsOutput;
use Pest\Plugins\Actions\CallsBoot; use Pest\Plugins\Actions\CallsBoot;
use Pest\Plugins\Actions\CallsShutdown; use Pest\Plugins\Actions\CallsShutdown;
use Pest\Support\Container; use Pest\Support\Container;
use PHPUnit\TextUI\Application; use PHPUnit\TextUI\Application;
use PHPUnit\TextUI\Exception; use PHPUnit\TextUI\Exception;
use Symfony\Component\Console\Output\OutputInterface;
/** /**
* @internal * @internal
@ -69,11 +71,19 @@ final class Kernel
* *
* @throws Exception * @throws Exception
*/ */
public function handle(array $argv): int public function handle(OutputInterface $output, array $argv): int
{ {
$argv = (new Plugins\Actions\CallsHandleArguments())->__invoke($argv); $argv = (new Plugins\Actions\CallsHandleArguments())->__invoke($argv);
$this->application->run($argv, false); try {
$this->application->run($argv, false);
} catch (NoTestsFound) { // @phpstan-ignore-line
$output->writeln([
'',
' <fg=white;options=bold;bg=blue> INFO </> No tests found.',
'',
]);
}
return (new CallsAddsOutput())->__invoke( return (new CallsAddsOutput())->__invoke(
Result::exitCode(), Result::exitCode(),

View File

@ -6,22 +6,30 @@ namespace Pest\TestCaseFilters;
use Pest\Contracts\TestCaseFilter; use Pest\Contracts\TestCaseFilter;
use Pest\Exceptions\MissingDependency; use Pest\Exceptions\MissingDependency;
use Pest\Exceptions\NoTestsFound;
use Pest\TestSuite;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
final class GitDirtyTestCaseFilter implements TestCaseFilter final class GitDirtyTestCaseFilter implements TestCaseFilter
{ {
/** /**
* @var array<string> * @var string[]|null
*/ */
private array $changedFiles = []; private array|null $changedFiles = null;
public function __construct(private readonly string $projectRoot) public function __construct(private readonly string $projectRoot)
{ {
$this->loadDiff(); // ...
} }
public function accept(string $testCaseFilename): bool public function accept(string $testCaseFilename): bool
{ {
if ($this->changedFiles === null) {
$this->loadChangedFiles();
}
assert(is_array($this->changedFiles));
$relativePath = str_replace($this->projectRoot, '', $testCaseFilename); $relativePath = str_replace($this->projectRoot, '', $testCaseFilename);
if (str_starts_with($relativePath, '/')) { if (str_starts_with($relativePath, '/')) {
@ -31,7 +39,7 @@ final class GitDirtyTestCaseFilter implements TestCaseFilter
return in_array($relativePath, $this->changedFiles, true); return in_array($relativePath, $this->changedFiles, true);
} }
private function loadDiff(): void private function loadChangedFiles(): void
{ {
$process = new Process(['git', 'status', '--short', '--', '*.php']); $process = new Process(['git', 'status', '--short', '--', '*.php']);
$process->run(); $process->run();
@ -53,6 +61,14 @@ final class GitDirtyTestCaseFilter implements TestCaseFilter
$dirtyFiles = array_map(fn ($file, $status): string => in_array($status, ['R', 'RM'], true) ? explode(' -> ', $file)[1] : $file, array_keys($dirtyFiles), $dirtyFiles); $dirtyFiles = array_map(fn ($file, $status): string => in_array($status, ['R', 'RM'], true) ? explode(' -> ', $file)[1] : $file, array_keys($dirtyFiles), $dirtyFiles);
$this->changedFiles = $dirtyFiles = array_values($dirtyFiles); $dirtyFiles = array_filter($dirtyFiles, fn ($file): bool => str_starts_with('.'.DIRECTORY_SEPARATOR.$file, TestSuite::getInstance()->testPath));
$dirtyFiles = array_values($dirtyFiles);
if ($dirtyFiles === []) {
throw new NoTestsFound();
}
$this->changedFiles = $dirtyFiles;
} }
} }