commit
12d41b160b
15 changed files with 180 additions and 61 deletions
|
@ -1,8 +1,8 @@
|
||||||
language: php
|
language: php
|
||||||
|
|
||||||
php:
|
php:
|
||||||
- 5.3
|
- 5.6
|
||||||
- 5.4
|
- 7.2
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- wget http://getcomposer.org/composer.phar
|
- wget http://getcomposer.org/composer.phar
|
||||||
|
|
10
README.md
10
README.md
|
@ -7,7 +7,15 @@ Simple math expressions calculator
|
||||||
|
|
||||||
## Install via Composer
|
## Install via Composer
|
||||||
|
|
||||||
All instructions to install here: https://packagist.org/packages/nxp/math-executor
|
Stable branch
|
||||||
|
```
|
||||||
|
composer require "nxp/math-executor" "dev-master"
|
||||||
|
```
|
||||||
|
|
||||||
|
Dev branch
|
||||||
|
```
|
||||||
|
composer require "nxp/math-executor" "dev-dev"
|
||||||
|
```
|
||||||
|
|
||||||
## Sample usage:
|
## Sample usage:
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace NXP\Classes;
|
||||||
use NXP\Classes\Token\InterfaceOperator;
|
use NXP\Classes\Token\InterfaceOperator;
|
||||||
use NXP\Classes\Token\TokenFunction;
|
use NXP\Classes\Token\TokenFunction;
|
||||||
use NXP\Classes\Token\TokenNumber;
|
use NXP\Classes\Token\TokenNumber;
|
||||||
|
use NXP\Classes\Token\TokenString;
|
||||||
use NXP\Classes\Token\TokenVariable;
|
use NXP\Classes\Token\TokenVariable;
|
||||||
use NXP\Exception\IncorrectExpressionException;
|
use NXP\Exception\IncorrectExpressionException;
|
||||||
use NXP\Exception\UnknownVariableException;
|
use NXP\Exception\UnknownVariableException;
|
||||||
|
@ -32,15 +33,18 @@ class Calculator
|
||||||
*/
|
*/
|
||||||
public function calculate($tokens, $variables)
|
public function calculate($tokens, $variables)
|
||||||
{
|
{
|
||||||
$stack = array();
|
$stack = [];
|
||||||
foreach ($tokens as $token) {
|
foreach ($tokens as $token) {
|
||||||
if ($token instanceof TokenNumber) {
|
if ($token instanceof TokenNumber) {
|
||||||
array_push($stack, $token);
|
array_push($stack, $token);
|
||||||
}
|
}
|
||||||
|
if ($token instanceof TokenString) {
|
||||||
|
array_push($stack, $token);
|
||||||
|
}
|
||||||
if ($token instanceof TokenVariable) {
|
if ($token instanceof TokenVariable) {
|
||||||
$variable = $token->getValue();
|
$variable = $token->getValue();
|
||||||
if (!array_key_exists($variable, $variables)) {
|
if (!array_key_exists($variable, $variables)) {
|
||||||
throw new UnknownVariableException();
|
throw new UnknownVariableException($variable);
|
||||||
}
|
}
|
||||||
$value = $variables[$variable];
|
$value = $variables[$variable];
|
||||||
array_push($stack, new TokenNumber($value));
|
array_push($stack, new TokenNumber($value));
|
||||||
|
|
|
@ -17,6 +17,7 @@ use NXP\Classes\Token\TokenLeftBracket;
|
||||||
use NXP\Classes\Token\TokenNumber;
|
use NXP\Classes\Token\TokenNumber;
|
||||||
use NXP\Classes\Token\TokenRightBracket;
|
use NXP\Classes\Token\TokenRightBracket;
|
||||||
use NXP\Classes\Token\TokenVariable;
|
use NXP\Classes\Token\TokenVariable;
|
||||||
|
use NXP\Classes\Token\TokenString;
|
||||||
use NXP\Exception\IncorrectBracketsException;
|
use NXP\Exception\IncorrectBracketsException;
|
||||||
use NXP\Exception\IncorrectExpressionException;
|
use NXP\Exception\IncorrectExpressionException;
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ class Lexer
|
||||||
*/
|
*/
|
||||||
public function stringToTokensStream($input)
|
public function stringToTokensStream($input)
|
||||||
{
|
{
|
||||||
$matches = array();
|
$matches = [];
|
||||||
preg_match_all($this->tokenFactory->getTokenParserRegex(), $input, $matches);
|
preg_match_all($this->tokenFactory->getTokenParserRegex(), $input, $matches);
|
||||||
$tokenFactory = $this->tokenFactory;
|
$tokenFactory = $this->tokenFactory;
|
||||||
$tokensStream = array_map(
|
$tokensStream = array_map(
|
||||||
|
@ -62,10 +63,13 @@ class Lexer
|
||||||
*/
|
*/
|
||||||
public function buildReversePolishNotation($tokensStream)
|
public function buildReversePolishNotation($tokensStream)
|
||||||
{
|
{
|
||||||
$output = array();
|
$output = [];
|
||||||
$stack = array();
|
$stack = [];
|
||||||
|
|
||||||
foreach ($tokensStream as $token) {
|
foreach ($tokensStream as $token) {
|
||||||
|
if ($token instanceof TokenString) {
|
||||||
|
$output[] = $token;
|
||||||
|
}
|
||||||
if ($token instanceof TokenNumber) {
|
if ($token instanceof TokenNumber) {
|
||||||
$output[] = $token;
|
$output[] = $token;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ class TokenFunction extends AbstractContainerToken implements InterfaceFunction
|
||||||
*/
|
*/
|
||||||
public function execute(&$stack)
|
public function execute(&$stack)
|
||||||
{
|
{
|
||||||
$args = array();
|
$args = [];
|
||||||
list($places, $function) = $this->value;
|
list($places, $function) = $this->value;
|
||||||
for ($i = 0; $i < $places; $i++) {
|
for ($i = 0; $i < $places; $i++) {
|
||||||
array_push($args, array_pop($stack)->getValue());
|
array_push($args, array_pop($stack)->getValue());
|
||||||
|
|
25
src/NXP/Classes/Token/TokenString.php
Normal file
25
src/NXP/Classes/Token/TokenString.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?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\Classes\Token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Bruce Wells <brucekwells@gmail.com>
|
||||||
|
*/
|
||||||
|
class TokenString extends AbstractContainerToken
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getRegex()
|
||||||
|
{
|
||||||
|
return '"([^"]|"")*"';
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ use NXP\Classes\Token\TokenLeftBracket;
|
||||||
use NXP\Classes\Token\TokenNumber;
|
use NXP\Classes\Token\TokenNumber;
|
||||||
use NXP\Classes\Token\TokenRightBracket;
|
use NXP\Classes\Token\TokenRightBracket;
|
||||||
use NXP\Classes\Token\TokenVariable;
|
use NXP\Classes\Token\TokenVariable;
|
||||||
|
use NXP\Classes\Token\TokenString;
|
||||||
use NXP\Exception\UnknownFunctionException;
|
use NXP\Exception\UnknownFunctionException;
|
||||||
use NXP\Exception\UnknownOperatorException;
|
use NXP\Exception\UnknownOperatorException;
|
||||||
use NXP\Exception\UnknownTokenException;
|
use NXP\Exception\UnknownTokenException;
|
||||||
|
@ -31,24 +32,35 @@ class TokenFactory
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $operators = array();
|
protected $operators = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available functions
|
* Available functions
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $functions = array();
|
protected $functions = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add function
|
* Add function
|
||||||
* @param $name
|
* @param string $name
|
||||||
* @param $function
|
* @param callable $function
|
||||||
* @param $places
|
* @param int $places
|
||||||
*/
|
*/
|
||||||
public function addFunction($name, $function, $places = 1)
|
public function addFunction($name, callable $function, $places = 1)
|
||||||
{
|
{
|
||||||
$this->functions[$name] = array($places, $function);
|
$this->functions[$name] = [$places, $function];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get functions
|
||||||
|
*
|
||||||
|
* @return array containing callback and places indexed by
|
||||||
|
* function name
|
||||||
|
*/
|
||||||
|
public function getFunctions()
|
||||||
|
{
|
||||||
|
return $this->functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +73,7 @@ class TokenFactory
|
||||||
$class = new \ReflectionClass($operatorClass);
|
$class = new \ReflectionClass($operatorClass);
|
||||||
|
|
||||||
if (!in_array('NXP\Classes\Token\InterfaceToken', $class->getInterfaceNames())) {
|
if (!in_array('NXP\Classes\Token\InterfaceToken', $class->getInterfaceNames())) {
|
||||||
throw new UnknownOperatorException;
|
throw new UnknownOperatorException($operatorClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->operators[] = $operatorClass;
|
$this->operators[] = $operatorClass;
|
||||||
|
@ -69,13 +81,13 @@ class TokenFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add variable
|
* Get registered operators
|
||||||
* @param string $name
|
*
|
||||||
* @param mixed $value
|
* @return array of operator class names
|
||||||
*/
|
*/
|
||||||
public function addVariable($name, $value)
|
public function getOperators()
|
||||||
{
|
{
|
||||||
|
return $this->operators;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,8 +101,9 @@ class TokenFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'/(%s)|([%s])|(%s)|(%s)|([%s%s%s])/i',
|
'/(%s)|(%s)|([%s])|(%s)|(%s)|([%s%s%s])/i',
|
||||||
TokenNumber::getRegex(),
|
TokenNumber::getRegex(),
|
||||||
|
TokenString::getRegex(),
|
||||||
$operatorsRegex,
|
$operatorsRegex,
|
||||||
TokenFunction::getRegex(),
|
TokenFunction::getRegex(),
|
||||||
TokenVariable::getRegex(),
|
TokenVariable::getRegex(),
|
||||||
|
@ -119,6 +132,10 @@ class TokenFactory
|
||||||
return new TokenRightBracket();
|
return new TokenRightBracket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($token[0] == '"') {
|
||||||
|
return new TokenString(str_replace('"', '', $token));
|
||||||
|
}
|
||||||
|
|
||||||
if ($token == ',') {
|
if ($token == ',') {
|
||||||
return new TokenComma();
|
return new TokenComma();
|
||||||
}
|
}
|
||||||
|
@ -140,10 +157,10 @@ class TokenFactory
|
||||||
if (isset($this->functions[$token])) {
|
if (isset($this->functions[$token])) {
|
||||||
return new TokenFunction($this->functions[$token]);
|
return new TokenFunction($this->functions[$token]);
|
||||||
} else {
|
} else {
|
||||||
throw new UnknownFunctionException();
|
throw new UnknownFunctionException($token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnknownTokenException();
|
throw new UnknownTokenException($token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace NXP\Exception;
|
||||||
/**
|
/**
|
||||||
* @author Alexander Kiryukhin <alexander@symdev.org>
|
* @author Alexander Kiryukhin <alexander@symdev.org>
|
||||||
*/
|
*/
|
||||||
class IncorrectBracketsException extends \Exception
|
class IncorrectBracketsException extends MathExecutorException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace NXP\Exception;
|
||||||
/**
|
/**
|
||||||
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
|
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
|
||||||
*/
|
*/
|
||||||
class IncorrectExpressionException extends \Exception
|
class IncorrectExpressionException extends MathExecutorException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace NXP\Exception;
|
||||||
/**
|
/**
|
||||||
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
|
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
|
||||||
*/
|
*/
|
||||||
class UnknownFunctionException extends \Exception
|
class UnknownFunctionException extends MathExecutorException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace NXP\Exception;
|
||||||
/**
|
/**
|
||||||
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
|
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
|
||||||
*/
|
*/
|
||||||
class UnknownOperatorException extends \Exception
|
class UnknownOperatorException extends MathExecutorException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace NXP\Exception;
|
||||||
/**
|
/**
|
||||||
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
|
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
|
||||||
*/
|
*/
|
||||||
class UnknownTokenException extends \Exception
|
class UnknownTokenException extends MathExecutorException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace NXP\Exception;
|
||||||
/**
|
/**
|
||||||
* @author Alexander Kiryukhin <alexander@symdev.org>
|
* @author Alexander Kiryukhin <alexander@symdev.org>
|
||||||
*/
|
*/
|
||||||
class UnknownVariableException extends \Exception
|
class UnknownVariableException extends MathExecutorException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ use NXP\Classes\Calculator;
|
||||||
use NXP\Classes\Lexer;
|
use NXP\Classes\Lexer;
|
||||||
use NXP\Classes\Token;
|
use NXP\Classes\Token;
|
||||||
use NXP\Classes\TokenFactory;
|
use NXP\Classes\TokenFactory;
|
||||||
|
use NXP\Exception\UnknownVariableException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class MathExecutor
|
* Class MathExecutor
|
||||||
|
@ -27,7 +28,7 @@ class MathExecutor
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $variables = array();
|
private $variables = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var TokenFactory
|
* @var TokenFactory
|
||||||
|
@ -37,7 +38,7 @@ class MathExecutor
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $cache = array();
|
private $cache = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base math operators
|
* Base math operators
|
||||||
|
@ -75,10 +76,36 @@ class MathExecutor
|
||||||
$this->tokenFactory->addFunction('max', 'max', 2);
|
$this->tokenFactory->addFunction('max', 'max', 2);
|
||||||
$this->tokenFactory->addFunction('avg', function($arg1, $arg2) { return ($arg1 + $arg2) / 2; }, 2);
|
$this->tokenFactory->addFunction('avg', function($arg1, $arg2) { return ($arg1 + $arg2) / 2; }, 2);
|
||||||
|
|
||||||
$this->setVars(array(
|
$this->setVars([
|
||||||
'pi' => 3.14159265359,
|
'pi' => 3.14159265359,
|
||||||
'e' => 2.71828182846
|
'e' => 2.71828182846
|
||||||
));
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all vars
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getVars()
|
||||||
|
{
|
||||||
|
return $this->variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a specific var
|
||||||
|
*
|
||||||
|
* @param string $variable
|
||||||
|
* @return integer|float
|
||||||
|
* @throws UnknownVariableException
|
||||||
|
*/
|
||||||
|
public function getVar($variable)
|
||||||
|
{
|
||||||
|
if (! isset($this->variables[$variable])) {
|
||||||
|
throw new UnknownVariableException("Variable ({$variable}) not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->variables[$variable];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,11 +113,14 @@ class MathExecutor
|
||||||
*
|
*
|
||||||
* @param string $variable
|
* @param string $variable
|
||||||
* @param integer|float $value
|
* @param integer|float $value
|
||||||
* @throws \Exception
|
|
||||||
* @return MathExecutor
|
* @return MathExecutor
|
||||||
*/
|
*/
|
||||||
public function setVar($variable, $value)
|
public function setVar($variable, $value)
|
||||||
{
|
{
|
||||||
|
if (!is_numeric($value)) {
|
||||||
|
throw new \Exception("Variable ({$variable}) value must be a number ({$value}) type ({gettype($value)})");
|
||||||
|
}
|
||||||
|
|
||||||
$this->variables[$variable] = $value;
|
$this->variables[$variable] = $value;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -134,7 +164,7 @@ class MathExecutor
|
||||||
*/
|
*/
|
||||||
public function removeVars()
|
public function removeVars()
|
||||||
{
|
{
|
||||||
$this->variables = array();
|
$this->variables = [];
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -152,6 +182,16 @@ class MathExecutor
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all registered operators to executor
|
||||||
|
*
|
||||||
|
* @return array of operator class names
|
||||||
|
*/
|
||||||
|
public function getOperators()
|
||||||
|
{
|
||||||
|
return $this->tokenFactory->getOperators();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add function to executor
|
* Add function to executor
|
||||||
*
|
*
|
||||||
|
@ -160,13 +200,24 @@ class MathExecutor
|
||||||
* @param int $places Count of arguments
|
* @param int $places Count of arguments
|
||||||
* @return MathExecutor
|
* @return MathExecutor
|
||||||
*/
|
*/
|
||||||
public function addFunction($name, callable $function = null, $places = 1)
|
public function addFunction($name, $function = null, $places = 1)
|
||||||
{
|
{
|
||||||
$this->tokenFactory->addFunction($name, $function, $places);
|
$this->tokenFactory->addFunction($name, $function, $places);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all registered functions
|
||||||
|
*
|
||||||
|
* @return array containing callback and places indexed by
|
||||||
|
* function name
|
||||||
|
*/
|
||||||
|
public function getFunctions()
|
||||||
|
{
|
||||||
|
return $this->tokenFactory->getFunctions();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute expression
|
* Execute expression
|
||||||
*
|
*
|
||||||
|
|
|
@ -27,7 +27,7 @@ class MathTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertEquals($calculator->execute($expression), $phpResult);
|
$this->assertEquals($calculator->execute($expression), $phpResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testZeroDevision()
|
public function testZeroDivision()
|
||||||
{
|
{
|
||||||
$calculator = new MathExecutor();
|
$calculator = new MathExecutor();
|
||||||
$this->assertEquals($calculator->execute('1 / 0'), 0);
|
$this->assertEquals($calculator->execute('1 / 0'), 0);
|
||||||
|
@ -44,34 +44,44 @@ class MathTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function providerExpressions()
|
public function providerExpressions()
|
||||||
{
|
{
|
||||||
return array(
|
return [
|
||||||
array('0.1 + 0.2'),
|
['0.1 + 0.2'],
|
||||||
array('1 + 2'),
|
['1 + 2'],
|
||||||
|
|
||||||
array('0.1 - 0.2'),
|
['0.1 - 0.2'],
|
||||||
array('1 - 2'),
|
['1 - 2'],
|
||||||
|
|
||||||
array('0.1 * 2'),
|
['0.1 * 2'],
|
||||||
array('1 * 2'),
|
['1 * 2'],
|
||||||
|
|
||||||
array('0.1 / 0.2'),
|
['0.1 / 0.2'],
|
||||||
array('1 / 2'),
|
['1 / 2'],
|
||||||
|
|
||||||
array('2 * 2 + 3 * 3'),
|
['2 * 2 + 3 * 3'],
|
||||||
|
|
||||||
array('1 + 0.6 - 3 * 2 / 50'),
|
['1 + 0.6 - 3 * 2 / 50'],
|
||||||
|
|
||||||
array('(5 + 3) * -1'),
|
['(5 + 3) * -1'],
|
||||||
|
|
||||||
array('2+2*2'),
|
['2+2*2'],
|
||||||
array('(2+2)*2'),
|
['(2+2)*2'],
|
||||||
array('(2+2)*-2'),
|
['(2+2)*-2'],
|
||||||
array('(2+-2)*2'),
|
['(2+-2)*2'],
|
||||||
|
|
||||||
array('sin(10) * cos(50) / min(10, 20/2)'),
|
['sin(10) * cos(50) / min(10, 20/2)'],
|
||||||
|
|
||||||
array('100500 * 3.5E5'),
|
['100500 * 3.5E5'],
|
||||||
array('100500 * 3.5E-5')
|
['100500 * 3.5E-5'],
|
||||||
);
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFunction()
|
||||||
|
{
|
||||||
|
$calculator = new MathExecutor();
|
||||||
|
|
||||||
|
$calculator->addFunction('round', function ($arg) { return round($arg); }, 1);
|
||||||
|
/** @var float $phpResult */
|
||||||
|
eval('$phpResult = round(100/30);');
|
||||||
|
$this->assertEquals($calculator->execute('round(100/30)'), $phpResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue