Skip to content

Commit

Permalink
test: Force mutators to include remedies (#1954)
Browse files Browse the repository at this point in the history
This PR is a rebased version of #1907.

It currently skips all but one mutator to set a baseline. Existing mutators should no longer be skipped in the future and this check ensures that new mutators will require a remedy to be documented.

There is more to do with remedies to, for example some ideas of #1907 (comment), but I think it is vastly out of scope of this PR and should be considered at a later time.

Closes #1907.

---------

Co-authored-by: Tom de Wit <tdewit@gainsight.com>
  • Loading branch information
theofidry and gs-tdewit committed Apr 12, 2024
1 parent 684085b commit 7bd2ce3
Show file tree
Hide file tree
Showing 2 changed files with 213 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/Mutator/Unwrap/UnwrapArrayMap.php
Expand Up @@ -64,7 +64,13 @@ public static function getDefinition(): ?Definition
TXT
,
MutatorCategory::SEMANTIC_REDUCTION,
null,
<<<'TXT'
This mutation escaping suggests that the `$callback` transformation passed to
`array_map()` does no effect to the passed elements.
Either this transformation is needed in which case additional tests capturing
this need are required, or it is not and should be removed.
TXT,
<<<'DIFF'
- $x = array_map($callback, ['foo', 'bar', 'baz']);
+ $x = ['foo', 'bar', 'baz'];
Expand Down
206 changes: 206 additions & 0 deletions tests/phpunit/Mutator/DefinitionTest.php
Expand Up @@ -35,15 +35,185 @@

namespace Infection\Tests\Mutator;

use function array_diff_key;
use function array_fill_keys;
use function array_flip;
use Infection\Mutator\Definition;
use Infection\Mutator\Mutator;
use Infection\Mutator\MutatorCategory;
use Infection\Mutator\ProfileList;
use Infection\Tests\SingletonContainer;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use function sprintf;

#[CoversClass(Definition::class)]
final class DefinitionTest extends TestCase
{
// TODO: address those
private const MUTATORS_WITHOUT_REMEDIES = [
'Assignment',
'AssignmentEqual',
'BitwiseAnd',
'BitwiseNot',
'BitwiseOr',
'BitwiseXor',
'Decrement',
'DivEqual',
'Division',
'Exponentiation',
'Increment',
'Minus',
'MinusEqual',
'ModEqual',
'Modulus',
'MulEqual',
'Multiplication',
'Plus',
'PlusEqual',
'PowEqual',
'RoundingFamily',
'ShiftLeft',
'ShiftRight',
'ArrayItem',
'EqualIdentical',
'FalseValue',
'IdenticalEqual',
'InstanceOf_',
'LogicalAnd',
'LogicalAndAllSubExprNegation',
'LogicalAndNegation',
'LogicalAndSingleSubExprNegation',
'LogicalLowerAnd',
'LogicalLowerOr',
'LogicalNot',
'LogicalOr',
'LogicalOrAllSubExprNegation',
'LogicalOrNegation',
'LogicalOrSingleSubExprNegation',
'NotEqualNotIdentical',
'NotIdenticalNotEqual',
'TrueValue',
'Yield_',
'GreaterThan',
'GreaterThanOrEqualTo',
'LessThan',
'LessThanOrEqualTo',
'Equal',
'GreaterThanNegotiation',
'GreaterThanOrEqualToNegotiation',
'Identical',
'LessThanNegotiation',
'LessThanOrEqualToNegotiation',
'NotEqual',
'NotIdentical',
'ProtectedVisibility',
'PublicVisibility',
'DecrementInteger',
'IncrementInteger',
'OneZeroFloat',
'AssignCoalesce',
'Break_',
'Coalesce',
'Concat',
'Continue_',
'ElseIfNegation',
'Finally_',
'IfNegation',
'NullSafeMethodCall',
'NullSafePropertyCall',
'SpreadAssignment',
'SpreadOneItem',
'SpreadRemoval',
'Ternary',
'Throw_',
'Catch_',
'PregMatchMatches',
'PregMatchRemoveCaret',
'PregMatchRemoveDollar',
'PregMatchRemoveFlags',
'PregQuote',
'ArrayItemRemoval',
'CatchBlockRemoval',
'CloneRemoval',
'ConcatOperandRemoval',
'FunctionCallRemoval',
'MatchArmRemoval',
'MethodCallRemoval',
'SharedCaseRemoval',
'ArrayOneItem',
'FloatNegation',
'FunctionCall',
'IntegerNegation',
'NewObject',
'This',
'YieldValue',
'Spaceship',
'DoWhile',
'Foreach_',
'For_',
'While_',
'CastArray',
'CastBool',
'CastFloat',
'CastInt',
'CastObject',
'CastString',
'UnwrapArrayChangeKeyCase',
'UnwrapArrayChunk',
'UnwrapArrayColumn',
'UnwrapArrayCombine',
'UnwrapArrayDiff',
'UnwrapArrayDiffAssoc',
'UnwrapArrayDiffKey',
'UnwrapArrayDiffUassoc',
'UnwrapArrayDiffUkey',
'UnwrapArrayFilter',
'UnwrapArrayFlip',
'UnwrapArrayIntersect',
'UnwrapArrayIntersectAssoc',
'UnwrapArrayIntersectKey',
'UnwrapArrayIntersectUassoc',
'UnwrapArrayIntersectUkey',
'UnwrapArrayKeys',
'UnwrapArrayMerge',
'UnwrapArrayMergeRecursive',
'UnwrapArrayPad',
'UnwrapArrayReduce',
'UnwrapArrayReplace',
'UnwrapArrayReplaceRecursive',
'UnwrapArrayReverse',
'UnwrapArraySlice',
'UnwrapArraySplice',
'UnwrapArrayUdiff',
'UnwrapArrayUdiffAssoc',
'UnwrapArrayUdiffUassoc',
'UnwrapArrayUintersect',
'UnwrapArrayUintersectAssoc',
'UnwrapArrayUintersectUassoc',
'UnwrapArrayUnique',
'UnwrapArrayValues',
'UnwrapLcFirst',
'UnwrapLtrim',
'UnwrapRtrim',
'UnwrapStrIreplace',
'UnwrapStrRepeat',
'UnwrapStrReplace',
'UnwrapStrRev',
'UnwrapStrShuffle',
'UnwrapStrToLower',
'UnwrapStrToUpper',
'UnwrapSubstr',
'UnwrapTrim',
'UnwrapUcFirst',
'UnwrapUcWords',
'UnwrapFinally',
'BCMath',
'MBString',
'SyntaxError',
];

#[DataProvider('valuesProvider')]
public function test_it_can_be_instantiated(
string $description,
Expand Down Expand Up @@ -75,4 +245,40 @@ public static function valuesProvider(): iterable
'The diff',
];
}

#[DataProvider('mutatorsProvider')]
public function test_it_must_define_remedies(Mutator $mutator): void
{
$this->assertNotNull(
$mutator::getDefinition()->getRemedies(),
sprintf(
'Definition of [%s] must provide remedies.',
$mutator->getName(),
),
);
}

public static function mutatorsProvider(): iterable
{
$mutatorFactory = SingletonContainer::getContainer()->getMutatorFactory();

$mutators = $mutatorFactory->create(
array_fill_keys(
ProfileList::ALL_MUTATORS,
[],
),
false,
);

$checkedMutators = array_diff_key(
$mutators,
array_flip(self::MUTATORS_WITHOUT_REMEDIES),
);

foreach ($checkedMutators as $name => $mutator) {
self::assertInstanceOf(Mutator::class, $mutator);

yield $name => [$mutator];
}
}
}

0 comments on commit 7bd2ce3

Please sign in to comment.