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()) {
|
if (Only::isEnabled()) {
|
||||||
$factory->addIncludeGroupFilter(['__pest_only']);
|
$factory->addIncludeGroupFilter([Only::group()]);
|
||||||
} elseif ($configuration->hasGroups()) {
|
} elseif ($configuration->hasGroups()) {
|
||||||
$factory->addIncludeGroupFilter(
|
$factory->addIncludeGroupFilter(
|
||||||
$configuration->groups(),
|
$configuration->groups(),
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use Pest\Configuration;
|
|||||||
use Pest\Exceptions\AfterAllWithinDescribe;
|
use Pest\Exceptions\AfterAllWithinDescribe;
|
||||||
use Pest\Exceptions\BeforeAllWithinDescribe;
|
use Pest\Exceptions\BeforeAllWithinDescribe;
|
||||||
use Pest\Expectation;
|
use Pest\Expectation;
|
||||||
|
use Pest\Mutate\Contracts\MutationTestRunner;
|
||||||
use Pest\PendingCalls\AfterEachCall;
|
use Pest\PendingCalls\AfterEachCall;
|
||||||
use Pest\PendingCalls\BeforeEachCall;
|
use Pest\PendingCalls\BeforeEachCall;
|
||||||
use Pest\PendingCalls\DescribeCall;
|
use Pest\PendingCalls\DescribeCall;
|
||||||
@ -14,6 +15,7 @@ use Pest\PendingCalls\TestCall;
|
|||||||
use Pest\PendingCalls\UsesCall;
|
use Pest\PendingCalls\UsesCall;
|
||||||
use Pest\Repositories\DatasetsRepository;
|
use Pest\Repositories\DatasetsRepository;
|
||||||
use Pest\Support\Backtrace;
|
use Pest\Support\Backtrace;
|
||||||
|
use Pest\Support\Container;
|
||||||
use Pest\Support\DatasetInfo;
|
use Pest\Support\DatasetInfo;
|
||||||
use Pest\Support\HigherOrderTapProxy;
|
use Pest\Support\HigherOrderTapProxy;
|
||||||
use Pest\TestSuite;
|
use Pest\TestSuite;
|
||||||
@ -222,7 +224,15 @@ if (! function_exists('covers')) {
|
|||||||
{
|
{
|
||||||
$filename = Backtrace::file();
|
$filename = Backtrace::file();
|
||||||
|
|
||||||
(new BeforeEachCall(TestSuite::getInstance(), $filename))
|
$beforeEachCall = (new BeforeEachCall(TestSuite::getInstance(), $filename));
|
||||||
->covers(...$classesOrFunctions);
|
|
||||||
|
$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
|
public function only(): self
|
||||||
{
|
{
|
||||||
Only::enable($this);
|
Only::enable($this, ...func_get_args()); // @phpstan-ignore-line
|
||||||
|
|
||||||
return $this;
|
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
|
$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) {
|
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);
|
$isFunction = function_exists($classOrFunction);
|
||||||
|
|
||||||
if (! $isClass && ! $isFunction) {
|
if (! $isClass && ! $isFunction) {
|
||||||
@ -532,6 +533,8 @@ final class TestCall
|
|||||||
|
|
||||||
if ($isClass) {
|
if ($isClass) {
|
||||||
$this->coversClass($classOrFunction);
|
$this->coversClass($classOrFunction);
|
||||||
|
} elseif ($isTrait) {
|
||||||
|
$this->coversTrait($classOrFunction);
|
||||||
} else {
|
} else {
|
||||||
$this->coversFunction($classOrFunction);
|
$this->coversFunction($classOrFunction);
|
||||||
}
|
}
|
||||||
@ -559,6 +562,25 @@ final class TestCall
|
|||||||
return $this;
|
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.
|
* Sets the covered functions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -38,18 +38,26 @@ final class Only implements Terminable
|
|||||||
/**
|
/**
|
||||||
* Creates the lock file.
|
* 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) {
|
if (Environment::name() === Environment::CI) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$testCall->group('__pest_only');
|
$testCall->group($group);
|
||||||
|
|
||||||
$lockFile = self::TEMPORARY_FOLDER.DIRECTORY_SEPARATOR.'only.lock';
|
$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)) {
|
if (! file_exists($lockFile)) {
|
||||||
touch($lockFile);
|
touch($lockFile);
|
||||||
|
|
||||||
|
file_put_contents($lockFile, $group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,4 +70,18 @@ final class Only implements Terminable
|
|||||||
|
|
||||||
return file_exists($lockFile);
|
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 () {
|
it('uses the correct PHPUnit attribute for trait', function () {
|
||||||
$attributes = (new ReflectionClass($this))->getAttributes();
|
$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');
|
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 () {
|
it('uses the correct PHPUnit attribute for covers nothing', function () {
|
||||||
$attributes = (new ReflectionMethod($this, $this->name()))->getAttributes();
|
$attributes = (new ReflectionMethod($this, $this->name()))->getAttributes();
|
||||||
|
|||||||
@ -16,7 +16,7 @@ $run = function () {
|
|||||||
|
|
||||||
test('parallel', function () use ($run) {
|
test('parallel', function () use ($run) {
|
||||||
expect($run('--exclude-group=integration'))
|
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');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skipOnWindows();
|
})->skipOnWindows();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user