Skip to content

Commit

Permalink
Don't mutate $limit argument from 0 to -1 and from -1 to 0 in `preg_s…
Browse files Browse the repository at this point in the history
…plit` function (#1347)

* Don't mutant $limit 0, -1 in preg_split

* Amend TimeoutSkipped e2e test

* Amend ExecPath e2e test
  • Loading branch information
sidz committed Oct 21, 2020
1 parent 42e6313 commit 1d82648
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 33 deletions.
30 changes: 30 additions & 0 deletions src/Mutator/Number/AbstractNumberMutator.php
Expand Up @@ -51,6 +51,13 @@ protected function isPartOfSizeComparison(Node $node): bool
return $this->isSizeComparison($parent);
}

protected function isPartOfComparison(Node $node): bool
{
$parent = ParentConnector::getParent($node);

return $this->isComparison($parent);
}

private function isSizeComparison(?Node $node): bool
{
if ($node === null) {
Expand All @@ -61,10 +68,33 @@ private function isSizeComparison(?Node $node): bool
return $this->isSizeComparison(ParentConnector::findParent($node));
}

return $this->isSizeNode($node);
}

private function isSizeNode(Node $node): bool
{
return $node instanceof Node\Expr\BinaryOp\Greater
|| $node instanceof Node\Expr\BinaryOp\GreaterOrEqual
|| $node instanceof Node\Expr\BinaryOp\Smaller
|| $node instanceof Node\Expr\BinaryOp\SmallerOrEqual
;
}

private function isComparison(?Node $node): bool
{
if ($node === null) {
return false;
}

if ($node instanceof Node\Expr\UnaryMinus) {
return $this->isComparison(ParentConnector::findParent($node));
}

return $node instanceof Node\Expr\BinaryOp\Identical
|| $node instanceof Node\Expr\BinaryOp\NotIdentical
|| $node instanceof Node\Expr\BinaryOp\Equal
|| $node instanceof Node\Expr\BinaryOp\NotEqual
|| $this->isSizeNode($node)
;
}
}
68 changes: 45 additions & 23 deletions src/Mutator/Number/DecrementInteger.php
Expand Up @@ -87,7 +87,14 @@ public function mutate(Node $node): iterable

public function canMutate(Node $node): bool
{
if (!$node instanceof Node\Scalar\LNumber || $node->value === 1) {
if (!$node instanceof Node\Scalar\LNumber) {
return false;
}

if (
$node->value === 1
&& ($this->isPartOfComparison($node) || ParentConnector::getParent($node) instanceof Node\Expr\Assign)
) {
return false;
}

Expand All @@ -99,6 +106,10 @@ public function canMutate(Node $node): bool
return false;
}

if ($this->isPregSplitLimitZeroOrMinusOneArgument($node)) {
return false;
}

return $this->isAllowedComparison($node);
}

Expand All @@ -108,11 +119,12 @@ private function isAllowedComparison(Node\Scalar\LNumber $node): bool
return true;
}

$parentNode = ParentConnector::getParent($node);

if (!$this->isComparison($parentNode)) {
if (!$this->isPartOfComparison($node)) {
return true;
}

$parentNode = ParentConnector::getParent($node);

/** @var Node\Expr\BinaryOp $parentNode */
if ($parentNode->left instanceof Node\Expr\FuncCall && $parentNode->left->name instanceof Node\Name
&& in_array(
Expand All @@ -137,26 +149,8 @@ private function isAllowedComparison(Node\Scalar\LNumber $node): bool
return true;
}

private function isComparison(Node $parentNode): bool
private function isArrayZeroIndexAccess(Node\Scalar\LNumber $node): bool
{
return $parentNode instanceof Node\Expr\BinaryOp\Identical
|| $parentNode instanceof Node\Expr\BinaryOp\NotIdentical
|| $parentNode instanceof Node\Expr\BinaryOp\Equal
|| $parentNode instanceof Node\Expr\BinaryOp\NotEqual
|| $parentNode instanceof Node\Expr\BinaryOp\Greater
|| $parentNode instanceof Node\Expr\BinaryOp\GreaterOrEqual
|| $parentNode instanceof Node\Expr\BinaryOp\Smaller
|| $parentNode instanceof Node\Expr\BinaryOp\SmallerOrEqual
;
}

private function isArrayZeroIndexAccess(Node $node): bool
{
if (!$node instanceof Node\Scalar\LNumber) {
return false;
}

/** @var Node\Scalar\LNumber $node */
if ($node->value !== 0) {
return false;
}
Expand All @@ -167,4 +161,32 @@ private function isArrayZeroIndexAccess(Node $node): bool

return false;
}

private function isPregSplitLimitZeroOrMinusOneArgument(Node\Scalar\LNumber $node): bool
{
if ($node->value !== 0) {
return false;
}

$parentNode = ParentConnector::getParent($node);

if (!$parentNode instanceof Node\Arg) {
if (!$parentNode instanceof Node\Expr\UnaryMinus) {
return false;
}

$parentNode = ParentConnector::getParent($node);

if (!$parentNode instanceof Node\Arg) {
return false;
}
}

$parentNode = ParentConnector::getParent($parentNode);

return $parentNode instanceof Node\Expr\FuncCall
&& $parentNode->name instanceof Node\Name
&& $parentNode->name->toLowerString() === 'preg_split'
;
}
}
49 changes: 46 additions & 3 deletions src/Mutator/Number/IncrementInteger.php
Expand Up @@ -77,8 +77,51 @@ public function mutate(Node $node): iterable

public function canMutate(Node $node): bool
{
return $node instanceof Node\Scalar\LNumber
&& $node->value !== 0
&& !$this->isPartOfSizeComparison($node);
if (!$node instanceof Node\Scalar\LNumber) {
return false;
}

if (
$node->value === 0
&& ($this->isPartOfComparison($node) || ParentConnector::getParent($node) instanceof Node\Expr\Assign)
) {
return false;
}

if ($this->isPartOfSizeComparison($node)) {
return false;
}

if ($this->isPregSplitLimitZeroOrMinusOneArgument($node)) {
return false;
}

return true;
}

private function isPregSplitLimitZeroOrMinusOneArgument(Node\Scalar\LNumber $node): bool
{
if ($node->value !== 1) {
return false;
}

$parentNode = ParentConnector::getParent($node);

if (!$parentNode instanceof Node\Expr\UnaryMinus) {
return false;
}

$parentNode = ParentConnector::getParent($parentNode);

if (!$parentNode instanceof Node\Arg) {
return false;
}

$parentNode = ParentConnector::getParent($parentNode);

return $parentNode instanceof Node\Expr\FuncCall
&& $parentNode->name instanceof Node\Name
&& $parentNode->name->toLowerString() === 'preg_split'
;
}
}
47 changes: 44 additions & 3 deletions src/Mutator/Number/OneZeroInteger.php
Expand Up @@ -38,6 +38,7 @@
use Infection\Mutator\Definition;
use Infection\Mutator\GetMutatorName;
use Infection\Mutator\MutatorCategory;
use Infection\PhpParser\Visitor\ParentConnector;
use PhpParser\Node;

/**
Expand Down Expand Up @@ -77,8 +78,48 @@ public function mutate(Node $node): iterable

public function canMutate(Node $node): bool
{
return $node instanceof Node\Scalar\LNumber
&& ($node->value === 0 || $node->value === 1)
&& !$this->isPartOfSizeComparison($node);
if (!$node instanceof Node\Scalar\LNumber) {
return false;
}

if ($this->isPartOfSizeComparison($node)) {
return false;
}

if ($node->value !== 0 && $node->value !== 1) {
return false;
}

if ($this->isPregSplitLimitZeroOrMinusOneArgument($node)) {
return false;
}

return true;
}

private function isPregSplitLimitZeroOrMinusOneArgument(Node\Scalar\LNumber $node): bool
{
if ($node->value !== 1) {
return false;
}

$parentNode = ParentConnector::getParent($node);

if (!$parentNode instanceof Node\Expr\UnaryMinus) {
return false;
}

$parentNode = ParentConnector::getParent($parentNode);

if (!$parentNode instanceof Node\Arg) {
return false;
}

$parentNode = ParentConnector::getParent($parentNode);

return $parentNode instanceof Node\Expr\FuncCall
&& $parentNode->name instanceof Node\Name
&& $parentNode->name->toLowerString() === 'preg_split'
;
}
}
4 changes: 2 additions & 2 deletions tests/e2e/Exec_Path/expected-output.txt
@@ -1,6 +1,6 @@
Total: 6
Total: 7

Killed: 5
Killed: 6
Errored: 0
Escaped: 0
Timed Out: 0
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/TimeoutSkipped/expected-output.txt
@@ -1,8 +1,8 @@
Total: 5
Total: 6

Killed: 2
Errored: 0
Escaped: 2
Escaped: 3
Timed Out: 1
Skipped: 0
Not Covered: 0
36 changes: 36 additions & 0 deletions tests/phpunit/Mutator/Number/DecrementIntegerTest.php
Expand Up @@ -468,6 +468,42 @@ public function mutationsProvider(): iterable
<<<'PHP'
<?php
$b = $a[0];
PHP
];

yield 'It does not decrement limit argument of preg_split function when it equals to 0' => [
<<<'PHP'
<?php
preg_split('//', 'string', 0);
PHP
];

yield 'It does decrement limit argument of preg_split function when it greater than 0' => [
<<<'PHP'
<?php
preg_split('//', 'string', 1);
PHP
,
<<<'PHP'
<?php
preg_split('//', 'string', 0);
PHP
];

yield 'It does decrement limit argument of preg_split function when it equal to -1' => [
<<<'PHP'
<?php
preg_split('//', 'string', -1);
PHP
,
<<<'PHP'
<?php
preg_split('//', 'string', -2);
PHP
];
}
Expand Down
35 changes: 35 additions & 0 deletions tests/phpunit/Mutator/Number/IncrementIntegerTest.php
Expand Up @@ -206,5 +206,40 @@ public function mutationsProvider(): iterable
PHP
,
];

yield 'It does not increment limit argument of preg_split function when it equals to -1' => [
<<<'PHP'
<?php
preg_split('//', 'string', -1);
PHP
];

yield 'It does increment limit argument of preg_split function when it equals to 0' => [
<<<'PHP'
<?php
preg_split('//', 'string', 0);
PHP
,
<<<'PHP'
<?php
preg_split('//', 'string', 1);
PHP
];

yield 'It does increment limit argument of preg_split function when it equals to -2' => [
<<<'PHP'
<?php
preg_split('//', 'string', -2);
PHP
,
<<<'PHP'
<?php
preg_split('//', 'string', -1);
PHP
];
}
}
22 changes: 22 additions & 0 deletions tests/phpunit/Mutator/Number/OneZeroIntegerTest.php
Expand Up @@ -440,6 +440,28 @@ public function mutationsProvider(): iterable
if ($foo !== -0) {
echo 'bar';
}
PHP
];

yield 'It does not mutates limit argument of preg_split function when it equal to -1' => [
<<<'PHP'
<?php
preg_split('//', 'string', -1);
PHP
];

yield 'It mutates limit argument of preg_split function when it equal to 1' => [
<<<'PHP'
<?php
preg_split('//', 'string', 1);
PHP
,
<<<'PHP'
<?php
preg_split('//', 'string', 0);
PHP
];
}
Expand Down

0 comments on commit 1d82648

Please sign in to comment.