From bcd1503cade938853a55c1283b02b6b820ea0b69 Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 21 Mar 2023 16:54:37 +0000 Subject: [PATCH] feat: "only" method --- composer.json | 1 + overrides/TextUI/TestSuiteFilterProcessor.php | 128 ++++++++++++++++++ src/Bootstrappers/BootOverrides.php | 1 + src/PendingCalls/TestCall.php | 11 ++ src/Plugins/Only.php | 61 +++++++++ 5 files changed, 202 insertions(+) create mode 100644 overrides/TextUI/TestSuiteFilterProcessor.php create mode 100644 src/Plugins/Only.php diff --git a/composer.json b/composer.json index 33ef9749..3685d4df 100644 --- a/composer.json +++ b/composer.json @@ -92,6 +92,7 @@ "Pest\\Plugins\\Environment", "Pest\\Plugins\\Help", "Pest\\Plugins\\Memory", + "Pest\\Plugins\\Only", "Pest\\Plugins\\Printer", "Pest\\Plugins\\ProcessIsolation", "Pest\\Plugins\\Profile", diff --git a/overrides/TextUI/TestSuiteFilterProcessor.php b/overrides/TextUI/TestSuiteFilterProcessor.php new file mode 100644 index 00000000..31ce5fe6 --- /dev/null +++ b/overrides/TextUI/TestSuiteFilterProcessor.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PHPUnit\TextUI; + +use function array_map; +use Pest\Plugins\Only; +use PHPUnit\Event; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Runner\Filter\Factory; +use PHPUnit\TextUI\Configuration\Configuration; +use PHPUnit\TextUI\Configuration\FilterNotConfiguredException; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestSuiteFilterProcessor +{ + private Factory $filterFactory; + + public function __construct(Factory $factory = new Factory) + { + $this->filterFactory = $factory; + } + + /** + * @throws Event\RuntimeException + * @throws FilterNotConfiguredException + */ + public function process(Configuration $configuration, TestSuite $suite): void + { + if (! $configuration->hasFilter() && + ! $configuration->hasGroups() && + ! $configuration->hasExcludeGroups() && + ! $configuration->hasTestsCovering() && + ! $configuration->hasTestsUsing() && + ! Only::isEnabled() + ) { + return; + } + + if ($configuration->hasExcludeGroups()) { + $this->filterFactory->addExcludeGroupFilter( + $configuration->excludeGroups() + ); + } + + if (Only::isEnabled()) { + $this->filterFactory->addIncludeGroupFilter(['__pest_only']); + } elseif ($configuration->hasGroups()) { + $this->filterFactory->addIncludeGroupFilter( + $configuration->groups() + ); + } + + if ($configuration->hasTestsCovering()) { + $this->filterFactory->addIncludeGroupFilter( + array_map( + static fn (string $name): string => '__phpunit_covers_'.$name, + $configuration->testsCovering() + ) + ); + } + + if ($configuration->hasTestsUsing()) { + $this->filterFactory->addIncludeGroupFilter( + array_map( + static fn (string $name): string => '__phpunit_uses_'.$name, + $configuration->testsUsing() + ) + ); + } + + if ($configuration->hasFilter()) { + $this->filterFactory->addNameFilter( + $configuration->filter() + ); + } + + $suite->injectFilter($this->filterFactory); + + Event\Facade::emitter()->testSuiteFiltered( + Event\TestSuite\TestSuiteBuilder::from($suite) + ); + } +} diff --git a/src/Bootstrappers/BootOverrides.php b/src/Bootstrappers/BootOverrides.php index d25f935d..e1489d7c 100644 --- a/src/Bootstrappers/BootOverrides.php +++ b/src/Bootstrappers/BootOverrides.php @@ -23,6 +23,7 @@ final class BootOverrides implements Bootstrapper 'Runner/TestSuiteLoader.php', 'TextUI/Command/WarmCodeCoverageCacheCommand.php', 'TextUI/Output/Default/ProgressPrinter/TestSkippedSubscriber.php', + 'TextUI/TestSuiteFilterProcessor.php', ]; /** diff --git a/src/PendingCalls/TestCall.php b/src/PendingCalls/TestCall.php index c793ef17..8b237ec7 100644 --- a/src/PendingCalls/TestCall.php +++ b/src/PendingCalls/TestCall.php @@ -10,6 +10,7 @@ use Pest\Factories\Covers\CoversClass; use Pest\Factories\Covers\CoversFunction; use Pest\Factories\Covers\CoversNothing; use Pest\Factories\TestCaseMethodFactory; +use Pest\Plugins\Only; use Pest\Support\Backtrace; use Pest\Support\Exporter; use Pest\Support\HigherOrderCallables; @@ -134,6 +135,16 @@ final class TestCall return $this; } + /** + * Filters the test suite by "only" tests. + */ + public function only(): self + { + Only::enable($this); + + return $this; + } + /** * Skips the current test. */ diff --git a/src/Plugins/Only.php b/src/Plugins/Only.php new file mode 100644 index 00000000..2ede1724 --- /dev/null +++ b/src/Plugins/Only.php @@ -0,0 +1,61 @@ +group('__pest_only'); + + $lockFile = self::TEMPORARY_FOLDER.DIRECTORY_SEPARATOR.'only.lock'; + + if (! file_exists($lockFile)) { + touch($lockFile); + } + } + + /** + * Checks if "only" mode is enabled. + */ + public static function isEnabled(): bool + { + $lockFile = self::TEMPORARY_FOLDER.DIRECTORY_SEPARATOR.'only.lock'; + + return file_exists($lockFile); + } +}