From 3f0c9f958395565c718f1812e9ad5ad6e83ba8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kowalik?= Date: Sat, 30 Mar 2019 16:18:47 +0100 Subject: [PATCH] #658 added required tests, refactoring --- src/Mutator/Extensions/BCMath.php | 63 +++++++------ tests/Mutator/Extensions/BCMathTest.php | 112 +++++++++++++----------- 2 files changed, 90 insertions(+), 85 deletions(-) diff --git a/src/Mutator/Extensions/BCMath.php b/src/Mutator/Extensions/BCMath.php index fa0d0f4abc..b132579151 100644 --- a/src/Mutator/Extensions/BCMath.php +++ b/src/Mutator/Extensions/BCMath.php @@ -57,69 +57,66 @@ public function __construct(MutatorConfig $config) } /** + * @param Node|Node\Expr\FuncCall $node + * * @return Node|Node[]|Generator */ public function mutate(Node $node) { - yield from $this->converters[$this->getFunctionName($node)]($node); + yield from $this->converters[$node->name->toLowerString()]($node); } protected function mutatesNode(Node $node): bool - { - $functionName = $this->getFunctionName($node); - - return $functionName !== null && isset($this->converters[$functionName]) && \function_exists($functionName); - } - - private function getFunctionName(Node $node): ?string { if (!$node instanceof Node\Expr\FuncCall || !$node->name instanceof Node\Name) { - return null; + return false; } - return \strtolower($node->name->toString()); + $functionName = $node->name->toLowerString(); + + return $functionName !== null && isset($this->converters[$functionName]) && \function_exists($functionName); } private function setupConverters(array $functionsMap): void { $converters = [ - 'bcadd' => $this->minArgsCastString(2, - $this->binaryOp(Node\Expr\BinaryOp\Plus::class) + 'bcadd' => $this->mapCheckingMinArgsThenCastToString(2, + $this->mapBinaryOperator(Node\Expr\BinaryOp\Plus::class) ), - 'bccomp' => $this->minArgsCastString(2, - $this->binaryOp(Node\Expr\BinaryOp\Spaceship::class) + 'bccomp' => $this->mapCheckingMinArgsThenCastToString(2, + $this->mapBinaryOperator(Node\Expr\BinaryOp\Spaceship::class) ), - 'bcdiv' => $this->minArgsCastString(2, - $this->binaryOp(Node\Expr\BinaryOp\Div::class) + 'bcdiv' => $this->mapCheckingMinArgsThenCastToString(2, + $this->mapBinaryOperator(Node\Expr\BinaryOp\Div::class) ), - 'bcmod' => $this->minArgsCastString(2, - $this->binaryOp(Node\Expr\BinaryOp\Mod::class) + 'bcmod' => $this->mapCheckingMinArgsThenCastToString(2, + $this->mapBinaryOperator(Node\Expr\BinaryOp\Mod::class) ), - 'bcmul' => $this->minArgsCastString(2, - $this->binaryOp(Node\Expr\BinaryOp\Mul::class) + 'bcmul' => $this->mapCheckingMinArgsThenCastToString(2, + $this->mapBinaryOperator(Node\Expr\BinaryOp\Mul::class) ), - 'bcpow' => $this->minArgsCastString(2, - $this->binaryOp(Node\Expr\BinaryOp\Pow::class) + 'bcpow' => $this->mapCheckingMinArgsThenCastToString(2, + $this->mapBinaryOperator(Node\Expr\BinaryOp\Pow::class) ), - 'bcsub' => $this->minArgsCastString(2, - $this->binaryOp(Node\Expr\BinaryOp\Minus::class) + 'bcsub' => $this->mapCheckingMinArgsThenCastToString(2, + $this->mapBinaryOperator(Node\Expr\BinaryOp\Minus::class) ), - 'bcsqrt' => $this->minArgsCastString(2, - $this->squareRoots() + 'bcsqrt' => $this->mapCheckingMinArgsThenCastToString(2, + $this->mapSquareRoots() ), - 'bcpowmod' => $this->minArgsCastString(3, - $this->powerModulo() + 'bcpowmod' => $this->mapCheckingMinArgsThenCastToString(3, + $this->mapPowerModulo() ), ]; - $functionsToRemove = \array_filter($functionsMap, function ($isOn) { + $functionsToRemove = \array_filter($functionsMap, static function ($isOn) { return !$isOn; }); $this->converters = \array_diff_key($converters, $functionsToRemove); } - private function minArgsCastString(int $minimumArgsCount, callable $converter): callable + private function mapCheckingMinArgsThenCastToString(int $minimumArgsCount, callable $converter): callable { return static function (Node\Expr\FuncCall $node) use ($minimumArgsCount, $converter): Generator { if (\count($node->args) >= $minimumArgsCount) { @@ -130,14 +127,14 @@ private function minArgsCastString(int $minimumArgsCount, callable $converter): }; } - private function binaryOp(string $operator): callable + private function mapBinaryOperator(string $operator): callable { return static function (Node\Expr\FuncCall $node) use ($operator): Generator { yield new $operator($node->args[0]->value, $node->args[1]->value); }; } - private function squareRoots(): callable + private function mapSquareRoots(): callable { return static function (Node\Expr\FuncCall $node): Generator { yield new Node\Expr\FuncCall( @@ -147,7 +144,7 @@ private function squareRoots(): callable }; } - private function powerModulo(): callable + private function mapPowerModulo(): callable { return static function (Node\Expr\FuncCall $node): Generator { yield new Node\Expr\BinaryOp\Mod( diff --git a/tests/Mutator/Extensions/BCMathTest.php b/tests/Mutator/Extensions/BCMathTest.php index 7fb6688edb..b431c14044 100644 --- a/tests/Mutator/Extensions/BCMathTest.php +++ b/tests/Mutator/Extensions/BCMathTest.php @@ -32,39 +32,6 @@ */ declare(strict_types=1); -/** - * This code is licensed under the BSD 3-Clause License. - * - * Copyright (c) 2017-2019, Maks Rafalko - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//declare(strict_types=1); namespace Infection\Tests\Mutator\Extensions; @@ -86,12 +53,6 @@ public function test_mutator(string $input, string $expected = null, array $sett public function provideMutationCases(): Generator { - yield 'It does not convert bcadd when disabled' => [ - " ['bcadd' => false]], - ]; - yield from $this->provideMutationCasesForBinaryOperator('bcadd', '+', 'summation'); yield from $this->provideMutationCasesForBinaryOperator('bccomp', '<=>', 'spaceship'); @@ -118,14 +79,17 @@ private function provideMutationCasesForBinaryOperator(string $bcFunc, string $o " [ - " [ + "randomizeCase($bcFunc)}(func(), \$b->test());", + "test());", ]; - yield "It does not convert $bcFunc when not enough arguments" => [ - " [ + "provideCasesWhereMutatorShouldNotApply($bcFunc); } private function provideMutationCasesForPowerOperator(): Generator @@ -135,14 +99,17 @@ private function provideMutationCasesForPowerOperator(): Generator " [ + ' [ ' [ - 'provideCasesWhereMutatorShouldNotApply('bcpow'); } private function provideMutationCasesForSquareRoot(): Generator @@ -152,14 +119,17 @@ private function provideMutationCasesForSquareRoot(): Generator " [ + ' [ ' [ - 'provideCasesWhereMutatorShouldNotApply('bcsqrt'); } private function provideMutationCasesForPowerModulo(): Generator @@ -169,13 +139,51 @@ private function provideMutationCasesForPowerModulo(): Generator " [ + ' [ ' [ - 'provideCasesWhereMutatorShouldNotApply('bcpowmod', 3); + } + + private function provideCasesWhereMutatorShouldNotApply(string $bcFunc, int $requiredArgumentsCount = 2): Generator + { + $invalidArgumentsExpression = $this->generateArgumentsExpression($requiredArgumentsCount - 1); + $validArgumentsExpression = $this->generateArgumentsExpression($requiredArgumentsCount); + + yield "It does not convert $bcFunc when no enough arguments" => [ + " [ + " [ + " [$bcFunc => false]], ]; } + + private function randomizeCase(string $bcFunc): string + { + $bcFunc[2] = strtoupper($bcFunc[2]); + $bcFunc[4] = strtoupper($bcFunc[4]); + + return ucfirst($bcFunc); + } + + private function generateArgumentsExpression(int $numberOfArguments): string + { + return \implode(', ', \array_map(static function (string $argument) { + return "'$argument'"; + }, \range(1, $numberOfArguments))); + } }