Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't mutate $limit argument from 0 to -1 and from -1 to 0 in preg_split function #1347

Merged
merged 3 commits into from Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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