From cab8e2d38ae1c8c7fb75022f7d9b0539a0a86d4e Mon Sep 17 00:00:00 2001 From: Alexander Kiryukhin Date: Fri, 15 May 2020 21:51:23 +0300 Subject: Massive refactoring More clean structure Parsing without regular expressions --- tests/MathTest.php | 59 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 23 deletions(-) (limited to 'tests') diff --git a/tests/MathTest.php b/tests/MathTest.php index 7cbc7de..958f14c 100644 --- a/tests/MathTest.php +++ b/tests/MathTest.php @@ -11,17 +11,15 @@ namespace NXP\Tests; -use NXP\MathExecutor; +use Exception; +use NXP\Classes\Operator; use NXP\Exception\DivisionByZeroException; -use NXP\Exception\IncorrectBracketsException; use NXP\Exception\IncorrectExpressionException; -use NXP\Exception\MathExecutorException; use NXP\Exception\UnknownFunctionException; -use NXP\Exception\UnknownOperatorException; -use NXP\Exception\UnknownTokenException; -use NXP\Exception\UnknownVariableException; +use NXP\MathExecutor; +use PHPUnit\Framework\TestCase; -class MathTest extends \PHPUnit\Framework\TestCase +class MathTest extends TestCase { /** * @dataProvider providerExpressions @@ -32,15 +30,20 @@ class MathTest extends \PHPUnit\Framework\TestCase /** @var float $phpResult */ eval('$phpResult = ' . $expression . ';'); - $this->assertEquals($phpResult, $calculator->execute($expression), "Expression was: ${expression}"); + try { + $result = $calculator->execute($expression); + } catch (Exception $e) { + $this->fail(sprintf("Exception: %s (%s:%d), expression was: %s", get_class($e), $e->getFile(), $e->getLine(), $expression)); + } + $this->assertEquals($phpResult, $result, "Expression was: ${expression}"); } /** * Expressions data provider - * - * Most tests can go in here. The idea is that each expression will be evaluated by MathExecutor and by PHP with eval. - * The results should be the same. If they are not, then the test fails. No need to add extra test unless you are doing - * something more complete and not a simple mathmatical expression. + * + * Most tests can go in here. The idea is that each expression will be evaluated by MathExecutor and by PHP with eval. + * The results should be the same. If they are not, then the test fails. No need to add extra test unless you are doing + * something more complete and not a simple mathmatical expression. */ public function providerExpressions() { @@ -223,13 +226,18 @@ class MathTest extends \PHPUnit\Framework\TestCase public function testZeroDivision() { $calculator = new MathExecutor(); + $calculator->addOperator(new Operator("/", false, 180, function ($a, $b) { + if ($b == 0) { + return 0; + } + return $a / $b; + })); $this->assertEquals(0, $calculator->execute('10 / 0')); } public function testZeroDivisionException() { $calculator = new MathExecutor(); - $calculator->setDivisionByZeroException(); $this->expectException(DivisionByZeroException::class); $calculator->execute('10 / 0'); } @@ -244,7 +252,9 @@ class MathTest extends \PHPUnit\Framework\TestCase { $calculator = new MathExecutor(); - $calculator->addFunction('concat', function ($arg1, $arg2) {return $arg1.$arg2;}); + $calculator->addFunction('concat', function ($arg1, $arg2) { + return $arg1 . $arg2; + }); $this->assertEquals('testing', $calculator->execute('concat("test","ing")')); $this->assertEquals('testing', $calculator->execute("concat('test','ing')")); } @@ -252,8 +262,10 @@ class MathTest extends \PHPUnit\Framework\TestCase public function testFunction() { $calculator = new MathExecutor(); - $calculator->addFunction('round', function ($arg) {return round($arg);}); - $this->assertEquals(round(100/30), $calculator->execute('round(100/30)')); + $calculator->addFunction('round', function ($arg) { + return round($arg); + }); + $this->assertEquals(round(100 / 30), $calculator->execute('round(100/30)')); } public function testFunctionIf() @@ -280,12 +292,12 @@ class MathTest extends \PHPUnit\Framework\TestCase public function testEvaluateFunctionParameters() { $calculator = new MathExecutor(); - $calculator->addFunction('round', function ($value, $decimals) - { + $calculator->addFunction('round', function ($value, $decimals) { return round($value, $decimals); - } + } ); $expression = 'round(100 * 1.111111, 2)'; + $phpResult = 0; eval('$phpResult = ' . $expression . ';'); $this->assertEquals($phpResult, $calculator->execute($expression)); $expression = 'round((100*0.04)+(((100*1.02)+0.5)*1.28),2)'; @@ -296,7 +308,9 @@ class MathTest extends \PHPUnit\Framework\TestCase public function testFunctionsWithQuotes() { $calculator = new MathExecutor(); - $calculator->addFunction('concat', function($first, $second){return $first.$second;}); + $calculator->addFunction('concat', function ($first, $second) { + return $first . $second; + }); $this->assertEquals('testing', $calculator->execute('concat("test", "ing")')); $this->assertEquals('testing', $calculator->execute("concat('test', 'ing')")); } @@ -305,11 +319,10 @@ class MathTest extends \PHPUnit\Framework\TestCase { $calculator = new MathExecutor(); $testString = "some, long. arg; with: different-separators!"; - $calculator->addFunction('test', function ($arg) use ($testString) - { + $calculator->addFunction('test', function ($arg) use ($testString) { $this->assertEquals($testString, $arg); return 0; - } + } ); $calculator->execute('test("' . $testString . '")'); // single quotes $calculator->execute("test('" . $testString . "')"); // double quotes -- cgit v1.2.3 From b95ab24f367baf928332dc5040ab444c1c719623 Mon Sep 17 00:00:00 2001 From: Bruce Wells Date: Tue, 19 May 2020 22:36:55 -0400 Subject: setDivisionByZeroIsZero --- src/NXP/MathExecutor.php | 16 ++++++++++++++++ tests/MathTest.php | 9 ++------- 2 files changed, 18 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php index 0b7e9db..e214209 100644 --- a/src/NXP/MathExecutor.php +++ b/src/NXP/MathExecutor.php @@ -468,6 +468,22 @@ class MathExecutor return $this->tokenFactory->getFunctions(); } + /** + * Set division by zero returns zero instead of throwing DivisionByZeroException + * + * @return MathExecutor + */ + public function setDivisionByZeroIsZero() : self + { + $this->addOperator(new Operator("/", false, 180, function ($a, $b) { + if ($b == 0) { + return 0; + } + return $a / $b; + })); + return $this; + } + public function __clone() { $this->addDefaults(); diff --git a/tests/MathTest.php b/tests/MathTest.php index 958f14c..39ac649 100644 --- a/tests/MathTest.php +++ b/tests/MathTest.php @@ -203,7 +203,7 @@ class MathTest extends TestCase ['(-3 * -1)'], ['1 + (-3 * -1)'], ['1 + ( -3 * 1)'], - ['1 + (3 * -1)'], + ['1 + (3 *-1)'], ['1 - 0'], ['1-0'], ]; @@ -226,12 +226,7 @@ class MathTest extends TestCase public function testZeroDivision() { $calculator = new MathExecutor(); - $calculator->addOperator(new Operator("/", false, 180, function ($a, $b) { - if ($b == 0) { - return 0; - } - return $a / $b; - })); + $calculator->setDivisionByZeroIsZero(); $this->assertEquals(0, $calculator->execute('10 / 0')); } -- cgit v1.2.3