mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
feat(mutate): only
This commit is contained in:
@ -83,7 +83,7 @@ final readonly class TestSuiteFilterProcessor
|
||||
}
|
||||
|
||||
if (Only::isEnabled()) {
|
||||
$factory->addIncludeGroupFilter(['__pest_only']);
|
||||
$factory->addIncludeGroupFilter([Only::group()]);
|
||||
} elseif ($configuration->hasGroups()) {
|
||||
$factory->addIncludeGroupFilter(
|
||||
$configuration->groups(),
|
||||
|
||||
@ -7,6 +7,7 @@ use Pest\Configuration;
|
||||
use Pest\Exceptions\AfterAllWithinDescribe;
|
||||
use Pest\Exceptions\BeforeAllWithinDescribe;
|
||||
use Pest\Expectation;
|
||||
use Pest\Mutate\Contracts\MutationTestRunner;
|
||||
use Pest\PendingCalls\AfterEachCall;
|
||||
use Pest\PendingCalls\BeforeEachCall;
|
||||
use Pest\PendingCalls\DescribeCall;
|
||||
@ -14,6 +15,7 @@ use Pest\PendingCalls\TestCall;
|
||||
use Pest\PendingCalls\UsesCall;
|
||||
use Pest\Repositories\DatasetsRepository;
|
||||
use Pest\Support\Backtrace;
|
||||
use Pest\Support\Container;
|
||||
use Pest\Support\DatasetInfo;
|
||||
use Pest\Support\HigherOrderTapProxy;
|
||||
use Pest\TestSuite;
|
||||
@ -222,7 +224,15 @@ if (! function_exists('covers')) {
|
||||
{
|
||||
$filename = Backtrace::file();
|
||||
|
||||
(new BeforeEachCall(TestSuite::getInstance(), $filename))
|
||||
->covers(...$classesOrFunctions);
|
||||
$beforeEachCall = (new BeforeEachCall(TestSuite::getInstance(), $filename));
|
||||
|
||||
$beforeEachCall->covers(...$classesOrFunctions);
|
||||
|
||||
/** @var MutationTestRunner $runner */
|
||||
$runner = Container::getInstance()->get(MutationTestRunner::class);
|
||||
|
||||
if ($runner->isEnabled()) {
|
||||
$beforeEachCall->only('__pest_mutate_only');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ final class TestCall
|
||||
*/
|
||||
public function only(): self
|
||||
{
|
||||
Only::enable($this);
|
||||
Only::enable($this, ...func_get_args()); // @phpstan-ignore-line
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -523,7 +523,8 @@ final class TestCall
|
||||
$classesOrFunctions = array_reduce($classesOrFunctions, fn ($carry, $item): array => is_array($item) ? array_merge($carry, $item) : array_merge($carry, [$item]), []); // @pest-ignore-type
|
||||
|
||||
foreach ($classesOrFunctions as $classOrFunction) {
|
||||
$isClass = class_exists($classOrFunction) || trait_exists($classOrFunction) || interface_exists($classOrFunction) || enum_exists($classOrFunction);
|
||||
$isClass = class_exists($classOrFunction) || interface_exists($classOrFunction) || enum_exists($classOrFunction);
|
||||
$isTrait = trait_exists($classOrFunction);
|
||||
$isFunction = function_exists($classOrFunction);
|
||||
|
||||
if (! $isClass && ! $isFunction) {
|
||||
@ -532,6 +533,8 @@ final class TestCall
|
||||
|
||||
if ($isClass) {
|
||||
$this->coversClass($classOrFunction);
|
||||
} elseif ($isTrait) {
|
||||
$this->coversTrait($classOrFunction);
|
||||
} else {
|
||||
$this->coversFunction($classOrFunction);
|
||||
}
|
||||
@ -559,6 +562,25 @@ final class TestCall
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the covered classes.
|
||||
*/
|
||||
public function coversTrait(string ...$traits): self
|
||||
{
|
||||
foreach ($traits as $trait) {
|
||||
$this->testCaseFactoryAttributes[] = new Attribute(
|
||||
\PHPUnit\Framework\Attributes\CoversTrait::class,
|
||||
[$trait],
|
||||
);
|
||||
}
|
||||
|
||||
/** @var Configuration $configuration */
|
||||
$configuration = Container::getInstance()->get(ConfigurationRepository::class)->globalConfiguration('default'); // @phpstan-ignore-line
|
||||
$configuration->class(...$traits); // @phpstan-ignore-line
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the covered functions.
|
||||
*/
|
||||
|
||||
@ -38,18 +38,26 @@ final class Only implements Terminable
|
||||
/**
|
||||
* Creates the lock file.
|
||||
*/
|
||||
public static function enable(TestCall $testCall): void
|
||||
public static function enable(TestCall $testCall, string $group = '__pest_only'): void
|
||||
{
|
||||
if (Environment::name() === Environment::CI) {
|
||||
return;
|
||||
}
|
||||
|
||||
$testCall->group('__pest_only');
|
||||
$testCall->group($group);
|
||||
|
||||
$lockFile = self::TEMPORARY_FOLDER.DIRECTORY_SEPARATOR.'only.lock';
|
||||
|
||||
if (file_exists($lockFile) && $group === '__pest_only') {
|
||||
file_put_contents($lockFile, $group);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! file_exists($lockFile)) {
|
||||
touch($lockFile);
|
||||
|
||||
file_put_contents($lockFile, $group);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,4 +70,18 @@ final class Only implements Terminable
|
||||
|
||||
return file_exists($lockFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the group name.
|
||||
*/
|
||||
public static function group(): string
|
||||
{
|
||||
$lockFile = self::TEMPORARY_FOLDER.DIRECTORY_SEPARATOR.'only.lock';
|
||||
|
||||
if (! file_exists($lockFile)) {
|
||||
return '__pest_only';
|
||||
}
|
||||
|
||||
return file_get_contents($lockFile) ?: '__pest_only'; // @phpstan-ignore-line
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,9 +41,9 @@ it('guesses if the given argument is a class or function', function () {
|
||||
it('uses the correct PHPUnit attribute for trait', function () {
|
||||
$attributes = (new ReflectionClass($this))->getAttributes();
|
||||
|
||||
expect($attributes[8]->getName())->toBe('PHPUnit\Framework\Attributes\CoversClass');
|
||||
expect($attributes[8]->getName())->toBe('PHPUnit\Framework\Attributes\CoversTrait');
|
||||
expect($attributes[8]->getArguments()[0])->toBe('Tests\Fixtures\Covers\CoversTrait');
|
||||
})->coversClass(CoversTrait::class);
|
||||
})->coversTrait(CoversTrait::class);
|
||||
|
||||
it('uses the correct PHPUnit attribute for covers nothing', function () {
|
||||
$attributes = (new ReflectionMethod($this, $this->name()))->getAttributes();
|
||||
|
||||
@ -16,7 +16,7 @@ $run = function () {
|
||||
|
||||
test('parallel', function () use ($run) {
|
||||
expect($run('--exclude-group=integration'))
|
||||
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1081 passed (2600 assertions)')
|
||||
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1091 passed (2624 assertions)')
|
||||
->toContain('Parallel: 3 processes');
|
||||
})->skipOnWindows();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user