Support for better invalid expression detection and divide by zero (#30)

* Additional validation for bad expressions (*+ for example)

* Removing DivisionByZeroException testing for now

Added more unit tests.
This commit is contained in:
Bruce Wells 2018-10-25 11:54:54 -04:00 committed by GitHub
parent 4a672cfd94
commit 43f0ff3f28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 111 additions and 4 deletions

View file

@ -54,7 +54,7 @@ class Calculator
}
}
$result = array_pop($stack);
if (!empty($stack)) {
if ($result === null || ! empty($stack)) {
throw new IncorrectExpressionException();
}

View file

@ -10,6 +10,8 @@
namespace NXP\Classes\Token;
use NXP\Exception\IncorrectExpressionException;
/**
* @author Alexander Kiryukhin <alexander@symdev.org>
*/
@ -41,12 +43,20 @@ class TokenDegree extends AbstractOperator
/**
* @param InterfaceToken[] $stack
*
* @return TokenNumber
*
* @throws \NXP\Exception\IncorrectExpressionException
*/
public function execute(&$stack)
{
$op2 = array_pop($stack);
$op1 = array_pop($stack);
if ($op1 === null || $op2 === null) {
throw new IncorrectExpressionException("Power operator requires two operators");
}
$result = $op1->getValue() ** $op2->getValue();
return new TokenNumber($result);

View file

@ -10,6 +10,9 @@
namespace NXP\Classes\Token;
use NXP\Exception\IncorrectExpressionException;
use NXP\Exception\DivisionByZeroException;
/**
* @author Alexander Kiryukhin <alexander@symdev.org>
*/
@ -41,12 +44,21 @@ class TokenDivision extends AbstractOperator
/**
* @param InterfaceToken[] $stack
*
* @return $this
*
* @throws \NXP\Exception\IncorrectExpressionException
* @throws \NXP\Exception\DivisionByZeroException
*/
public function execute(&$stack)
{
$op2 = array_pop($stack);
$op1 = array_pop($stack);
if ($op1 === null || $op2 === null) {
throw new IncorrectExpressionException("Division requires two operators");
}
$result = $op2->getValue() != 0 ? $op1->getValue() / $op2->getValue() : 0;
return new TokenNumber($result);

View file

@ -10,6 +10,8 @@
namespace NXP\Classes\Token;
use NXP\Exception\IncorrectExpressionException;
/**
* @author Alexander Kiryukhin <alexander@symdev.org>
*/
@ -41,12 +43,20 @@ class TokenMinus extends AbstractOperator
/**
* @param InterfaceToken[] $stack
*
* @return $this
*
* @throws \NXP\Exception\IncorrectExpressionException
*/
public function execute(&$stack)
{
$op2 = array_pop($stack);
$op1 = array_pop($stack);
if ($op1 === null || $op2 === null) {
throw new IncorrectExpressionException("Subtraction requires two operators");
}
$result = $op1->getValue() - $op2->getValue();
return new TokenNumber($result);

View file

@ -10,6 +10,8 @@
namespace NXP\Classes\Token;
use NXP\Exception\IncorrectExpressionException;
/**
* @author Alexander Kiryukhin <alexander@symdev.org>
*/
@ -41,12 +43,20 @@ class TokenMultiply extends AbstractOperator
/**
* @param InterfaceToken[] $stack
*
* @return $this
*
* @throws \NXP\Exception\IncorrectExpressionException
*/
public function execute(&$stack)
{
$op2 = array_pop($stack);
$op1 = array_pop($stack);
if ($op1 === null || $op2 === null) {
throw new IncorrectExpressionException("Multiplication requires two operators");
}
$result = $op1->getValue() * $op2->getValue();
return new TokenNumber($result);

View file

@ -10,6 +10,8 @@
namespace NXP\Classes\Token;
use NXP\Exception\IncorrectExpressionException;
/**
* @author Alexander Kiryukhin <alexander@symdev.org>
*/
@ -41,12 +43,20 @@ class TokenPlus extends AbstractOperator
/**
* @param InterfaceToken[] $stack
*
* @return $this
*
* @throws \NXP\Exception\IncorrectExpressionException
*/
public function execute(&$stack)
{
$op2 = array_pop($stack);
$op1 = array_pop($stack);
if ($op1 === null || $op2 === null) {
throw new IncorrectExpressionException("Addition requires two operators");
}
$result = $op1->getValue() + $op2->getValue();
return new TokenNumber($result);

View file

@ -0,0 +1,19 @@
<?php
/**
* This file is part of the MathExecutor package
*
* (c) Alexander Kiryukhin
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code
*/
namespace NXP\Exception;
/**
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
*/
class DivisionByZeroException extends MathExecutorException
{
}

View file

@ -11,7 +11,15 @@
namespace NXP\Tests;
use \NXP\MathExecutor;
use NXP\MathExecutor;
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;
class MathTest extends \PHPUnit_Framework_TestCase
{
@ -27,10 +35,28 @@ class MathTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($calculator->execute($expression), $phpResult);
}
public function testUnknownFunctionException()
{
$calculator = new MathExecutor();
$this->expectException(UnknownFunctionException::class);
$calculator->execute('1 * fred("wilma") + 3');
}
public function testIncorrectExpressionException()
{
$calculator = new MathExecutor();
$this->expectException(IncorrectExpressionException::class);
$calculator->execute('1 * + ');
}
public function testZeroDivision()
{
$calculator = new MathExecutor();
$this->assertEquals($calculator->execute('1 / 0'), 0);
// future version with allow for optional exceptions on divide by zero
// $this->expectException(DivisionByZeroException::class);
// $calculator->execute('1 / 0');
}
public function testExponentiation()
@ -63,15 +89,25 @@ class MathTest extends \PHPUnit_Framework_TestCase
['(5 + 3) * -1'],
['2+2*2'],
['2- 2*2'],
['2-(2*2)'],
['(2- 2)*2'],
['2 + 2*2'],
['2+ 2*2'],
['(2+2)*2'],
['(2+2)*-2'],
['(2 + 2)*-2'],
['(2+-2)*2'],
['sin(10) * cos(50) / min(10, 20/2)'],
['100500 * 3.5E5'],
['100500 * 3.5E-5'],
['-1 + -2'],
['-1+-2'],
['-1- -2'],
['-1/-2'],
['-1*-2'],
];
}