From ce5001573292f864471acf006b69186e2a2ba8be Mon Sep 17 00:00:00 2001 From: Bruce Wells Date: Fri, 16 Aug 2019 10:27:44 -0400 Subject: Subtraction fix (#46) * Updated unit tests * Fixed docs * Better unary minus support --- .gitignore | 3 ++- README.md | 10 ++++++++-- phpunit.xml.dist | 1 - src/NXP/Classes/Lexer.php | 20 ++++++++++++++++++-- tests/MathTest.php | 23 ++++++++++++++++++++++- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 83436db..c3b38ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ vendor/ .idea/ -composer.lock \ No newline at end of file +composer.lock +.phpunit.result.cache diff --git a/README.md b/README.md index 81d9475..7238a0b 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,8 @@ $executor->addFunction('abs', function($arg) {return abs($arg);}); ``` Function default parameters are not supported at this time. +Default parameters are not currently supported. + ## Operators: Default operators: `+ - * / ^` @@ -112,7 +114,7 @@ Default variables: ``` $pi = 3.14159265359 -$e = 2.71828182846 +$e = 2.71828182846 ``` You can add your own variables to executor: @@ -138,7 +140,7 @@ try { ``` ## Unary Minus Operator: -Negative numbers are supported via the unary minus operator, but need to have a space before the minus sign. `-1+ -3` is legal, while `-1+-3` will produce an error due to the way the parser works. Positive numbers are not explicitly supported as unsigned numbers are assumed positive. +Negative numbers are supported via the unary minus operator. Positive numbers are not explicitly supported as unsigned numbers are assumed positive. ## String Support: Expressions can contain double or single quoted strings that are evaluated the same way as PHP evalutes strings as numbers. You can also pass strings to functions. @@ -156,3 +158,7 @@ You can add operators, functions and variables with the public methods in MathEx This will allow you to remove functions and operators if needed, or implement different types more simply. Also note that you can replace an existing default operator by adding a new operator with the same regular expression string. For example if you just need to redefine TokenPlus, you can just add a new operator with the same regex string, in this case '\\+'. + +## Future Enhancements + +At some point this package will be upgraded to a currently supported version of PHP. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index bfe1846..d515f51 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -8,7 +8,6 @@ convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" - syntaxCheck="false" bootstrap="./tests/bootstrap.php" > diff --git a/src/NXP/Classes/Lexer.php b/src/NXP/Classes/Lexer.php index 898d8c1..73c25ac 100644 --- a/src/NXP/Classes/Lexer.php +++ b/src/NXP/Classes/Lexer.php @@ -15,11 +15,12 @@ use NXP\Classes\Token\InterfaceOperator; use NXP\Classes\Token\TokenComma; use NXP\Classes\Token\TokenFunction; use NXP\Classes\Token\TokenLeftBracket; +use NXP\Classes\Token\TokenMinus; use NXP\Classes\Token\TokenNumber; use NXP\Classes\Token\TokenRightBracket; +use NXP\Classes\Token\TokenStringDoubleQuoted; use NXP\Classes\Token\TokenStringSingleQuoted; use NXP\Classes\Token\TokenVariable; -use NXP\Classes\Token\TokenStringDoubleQuoted; use NXP\Exception\IncorrectBracketsException; use NXP\Exception\IncorrectExpressionException; @@ -66,6 +67,7 @@ class Lexer { $output = []; $stack = []; + $lastToken = null; foreach ($tokensStream as $token) { if ($token instanceof TokenStringDoubleQuoted) { @@ -73,7 +75,20 @@ class Lexer } elseif ($token instanceof TokenStringSingleQuoted) { $output[] = $token; } elseif ($token instanceof TokenNumber) { - $output[] = $token; + // if the number starts with a minus sign, it could be a negative number, or it could be an operator grabbed by the greedy regex + // if previous token is an operator, then it negative, otherwise remove the minus sign and put a negative operator on the stack + if ($lastToken !== null) { + $value = (int)$token->getValue(); + if ($value < 0 && ! ($lastToken instanceof AbstractOperator)) { + $token = new TokenNumber(abs($value)); + $output[] = $token; + $output[] = new TokenMinus('-'); + } else { + $output[] = $token; + } + } else { + $output[] = $token; + } } elseif ($token instanceof TokenVariable) { $output[] = $token; } elseif ($token instanceof TokenFunction) { @@ -118,6 +133,7 @@ class Lexer $output[] = array_pop($stack); } } + $lastToken = $token; } while (!empty($stack)) { $token = array_pop($stack); diff --git a/tests/MathTest.php b/tests/MathTest.php index 3cf4dbd..7f5ce9b 100644 --- a/tests/MathTest.php +++ b/tests/MathTest.php @@ -41,6 +41,15 @@ class MathTest extends \PHPUnit_Framework_TestCase public function providerExpressions() { return [ + ['-5'], + ['-5+10'], + ['4-5'], + ['4 -5'], + ['(4*2)-5'], + ['(4*2) - 5'], + ['4*-5'], + ['4 * -5'], + ['0.1 + 0.2'], ['1 + 2'], @@ -80,7 +89,6 @@ class MathTest extends \PHPUnit_Framework_TestCase ['1 + 2 * 3 / (3 * min(1, 5) * 2 + 1)'], ['1 + 2 * 3 / (3 / min(1, 5) / 2 + 1)'], - ['sin(10) * cos(50) / min(10, 20/2)'], ['sin(10) * cos(50) / min(10, (20/2))'], ['sin(10) * cos(50) / min(10, (max(10,20)/2))'], @@ -97,6 +105,11 @@ class MathTest extends \PHPUnit_Framework_TestCase ['-1- -2'], ['-1/-2'], ['-1*-2'], + + ['(1+2+3+4-5)*7/100'], + ['(1+2+3+4- 5)*7/100'], + ['( 1 + 2 + 3 + 4 - 5 ) * 7 / 100'], + ]; } @@ -166,6 +179,14 @@ class MathTest extends \PHPUnit_Framework_TestCase $this->assertEquals($phpResult, $calculator->execute($expression)); } + public function testFunctionsWithQuotes() + { + $calculator = new MathExecutor(); + $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')")); + } + public function testQuotes() { $calculator = new MathExecutor(); -- cgit v1.2.3 From b8456057af1bcaad362ccb5ef55e8c696dd63e11 Mon Sep 17 00:00:00 2001 From: Bruce Wells Date: Wed, 30 Oct 2019 22:14:36 -0400 Subject: Upgrading to PHP 7.1 (#48) * Subtraction fix (#46) (#7) * Updated unit tests * Fixed docs * Better unary minus support * Subtraction fix (#46) (#8) * Updated unit tests * Fixed docs * Better unary minus support * Upgrading PHPUnit and dropping support for 5.6 and 7.0 --- .travis.yml | 1 - composer.json | 4 ++-- tests/MathTest.php | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 551e6ed..3a63f2f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - 5.6 - 7.1 - 7.2 - 7.3 diff --git a/composer.json b/composer.json index dc35c2f..4c57b47 100644 --- a/composer.json +++ b/composer.json @@ -12,10 +12,10 @@ } ], "require": { - "php": ">=5.6" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "~5.0" + "phpunit/phpunit": "~7.0" }, "autoload": { "psr-0": {"NXP": "src/"} diff --git a/tests/MathTest.php b/tests/MathTest.php index 7f5ce9b..e289016 100644 --- a/tests/MathTest.php +++ b/tests/MathTest.php @@ -21,7 +21,7 @@ use NXP\Exception\UnknownOperatorException; use NXP\Exception\UnknownTokenException; use NXP\Exception\UnknownVariableException; -class MathTest extends \PHPUnit_Framework_TestCase +class MathTest extends \PHPUnit\Framework\TestCase { /** * @dataProvider providerExpressions -- cgit v1.2.3 From 29c5b5006ccb5cb308b9467ca25813b29be8cfc6 Mon Sep 17 00:00:00 2001 From: franksl Date: Tue, 26 Nov 2019 15:00:24 +0100 Subject: Logicandcompare (#50) * TokenFactory: allowing multicharacter tokens * Added logical and compare operators: <, <=, >, >=, ==, !=, ||, && * Fixed operator priorities * Error messages fixes * Fixed operators priority The priorities are assigned by following the php language standard (https://www.php.net/manual/en/language.operators.precedence.php) I've assigned precedence in steps of 10 units by following the linked page: 230 clone new 220 ** 210 ++ -- ~ (int) (float) (string) (array) (object) (bool) @ 200 instanceof 190 ! 180 * / % 170 + - . 160 << >> 150 < <= > >= 140 == != === !== <> <=> 130 & 120 ^ 110 | 100 && 90 || 80 ?? 70 ? : 60 = += -= *= **= /= .= %= &= |= ^= <<= >>= 50 yield from 40 yield 30 and 20 xor 10 or * Added if() function * Cache key fix There are cases where the cache key creation raised an error, for example while evaluating the expression "if(cos(2), cos(2), 0)", because the if() function was passing a float to the MathExecutor:execute() method. --- .gitignore | 1 + src/NXP/Classes/Token/TokenAnd.php | 53 ++++++++++++++++++++ src/NXP/Classes/Token/TokenDegree.php | 2 +- src/NXP/Classes/Token/TokenDivision.php | 2 +- src/NXP/Classes/Token/TokenEqual.php | 53 ++++++++++++++++++++ src/NXP/Classes/Token/TokenGreaterThan.php | 53 ++++++++++++++++++++ src/NXP/Classes/Token/TokenGreaterThanOrEqual.php | 53 ++++++++++++++++++++ src/NXP/Classes/Token/TokenLessThan.php | 53 ++++++++++++++++++++ src/NXP/Classes/Token/TokenLessThanOrEqual.php | 53 ++++++++++++++++++++ src/NXP/Classes/Token/TokenMinus.php | 2 +- src/NXP/Classes/Token/TokenMultiply.php | 2 +- src/NXP/Classes/Token/TokenOr.php | 53 ++++++++++++++++++++ src/NXP/Classes/Token/TokenPlus.php | 2 +- src/NXP/Classes/Token/TokenUnequal.php | 53 ++++++++++++++++++++ src/NXP/Classes/TokenFactory.php | 10 ++-- src/NXP/MathExecutor.php | 27 ++++++++-- tests/MathTest.php | 61 +++++++++++++++++++++++ 17 files changed, 520 insertions(+), 13 deletions(-) create mode 100644 src/NXP/Classes/Token/TokenAnd.php create mode 100644 src/NXP/Classes/Token/TokenEqual.php create mode 100644 src/NXP/Classes/Token/TokenGreaterThan.php create mode 100644 src/NXP/Classes/Token/TokenGreaterThanOrEqual.php create mode 100644 src/NXP/Classes/Token/TokenLessThan.php create mode 100644 src/NXP/Classes/Token/TokenLessThanOrEqual.php create mode 100644 src/NXP/Classes/Token/TokenOr.php create mode 100644 src/NXP/Classes/Token/TokenUnequal.php diff --git a/.gitignore b/.gitignore index c3b38ab..7256f68 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ vendor/ .idea/ composer.lock .phpunit.result.cache +.vscode diff --git a/src/NXP/Classes/Token/TokenAnd.php b/src/NXP/Classes/Token/TokenAnd.php new file mode 100644 index 0000000..dab4497 --- /dev/null +++ b/src/NXP/Classes/Token/TokenAnd.php @@ -0,0 +1,53 @@ +getValue() && $op2->getValue(); + + return new TokenNumber($result); + } +} diff --git a/src/NXP/Classes/Token/TokenDegree.php b/src/NXP/Classes/Token/TokenDegree.php index 273183a..0d22f91 100644 --- a/src/NXP/Classes/Token/TokenDegree.php +++ b/src/NXP/Classes/Token/TokenDegree.php @@ -30,7 +30,7 @@ class TokenDegree extends AbstractOperator */ public function getPriority() { - return 3; + return 220; } /** diff --git a/src/NXP/Classes/Token/TokenDivision.php b/src/NXP/Classes/Token/TokenDivision.php index 4a8f8ce..328833b 100644 --- a/src/NXP/Classes/Token/TokenDivision.php +++ b/src/NXP/Classes/Token/TokenDivision.php @@ -31,7 +31,7 @@ class TokenDivision extends AbstractOperator */ public function getPriority() { - return 2; + return 180; } /** diff --git a/src/NXP/Classes/Token/TokenEqual.php b/src/NXP/Classes/Token/TokenEqual.php new file mode 100644 index 0000000..b0ac31e --- /dev/null +++ b/src/NXP/Classes/Token/TokenEqual.php @@ -0,0 +1,53 @@ +getValue() == $op2->getValue(); + + return new TokenNumber($result); + } +} diff --git a/src/NXP/Classes/Token/TokenGreaterThan.php b/src/NXP/Classes/Token/TokenGreaterThan.php new file mode 100644 index 0000000..51a5aca --- /dev/null +++ b/src/NXP/Classes/Token/TokenGreaterThan.php @@ -0,0 +1,53 @@ +'; + } + + /** + * @return int + */ + public function getPriority() + { + return 150; + } + + /** + * @return string + */ + public function getAssociation() + { + return self::LEFT_ASSOC; + } + + /** + * @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("> requires two operators"); + } + + $result = $op1->getValue() > $op2->getValue(); + + return new TokenNumber($result); + } +} diff --git a/src/NXP/Classes/Token/TokenGreaterThanOrEqual.php b/src/NXP/Classes/Token/TokenGreaterThanOrEqual.php new file mode 100644 index 0000000..aa4425f --- /dev/null +++ b/src/NXP/Classes/Token/TokenGreaterThanOrEqual.php @@ -0,0 +1,53 @@ +\='; + } + + /** + * @return int + */ + public function getPriority() + { + return 150; + } + + /** + * @return string + */ + public function getAssociation() + { + return self::LEFT_ASSOC; + } + + /** + * @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(">= requires two operators"); + } + + $result = $op1->getValue() >= $op2->getValue(); + + return new TokenNumber($result); + } +} diff --git a/src/NXP/Classes/Token/TokenLessThan.php b/src/NXP/Classes/Token/TokenLessThan.php new file mode 100644 index 0000000..d289028 --- /dev/null +++ b/src/NXP/Classes/Token/TokenLessThan.php @@ -0,0 +1,53 @@ +getValue() < $op2->getValue(); + + return new TokenNumber($result); + } +} diff --git a/src/NXP/Classes/Token/TokenLessThanOrEqual.php b/src/NXP/Classes/Token/TokenLessThanOrEqual.php new file mode 100644 index 0000000..5a2fba3 --- /dev/null +++ b/src/NXP/Classes/Token/TokenLessThanOrEqual.php @@ -0,0 +1,53 @@ +getValue() <= $op2->getValue(); + + return new TokenNumber($result); + } +} diff --git a/src/NXP/Classes/Token/TokenMinus.php b/src/NXP/Classes/Token/TokenMinus.php index ad0b8e5..d8ac079 100644 --- a/src/NXP/Classes/Token/TokenMinus.php +++ b/src/NXP/Classes/Token/TokenMinus.php @@ -30,7 +30,7 @@ class TokenMinus extends AbstractOperator */ public function getPriority() { - return 1; + return 170; } /** diff --git a/src/NXP/Classes/Token/TokenMultiply.php b/src/NXP/Classes/Token/TokenMultiply.php index 0b1ecfb..762fb48 100644 --- a/src/NXP/Classes/Token/TokenMultiply.php +++ b/src/NXP/Classes/Token/TokenMultiply.php @@ -30,7 +30,7 @@ class TokenMultiply extends AbstractOperator */ public function getPriority() { - return 2; + return 180; } /** diff --git a/src/NXP/Classes/Token/TokenOr.php b/src/NXP/Classes/Token/TokenOr.php new file mode 100644 index 0000000..86a4e53 --- /dev/null +++ b/src/NXP/Classes/Token/TokenOr.php @@ -0,0 +1,53 @@ +getValue() || $op2->getValue(); + + return new TokenNumber($result); + } +} diff --git a/src/NXP/Classes/Token/TokenPlus.php b/src/NXP/Classes/Token/TokenPlus.php index a6e5036..494f786 100644 --- a/src/NXP/Classes/Token/TokenPlus.php +++ b/src/NXP/Classes/Token/TokenPlus.php @@ -30,7 +30,7 @@ class TokenPlus extends AbstractOperator */ public function getPriority() { - return 1; + return 170; } /** diff --git a/src/NXP/Classes/Token/TokenUnequal.php b/src/NXP/Classes/Token/TokenUnequal.php new file mode 100644 index 0000000..c8c5d1a --- /dev/null +++ b/src/NXP/Classes/Token/TokenUnequal.php @@ -0,0 +1,53 @@ +getValue() != $op2->getValue(); + + return new TokenNumber($result); + } +} diff --git a/src/NXP/Classes/TokenFactory.php b/src/NXP/Classes/TokenFactory.php index 74b5789..5aa634a 100644 --- a/src/NXP/Classes/TokenFactory.php +++ b/src/NXP/Classes/TokenFactory.php @@ -133,21 +133,21 @@ class TokenFactory { $operatorsRegex = ''; foreach ($this->operators as $operator) { - $operatorsRegex .= $operator::getRegex(); + $operatorsRegex .= '|(' . $operator::getRegex() . ')'; } - - return sprintf( - '/(%s)|(%s)|(%s)|([%s])|(%s)|(%s)|([%s%s%s])/i', + $s = sprintf( + '/(%s)|(%s)|(%s)|(%s)|(%s)|([%s%s%s])', TokenNumber::getRegex(), TokenStringDoubleQuoted::getRegex(), TokenStringSingleQuoted::getRegex(), - $operatorsRegex, TokenFunction::getRegex(), TokenVariable::getRegex(), TokenLeftBracket::getRegex(), TokenRightBracket::getRegex(), TokenComma::getRegex() ); + $s .= $operatorsRegex . '/i'; + return $s; } /** diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php index 6325d35..2a5f9fb 100644 --- a/src/NXP/MathExecutor.php +++ b/src/NXP/MathExecutor.php @@ -223,13 +223,14 @@ class MathExecutor */ public function execute($expression) { - if (!array_key_exists($expression, $this->cache)) { + $cachekey = (string)$expression; + if (!array_key_exists($cachekey, $this->cache)) { $lexer = new Lexer($this->tokenFactory); $tokensStream = $lexer->stringToTokensStream($expression); $tokens = $lexer->buildReversePolishNotation($tokensStream); - $this->cache[$expression] = $tokens; + $this->cache[$cachekey] = $tokens; } else { - $tokens = $this->cache[$expression]; + $tokens = $this->cache[$cachekey]; } $calculator = new Calculator(); $result = $calculator->calculate($tokens, $this->variables); @@ -263,6 +264,14 @@ class MathExecutor 'NXP\Classes\Token\TokenMultiply', 'NXP\Classes\Token\TokenDivision', 'NXP\Classes\Token\TokenDegree', + 'NXP\Classes\Token\TokenAnd', + 'NXP\Classes\Token\TokenOr', + 'NXP\Classes\Token\TokenEqual', + 'NXP\Classes\Token\TokenUnequal', + 'NXP\Classes\Token\TokenGreaterThanOrEqual', + 'NXP\Classes\Token\TokenGreaterThan', + 'NXP\Classes\Token\TokenLessThanOrEqual', + 'NXP\Classes\Token\TokenLessThan', ]; } @@ -296,6 +305,18 @@ class MathExecutor 'avg' => function ($arg1, $arg2) { return ($arg1 + $arg2) / 2; }, + 'if' => function ($expr, $trueval, $falseval) { + if ($expr === true || $expr === false) { + $exres = $expr; + } else { + $exres = $this->execute($expr); + } + if ($exres) { + return $this->execute($trueval); + } else { + return $this->execute($falseval); + } + } ]; } diff --git a/tests/MathTest.php b/tests/MathTest.php index e289016..90cdccf 100644 --- a/tests/MathTest.php +++ b/tests/MathTest.php @@ -50,6 +50,8 @@ class MathTest extends \PHPUnit\Framework\TestCase ['4*-5'], ['4 * -5'], + [cos(2)], + ['0.1 + 0.2'], ['1 + 2'], @@ -63,6 +65,10 @@ class MathTest extends \PHPUnit\Framework\TestCase ['1 / 2'], ['2 * 2 + 3 * 3'], + ['2 * 2 / 3 * 3'], + ['2 / 2 / 3 / 3'], + ['2 / 2 * 3 / 3'], + ['2 / 2 * 3 * 3'], ['1 + 0.6 - 3 * 2 / 50'], @@ -89,6 +95,8 @@ class MathTest extends \PHPUnit\Framework\TestCase ['1 + 2 * 3 / (3 * min(1, 5) * 2 + 1)'], ['1 + 2 * 3 / (3 / min(1, 5) / 2 + 1)'], + ['(1 + 2) * 3 / (3 / min(1, 5) / 2 + 1)'], + ['sin(10) * cos(50) / min(10, 20/2)'], ['sin(10) * cos(50) / min(10, (20/2))'], ['sin(10) * cos(50) / min(10, (max(10,20)/2))'], @@ -110,6 +118,38 @@ class MathTest extends \PHPUnit\Framework\TestCase ['(1+2+3+4- 5)*7/100'], ['( 1 + 2 + 3 + 4 - 5 ) * 7 / 100'], + ['1 && 0'], + ['1 && 0 && 1'], + ['1 || 0'], + ['1 && 0 || 1'], + + ['5 == 3'], + ['5 == 5'], + ['5 != 3'], + ['5 != 5'], + ['5 > 3'], + ['3 > 5'], + ['3 >= 5'], + ['3 >= 3'], + ['3 < 5'], + ['5 < 3'], + ['3 <= 5'], + ['5 <= 5'], + ['10 < 9 || 4 > (2+1)'], + ['10 < 9 || 4 > (2+1) && 5 == 5 || 4 != 6 || 3 >= 4 || 3 <= 7'], + + ['1 + 5 == 3 + 1'], + ['1 + 5 == 5 + 1'], + ['1 + 5 != 3 + 1'], + ['1 + 5 != 5 + 1'], + ['1 + 5 > 3 + 1'], + ['1 + 3 > 5 + 1'], + ['1 + 3 >= 5 + 1'], + ['1 + 3 >= 3 + 1'], + ['1 + 3 < 5 + 1'], + ['1 + 5 < 3 + 1'], + ['1 + 3 <= 5 + 1'], + ['1 + 5 <= 5 + 1'], ]; } @@ -163,6 +203,27 @@ class MathTest extends \PHPUnit\Framework\TestCase $this->assertEquals(round(100/30), $calculator->execute('round(100/30)')); } + public function testFunctionIf() + { + $calculator = new MathExecutor(); + $this->assertEquals(30, $calculator->execute( + 'if(100 > 99, 30, 0)')); + $this->assertEquals(0, $calculator->execute( + 'if(100 < 99, 30, 0)')); + $this->assertEquals(30, $calculator->execute( + 'if(98 < 99 && sin(1) < 1, 30, 0)')); + $this->assertEquals(40, $calculator->execute( + 'if(98 < 99 && sin(1) < 1, max(30, 40), 0)')); + $this->assertEquals(40, $calculator->execute( + 'if(98 < 99 && sin(1) < 1, if(10 > 5, max(30, 40), 1), 0)')); + $this->assertEquals(20, $calculator->execute( + 'if(98 < 99 && sin(1) > 1, if(10 > 5, max(30, 40), 1), if(4 <= 4, 20, 21))')); + $this->assertEquals(cos(2), $calculator->execute( + 'if(98 < 99 && sin(1) >= 1, max(30, 40), cos(2))')); + $this->assertEquals(cos(2), $calculator->execute( + 'if(cos(2), cos(2), 0)')); + } + public function testEvaluateFunctionParameters() { $calculator = new MathExecutor(); -- cgit v1.2.3 -- cgit v1.2.3