Skip to content

Commit

Permalink
Better setVar error message (#70)
Browse files Browse the repository at this point in the history
Additional unit tests
Readme update
  • Loading branch information
phpfui authored Jul 27, 2020
1 parent b38893d commit 44d72cc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 7 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MathExecutor [![Tests](https://github.com/neonxp/MathExecutor/workflows/Tests/badge.svg)](https://github.com/neonxp/MathExecutor/actions?query=workflow%3ATests) [![Latest Packagist release](https://img.shields.io/packagist/v/nxp/math-executor.svg)](https://packagist.org/packages/nxp/math-executor)
# MathExecutor [![Tests](https://github.com/neonxp/MathExecutor/workflows/Tests/badge.svg)](https://github.com/neonxp/MathExecutor/actions?query=workflow%3ATests)

# A simple and extensible math expressions calculator

Expand Down Expand Up @@ -115,6 +115,8 @@ You can think of the **if** function as prototyped like:
function if($condition, $returnIfTrue, $returnIfFalse)
```
## Variables:
Variables can be prefixed with the dollar sign ($) for PHP compatibility, but is not required.

Default variables:

```
Expand All @@ -127,7 +129,7 @@ You can add your own variables to executor:
```php
$executor->setVar('var1', 0.15)->setVar('var2', 0.22);

echo $executor->execute("$var1 + $var2");
echo $executor->execute("$var1 + var2");
```

You can dynamically define variables at run time. If a variable has a high computation cost, but might not be used, then you can define an undefined variable handler. It will only get called when the variable is used, rather than having to always set it initially.
Expand Down
3 changes: 2 additions & 1 deletion src/NXP/MathExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ public function getVar(string $variable)
public function setVar(string $variable, $value) : self
{
if (!is_scalar($value)) {
throw new MathExecutorException("Variable ({$variable}) value must be a scalar type ({gettype($value)})");
$type = gettype($value);
throw new MathExecutorException("Variable ({$variable}) type ({$type}) is not scalar");
}

$this->variables[$variable] = $value;
Expand Down
57 changes: 53 additions & 4 deletions tests/MathTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use NXP\Exception\DivisionByZeroException;
use NXP\Exception\IncorrectExpressionException;
use NXP\Exception\IncorrectNumberOfFunctionParametersException;
use NXP\Exception\MathExecutorException;
use NXP\Exception\UnknownFunctionException;
use NXP\Exception\UnknownVariableException;
use NXP\MathExecutor;
Expand Down Expand Up @@ -332,9 +333,11 @@ public function testVariables()
{
$calculator = new MathExecutor();
$this->assertEquals(3.14159265359, $calculator->execute('$pi'));
$this->assertEquals(3.14159265359, $calculator->execute('pi'));
$this->assertEquals(2.71828182846, $calculator->execute('$e'));
$this->assertEquals(2.71828182846, $calculator->execute('e'));
$calculator->setVars([
'trx_amount' => 100000,
'trx_amount' => 100000.01,
'ten' => 10,
'nine' => 9,
'eight' => 8,
Expand All @@ -347,16 +350,22 @@ public function testVariables()
'one' => 1,
'zero' => 0,
]);
$this->assertEquals(100000, $calculator->execute('$trx_amount'));
$this->assertEquals(100000.01, $calculator->execute('$trx_amount'));
$this->assertEquals(10 - 9, $calculator->execute('$ten - $nine'));
$this->assertEquals(9 - 10, $calculator->execute('$nine - $ten'));
$this->assertEquals(10 + 9, $calculator->execute('$ten + $nine'));
$this->assertEquals(10 * 9, $calculator->execute('$ten * $nine'));
$this->assertEquals(10 / 9, $calculator->execute('$ten / $nine'));
$this->assertEquals(10 / (9 / 5), $calculator->execute('$ten / ($nine / $five)'));

$this->expectException(UnknownVariableException::class);
$this->assertEquals(0.0, $calculator->execute('$unsetVariable'));
// test variables without leading $
$this->assertEquals(100000.01, $calculator->execute('trx_amount'));
$this->assertEquals(10 - 9, $calculator->execute('ten - nine'));
$this->assertEquals(9 - 10, $calculator->execute('nine - ten'));
$this->assertEquals(10 + 9, $calculator->execute('ten + nine'));
$this->assertEquals(10 * 9, $calculator->execute('ten * nine'));
$this->assertEquals(10 / 9, $calculator->execute('ten / nine'));
$this->assertEquals(10 / (9 / 5), $calculator->execute('ten / (nine / five)'));
}

public function testEvaluateFunctionParameters()
Expand Down Expand Up @@ -477,4 +486,44 @@ public function testGetVarsReturnsCount()
$calculator = new MathExecutor();
$this->assertGreaterThan(1, count($calculator->getVars()));
}

public function testUndefinedVarThrowsExecption()
{
$calculator = new MathExecutor();
$this->assertGreaterThan(1, count($calculator->getVars()));
$this->expectException(UnknownVariableException::class);
$calculator->execute('5 * undefined');
}

public function testSetVarsAcceptsAllScalars()
{
$calculator = new MathExecutor();
$calculator->setVar('boolTrue', true);
$calculator->setVar('boolFalse', false);
$calculator->setVar('int', 1);
$calculator->setVar('float', 1.1);
$calculator->setVar('string', 'string');
$this->assertEquals(7, count($calculator->getVars()));
}

public function testSetVarsDoesNoAcceptObject()
{
$calculator = new MathExecutor();
$this->expectException(MathExecutorException::class);
$calculator->setVar('object', $this);
}

public function testSetVarsDoesNotAcceptNull()
{
$calculator = new MathExecutor();
$this->expectException(MathExecutorException::class);
$calculator->setVar('null', null);
}

public function testSetVarsDoesNotAcceptResource()
{
$calculator = new MathExecutor();
$this->expectException(MathExecutorException::class);
$calculator->setVar('resource', tmpfile());
}
}

0 comments on commit 44d72cc

Please sign in to comment.