Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nunomaduro committed Sep 5, 2024
1 parent 9d5d160 commit c8633e5
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Symfony\Component\Console\Input\InputOption;

class ClearCache
class ClearCacheOption
{
final public const ARGUMENT = 'clear-cache';

Expand Down
27 changes: 27 additions & 0 deletions src/Options/EverythingOption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Pest\Mutate\Options;

use Symfony\Component\Console\Input\InputOption;

class EverythingOption
{
final public const ARGUMENT = 'everything';

public static function remove(): bool
{
return true;
}

public static function match(string $argument): bool
{
return $argument === sprintf('--%s', self::ARGUMENT);
}

public static function inputOption(): InputOption
{
return new InputOption(sprintf('--%s', self::ARGUMENT), null, InputOption::VALUE_NONE, '');
}
}
2 changes: 1 addition & 1 deletion src/Options/NoCache.php → src/Options/NoCacheOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Symfony\Component\Console\Input\InputOption;

class NoCache
class NoCacheOption
{
final public const ARGUMENT = 'no-cache';

Expand Down
39 changes: 32 additions & 7 deletions src/Plugins/Mutate.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Pest\Contracts\Plugins\AddsOutput;
use Pest\Contracts\Plugins\Bootable;
use Pest\Contracts\Plugins\HandlesArguments;
use Pest\Exceptions\InvalidOption;
use Pest\Mutate\Boostrappers\BootPhpUnitSubscribers;
use Pest\Mutate\Boostrappers\BootSubscribers;
use Pest\Mutate\Cache\FileStore;
Expand Down Expand Up @@ -37,6 +38,7 @@
use Pest\Mutate\Support\Printers\DefaultPrinter;
use Pest\Mutate\Support\StreamWrapper;
use Pest\Plugins\Concerns\HandleArguments;
use Pest\Plugins\Only;
use Pest\Plugins\Parallel;
use Pest\Support\Container;
use Pest\Support\Coverage;
Expand Down Expand Up @@ -115,16 +117,18 @@ public function handleArguments(array $arguments): array
$arguments = $this->popArgument('--mutate', $arguments);
}

if (Coverage::isAvailable() && ! isset($_SERVER['PEST_PLUGIN_INTERNAL_TEST_SUITE'])) {
throw new InvalidOption('Mutation testing requires code coverage to be enabled. You can find more about code coverage in the Pest documentation.');
}

$mutationTestRunner->enable();
$this->ensurePrinterIsRegistered();

if (Coverage::isAvailable()) {
$coverageRequired = array_filter($arguments, fn (string $argument): bool => str_starts_with($argument, '--coverage')) !== [];
if ($coverageRequired) {
$mutationTestRunner->doNotDisableCodeCoverage();
} else {
$arguments[] = '--coverage-php='.Coverage::getPath();
}
$coverageRequired = array_filter($arguments, fn (string $argument): bool => str_starts_with($argument, '--coverage')) !== [];
if ($coverageRequired) {
$mutationTestRunner->doNotDisableCodeCoverage();
} else {
$arguments[] = '--coverage-php='.Coverage::getPath();
}

$arguments = Container::getInstance()->get(ConfigurationRepository::class) // @phpstan-ignore-line
Expand All @@ -148,6 +152,27 @@ public function addOutput(int $exitCode): int
return $exitCode;
}

/** @var ConfigurationRepository $configuration */
$configuration = Container::getInstance()->get(ConfigurationRepository::class);

if (! Only::isEnabled() && ! $configuration->everything) {

Check failure on line 158 in src/Plugins/Mutate.php

View workflow job for this annotation

GitHub Actions / Static Tests (prefer-lowest)

Access to an undefined property Pest\Mutate\Repositories\ConfigurationRepository::$everything.

Check failure on line 158 in src/Plugins/Mutate.php

View workflow job for this annotation

GitHub Actions / Static Tests (prefer-stable)

Access to an undefined property Pest\Mutate\Repositories\ConfigurationRepository::$everything.
throw new InvalidOption(<<<'ERROR'
Mutation testing requires the usage of the `covers()` function. Here is an example:
```
<?php
covers(TodoController::class); // mutations will be generated only for this class
it('list todos', function () {
// your test here...
});
```
Optionally, you can use the `--everything` flag for generating mutations for "covered" classes, but this is not recommended as it will slow down the mutation testing process.
ERROR);
}

return $mutationTestRunner->run();
}

Expand Down
1 change: 1 addition & 0 deletions src/Repositories/ConfigurationRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ classes: $config['classes'] ?? [],
stopOnUncovered: $config['stop_on_uncovered'] ?? false,
mutationId: $config['mutation_id'] ?? null,
retry: $config['retry'] ?? false,
everything: $config['everything'] ?? false,
);
}

Expand Down
12 changes: 11 additions & 1 deletion src/Support/Configuration/AbstractConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ abstract class AbstractConfiguration implements ConfigurationContract

private ?string $mutationId = null;

private ?bool $everything = null;

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -175,8 +177,15 @@ public function mutationId(string $id): self
return $this;
}

public function everything(): self
{
$this->everything = true;

return $this;
}

/**
* @return array{paths?: string[], paths_to_ignore?: string[], mutators?: class-string<Mutator>[], excluded_mutators?: class-string<Mutator>[], classes?: string[], parallel?: bool, processes?: int, profile?: bool, min_score?: float, ignore_min_score_on_zero_mutations?: bool, covered_only?: bool, stop_on_untested?: bool, stop_on_uncovered?: bool, mutation_id?: string, retry?: bool}
* @return array{paths?: string[], paths_to_ignore?: string[], mutators?: class-string<Mutator>[], excluded_mutators?: class-string<Mutator>[], classes?: string[], parallel?: bool, processes?: int, profile?: bool, min_score?: float, ignore_min_score_on_zero_mutations?: bool, covered_only?: bool, stop_on_untested?: bool, stop_on_uncovered?: bool, mutation_id?: string, retry?: bool, everything?: bool}
*/
public function toArray(): array
{
Expand All @@ -195,6 +204,7 @@ public function toArray(): array
'stop_on_uncovered' => $this->stopOnUncovered,
'mutation_id' => $this->mutationId,
'retry' => $this->retry,
'everything' => $this->everything,
], fn (mixed $value): bool => ! is_null($value));
}

Expand Down
18 changes: 12 additions & 6 deletions src/Support/Configuration/CliConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
use Pest\Mutate\Cache\NullStore;
use Pest\Mutate\Options\BailOption;
use Pest\Mutate\Options\ClassOption;
use Pest\Mutate\Options\ClearCache;
use Pest\Mutate\Options\ClearCacheOption;
use Pest\Mutate\Options\EverythingOption;
use Pest\Mutate\Options\ExceptOption;
use Pest\Mutate\Options\IgnoreMinScoreOnZeroMutationsOption;
use Pest\Mutate\Options\IgnoreOption;
use Pest\Mutate\Options\MinScoreOption;
use Pest\Mutate\Options\MutateOption;
use Pest\Mutate\Options\MutationIdOption;
use Pest\Mutate\Options\MutatorsOption;
use Pest\Mutate\Options\NoCache;
use Pest\Mutate\Options\NoCacheOption;
use Pest\Mutate\Options\ParallelOption;
use Pest\Mutate\Options\PathOption;
use Pest\Mutate\Options\ProcessesOption;
Expand Down Expand Up @@ -47,8 +48,9 @@ class CliConfiguration extends AbstractConfiguration
BailOption::class,
RetryOption::class,
MutationIdOption::class,
NoCache::class,
ClearCache::class,
NoCacheOption::class,
ClearCacheOption::class,
EverythingOption::class,
];

/**
Expand Down Expand Up @@ -140,14 +142,18 @@ public function fromArguments(array $arguments): array
$this->mutationId((string) $input->getOption(MutationIdOption::ARGUMENT)); // @phpstan-ignore-line
}

if ($input->hasOption(NoCache::ARGUMENT)) {
if ($input->hasOption(NoCacheOption::ARGUMENT)) {
Container::getInstance()->add(CacheInterface::class, new NullStore);
}

if ($input->hasOption(ClearCache::ARGUMENT)) {
if ($input->hasOption(ClearCacheOption::ARGUMENT)) {
Container::getInstance()->get(CacheInterface::class)->clear(); // @phpstan-ignore-line
}

if ($input->hasOption(EverythingOption::ARGUMENT)) {
$this->everything();
}

return $arguments;
}
}
1 change: 1 addition & 0 deletions src/Support/Configuration/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ public function __construct(
public readonly bool $stopOnUncovered,
public readonly ?string $mutationId,
public readonly bool $retry,
public readonly bool $everything,
) {}
}

0 comments on commit c8633e5

Please sign in to comment.