Skip to content

Commit

Permalink
feat: Concat does not generate mutant when both operands are the same (
Browse files Browse the repository at this point in the history
…#1602)

* feat: Concat does not generate mutant when both operands are the same

Closes #1601

* Update ConcatTest.php

* use prettyPrint instead of prettyPrintExpr

* add clone per review suggestion

* suppress psalm issue - ImpureMethodCall

- per @maks-rafalko

* Update Concat.php

* suppress issue in psalm.xml
  • Loading branch information
michalbundyra committed Oct 31, 2021
1 parent a7ece6f commit 1892158
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
8 changes: 8 additions & 0 deletions psalm.xml
Expand Up @@ -14,4 +14,12 @@
<directory name="src/PhpParser" />
</ignoreFiles>
</projectFiles>

<issueHandlers>
<ImpureMethodCall>
<errorLevel type="suppress">
<file name="src/Mutator/Operator/Concat.php"/>
</errorLevel>
</ImpureMethodCall>
</issueHandlers>
</psalm>
13 changes: 10 additions & 3 deletions src/Mutator/Operator/Concat.php
Expand Up @@ -40,6 +40,7 @@
use Infection\Mutator\Mutator;
use Infection\Mutator\MutatorCategory;
use PhpParser\Node;
use PhpParser\PrettyPrinter\Standard;

/**
* @internal
Expand Down Expand Up @@ -81,13 +82,19 @@ public static function getDefinition(): ?Definition
*/
public function mutate(Node $node): iterable
{
$printer = new Standard();

if ($node->left instanceof Node\Expr\BinaryOp\Concat) {
$left = new Node\Expr\BinaryOp\Concat($node->left->left, $node->right);
$right = $node->left->right;

yield new Node\Expr\BinaryOp\Concat($left, $right);
} else {
yield new Node\Expr\BinaryOp\Concat($node->right, $node->left);
[$left, $right] = [$node->right, $node->left];
}

$newNode = new Node\Expr\BinaryOp\Concat($left, $right);

if ($printer->prettyPrint([clone $node]) !== $printer->prettyPrint([$newNode])) {
yield $newNode;
}
}

Expand Down
32 changes: 32 additions & 0 deletions tests/phpunit/Mutator/Operator/ConcatTest.php
Expand Up @@ -154,5 +154,37 @@ public function mutationsProvider(): iterable
,
],
];

yield 'Does not flip the same variable' => [
<<<'PHP'
<?php
$a = 'foo';
$a . $a;
PHP
,
[],
];

yield 'Does not flip the same variable - multiple concatenation' => [
<<<'PHP'
<?php
$a = 'foo';
$a . $a . $a;
PHP
,
[],
];

yield 'Does not flip the same value' => [
<<<'PHP'
<?php
'foo' . 'foo';
PHP
,
[],
];
}
}

0 comments on commit 1892158

Please sign in to comment.