Adding varExists method and support for undefined var handler in getVar (#96)

* Added varExists method

* getVar now respects VarNotFoundHandler setting

* Use local version of PHP-CS-Fixer

Instead of hard coded version from github actions

* Fixing actions

* Fixing actions

* Dropping testing for 7.3, as it is no longer supported
This commit is contained in:
Bruce Wells 2022-03-21 12:52:25 -04:00 committed by GitHub
parent 6ebe4849ff
commit a0ff7a79af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 79 additions and 51 deletions

View file

@ -8,7 +8,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php: [8.1, 8.0, 7.4, 7.3]
php: [8.1, 8.0, 7.4]
dependency-version: [prefer-lowest, prefer-stable]
os: [ubuntu-latest, windows-latest]
@ -34,7 +34,7 @@ jobs:
run: vendor/bin/phpunit
- name: PHP CS Fixer
uses: StephaneBour/actions-php-cs-fixer@1.0
if: matrix.os != 'windows-latest'
with:
dir: './src'
run: |
vendor/bin/php-cs-fixer fix --dry-run -v ./src
vendor/bin/php-cs-fixer fix --dry-run -v ./tests

2
.gitignore vendored
View file

@ -3,3 +3,5 @@ vendor/
composer.lock
.phpunit.result.cache
.vscode
.php-cs-fixer.cache

View file

@ -31,7 +31,8 @@
"php": ">=7.3"
},
"require-dev": {
"phpunit/phpunit": ">=9.0"
"phpunit/phpunit": ">=9.0",
"friendsofphp/php-cs-fixer": "^3.8"
},
"autoload": {
"psr-4": {

View file

@ -1,6 +1,5 @@
<?php
namespace NXP\Classes;
use NXP\Exception\IncorrectNumberOfFunctionParametersException;
@ -49,7 +48,7 @@ class CustomFunction
*
* @throws IncorrectNumberOfFunctionParametersException
*/
public function execute(array &$stack) : Token
public function execute(array &$stack): Token
{
if (count($stack) < $this->places) {
throw new IncorrectNumberOfFunctionParametersException($this->name);

View file

@ -1,6 +1,5 @@
<?php
namespace NXP\Classes;
use NXP\Exception\IncorrectExpressionException;
@ -55,7 +54,7 @@ class Operator
*
* @throws IncorrectExpressionException
*/
public function execute(array &$stack) : Token
public function execute(array &$stack): Token
{
if (count($stack) < $this->places) {
throw new IncorrectExpressionException();

View file

@ -1,6 +1,5 @@
<?php
namespace NXP\Classes;
class Token

View file

@ -66,7 +66,7 @@ class Tokenizer
$this->operators = $operators;
}
public function tokenize() : self
public function tokenize(): self
{
foreach (str_split($this->input, 1) as $ch) {
switch (true) {
@ -184,17 +184,17 @@ class Tokenizer
return $this;
}
private function isNumber(string $ch) : bool
private function isNumber(string $ch): bool
{
return $ch >= '0' && $ch <= '9';
}
private function isAlpha(string $ch) : bool
private function isAlpha(string $ch): bool
{
return $ch >= 'a' && $ch <= 'z' || $ch >= 'A' && $ch <= 'Z' || $ch == '_';
}
private function emptyNumberBufferAsLiteral() : void
private function emptyNumberBufferAsLiteral(): void
{
if (strlen($this->numberBuffer)) {
$this->tokens[] = new Token(Token::Literal, $this->numberBuffer);
@ -202,22 +202,22 @@ class Tokenizer
}
}
private function isDot(string $ch) : bool
private function isDot(string $ch): bool
{
return $ch == '.';
}
private function isLP(string $ch) : bool
private function isLP(string $ch): bool
{
return $ch == '(';
}
private function isRP(string $ch) : bool
private function isRP(string $ch): bool
{
return $ch == ')';
}
private function emptyStrBufferAsVariable() : void
private function emptyStrBufferAsVariable(): void
{
if ($this->stringBuffer != '') {
$this->tokens[] = new Token(Token::Variable, $this->stringBuffer);
@ -225,7 +225,7 @@ class Tokenizer
}
}
private function isComma(string $ch) : bool
private function isComma(string $ch): bool
{
return $ch == ',';
}
@ -235,7 +235,7 @@ class Tokenizer
* @throws IncorrectBracketsException
* @throws UnknownOperatorException
*/
public function buildReversePolishNotation() : array
public function buildReversePolishNotation(): array
{
$tokens = [];
/** @var SplStack<Token> $stack */

View file

@ -65,7 +65,7 @@ class MathExecutor
* Set default operands and functions
* @throws ReflectionException
*/
protected function addDefaults() : void
protected function addDefaults(): void
{
foreach ($this->defaultOperators() as $name => $operator) {
[$callable, $priority, $isRightAssoc] = $operator;
@ -82,7 +82,7 @@ class MathExecutor
*
* @return array<string, array{callable, int, bool}>
*/
protected function defaultOperators() : array
protected function defaultOperators(): array
{
return [
'+' => [
@ -210,7 +210,7 @@ class MathExecutor
* @param Operator $operator
* @return MathExecutor
*/
public function addOperator(Operator $operator) : self
public function addOperator(Operator $operator): self
{
$this->operators[$operator->operator] = $operator;
return $this;
@ -222,7 +222,7 @@ class MathExecutor
*
* @return array<callable>
*/
protected function defaultFunctions() : array
protected function defaultFunctions(): array
{
return [
'abs' => function ($arg) {
@ -459,7 +459,7 @@ class MathExecutor
* @return MathExecutor
* @throws ReflectionException
*/
public function addFunction(string $name, ?callable $function = null, ?int $places = null) : self
public function addFunction(string $name, ?callable $function = null, ?int $places = null): self
{
$this->functions[$name] = new CustomFunction($name, $function, $places);
return $this;
@ -470,7 +470,7 @@ class MathExecutor
*
* @return array<string, float>
*/
protected function defaultVars() : array
protected function defaultVars(): array
{
return [
'pi' => 3.14159265359,
@ -483,7 +483,7 @@ class MathExecutor
*
* @return array<string, float|string>
*/
public function getVars() : array
public function getVars(): array
{
return $this->variables;
}
@ -493,11 +493,14 @@ class MathExecutor
*
* @param string $variable
* @return integer|float
* @throws UnknownVariableException
* @throws UnknownVariableException if VarNotFoundHandler is not set
*/
public function getVar(string $variable)
{
if (!array_key_exists($variable, $this->variables)) {
if ($this->onVarNotFound) {
return call_user_func($this->onVarNotFound, $variable);
}
throw new UnknownVariableException("Variable ({$variable}) not set");
}
return $this->variables[$variable];
@ -510,7 +513,7 @@ class MathExecutor
* @param int|float $value
* @return MathExecutor
*/
public function setVar(string $variable, $value) : self
public function setVar(string $variable, $value): self
{
if (!is_scalar($value) && $value !== null) {
$type = gettype($value);
@ -521,6 +524,16 @@ class MathExecutor
return $this;
}
/**
* Test to see if a variable exists
*
* @param string $variable
*/
public function varExists(string $variable): bool
{
return array_key_exists($variable, $this->variables);
}
/**
* Add variables to executor
*
@ -529,7 +542,7 @@ class MathExecutor
* @return MathExecutor
* @throws \Exception
*/
public function setVars(array $variables, bool $clear = true) : self
public function setVars(array $variables, bool $clear = true): self
{
if ($clear) {
$this->removeVars();
@ -560,7 +573,7 @@ class MathExecutor
* @param string $variable
* @return MathExecutor
*/
public function removeVar(string $variable) : self
public function removeVar(string $variable): self
{
unset($this->variables[$variable]);
return $this;
@ -570,7 +583,7 @@ class MathExecutor
* Remove all variables and the variable not found handler
* @return MathExecutor
*/
public function removeVars() : self
public function removeVars(): self
{
$this->variables = [];
$this->onVarNotFound = null;
@ -593,7 +606,7 @@ class MathExecutor
* @return array<string, CustomFunction> containing callback and places indexed by
* function name
*/
public function getFunctions() : array
public function getFunctions(): array
{
return $this->functions;
}
@ -603,7 +616,7 @@ class MathExecutor
*
* @return MathExecutor
*/
public function setDivisionByZeroIsZero() : self
public function setDivisionByZeroIsZero(): self
{
$this->addOperator(new Operator("/", false, 180, function ($a, $b) {
if ($b == 0) {
@ -618,7 +631,7 @@ class MathExecutor
* Get cache array with tokens
* @return array<string, Token[]>
*/
public function getCache() : array
public function getCache(): array
{
return $this->cache;
}
@ -626,7 +639,7 @@ class MathExecutor
/**
* Clear token's cache
*/
public function clearCache() : void
public function clearCache(): void
{
$this->cache = [];
}

View file

@ -499,6 +499,15 @@ class MathTest extends TestCase
}
);
$this->assertEquals(15, $calculator->execute('5 * undefined'));
$this->assertEquals(3, $calculator->getVar('undefined'));
$this->assertNull($calculator->getVar('Lucy'));
}
public function testGetVarException()
{
$calculator = new MathExecutor();
$this->expectException(UnknownVariableException::class);
$this->assertNull($calculator->getVar('Lucy'));
}
public function testMinusZero()
@ -580,6 +589,15 @@ class MathTest extends TestCase
$calculator->setVar('resource', tmpfile());
}
public function testVarExists()
{
$calculator = new MathExecutor();
$varName = 'Eythel';
$calculator->setVar($varName, 1);
$this->assertTrue($calculator->varExists($varName));
$this->assertFalse($calculator->varExists('Lucy'));
}
/**
* @dataProvider providerExpressionValues
*/
@ -662,8 +680,5 @@ class MathTest extends TestCase
$this->assertEquals(2048, $calculator->execute('2 ^ 11', false));
$this->assertEquals(0, count($calculator->getCache()));
}
}