mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 09:48:40 +00:00
Fix mapper depth bugs and implement math evaluator
This commit is contained in:
parent
cdfb8894b9
commit
6cc520a579
|
|
@ -402,7 +402,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$query->prefix(self::$db->getPrefix())->into(static::$table);
|
||||
|
||||
foreach (static::$columns as $key => $column) {
|
||||
$propertyName = \stripos($column['internal'], '/') !== false ? explode('/', $column['internal'])[0] : $column['internal'];
|
||||
$propertyName = \stripos($column['internal'], '/') !== false ? \explode('/', $column['internal'])[0] : $column['internal'];
|
||||
if (isset(static::$hasMany[$propertyName]) || isset(static::$hasOne[$propertyName])) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -425,11 +425,11 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$query->insert($column['name'])->value($value, $column['type']);
|
||||
} elseif ($column['name'] !== static::$primaryField) {
|
||||
$tValue = $property->getValue($obj);
|
||||
if (stripos($column['internal'], '/') !== false) {
|
||||
if (\stripos($column['internal'], '/') !== false) {
|
||||
$path = \explode('/', $column['internal']);
|
||||
|
||||
array_shift($path);
|
||||
$path = implode('/', $path);
|
||||
\array_shift($path);
|
||||
$path = \implode('/', $path);
|
||||
$tValue = ArrayUtils::getArray($path, $tValue, '/');
|
||||
}
|
||||
|
||||
|
|
@ -475,11 +475,11 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
}
|
||||
|
||||
$path = $column['internal'];
|
||||
if (stripos($column['internal'], '/') !== false) {
|
||||
if (\stripos($column['internal'], '/') !== false) {
|
||||
$path = \explode('/', $column['internal']);
|
||||
|
||||
array_shift($path);
|
||||
$path = implode('/', $path);
|
||||
\array_shift($path);
|
||||
$path = \implode('/', $path);
|
||||
}
|
||||
|
||||
$property = ArrayUtils::getArray($path, $obj, '/');
|
||||
|
|
@ -602,7 +602,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$relReflectionClass = null;
|
||||
|
||||
foreach ($values as $key => &$value) {
|
||||
if (!is_object($value)) {
|
||||
if (!\is_object($value)) {
|
||||
// Is scalar => already in database
|
||||
$objsIds[$key] = $value;
|
||||
|
||||
|
|
@ -732,7 +732,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*/
|
||||
private static function createOwnsOne(string $propertyName, $obj)
|
||||
{
|
||||
if (is_object($obj)) {
|
||||
if (\is_object($obj)) {
|
||||
$mapper = static::$ownsOne[$propertyName]['mapper'];
|
||||
$primaryKey = $mapper::getObjectId($obj);
|
||||
|
||||
|
|
@ -788,7 +788,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*/
|
||||
private static function createBelongsTo(string $propertyName, $obj)
|
||||
{
|
||||
if (is_object($obj)) {
|
||||
if (\is_object($obj)) {
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$belongsTo[$propertyName]['mapper'];
|
||||
$primaryKey = $mapper::getObjectId($obj);
|
||||
|
|
@ -895,7 +895,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
return $value->serialize();
|
||||
} elseif ($value instanceof \JsonSerializable) {
|
||||
return (string) \json_encode($value->jsonSerialize());
|
||||
} elseif (is_object($value) && method_exists($value, 'getId')) {
|
||||
} elseif (\is_object($value) && method_exists($value, 'getId')) {
|
||||
return $value->getId();
|
||||
}
|
||||
|
||||
|
|
@ -905,9 +905,11 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
/**
|
||||
* Update has many
|
||||
*
|
||||
* @param \ReflectionClass $refClass Reflection class
|
||||
* @param object $obj Object to create
|
||||
* @param mixed $objId Id to set
|
||||
* @param \ReflectionClass $refClass Reflection class
|
||||
* @param object $obj Object to create
|
||||
* @param mixed $objId Id to set
|
||||
* @param int $relations Create all relations as well
|
||||
* @param int $depth Depth of relations to update (default = 1 = none)
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
|
|
@ -915,7 +917,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function updateHasMany(\ReflectionClass $refClass, object $obj, $objId) : void
|
||||
private static function updateHasMany(\ReflectionClass $refClass, object $obj, $objId, int $relations = RelationType::ALL, $depth = 1) : void
|
||||
{
|
||||
$objsIds = [];
|
||||
|
||||
|
|
@ -942,7 +944,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$objsIds[$propertyName] = [];
|
||||
|
||||
foreach ($values as $key => &$value) {
|
||||
if (!is_object($value)) {
|
||||
if (!\is_object($value)) {
|
||||
// Is scalar => already in database
|
||||
$objsIds[$propertyName][$key] = $value;
|
||||
|
||||
|
|
@ -957,7 +959,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
|
||||
// already in db
|
||||
if (!empty($primaryKey)) {
|
||||
$mapper::update($value);
|
||||
$mapper::update($value, $relations, $depth);
|
||||
|
||||
$objsIds[$propertyName][$key] = $value;
|
||||
|
||||
|
|
@ -1056,19 +1058,21 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @param string $propertyName Property name to initialize
|
||||
* @param object $obj Object to update
|
||||
* @param int $relations Create all relations as well
|
||||
* @param int $depth Depth of relations to update (default = 1 = none)
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function updateOwnsOne(string $propertyName, object $obj)
|
||||
private static function updateOwnsOne(string $propertyName, object $obj, int $relations = RelationType::ALL, int $depth = 1)
|
||||
{
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$ownsOne[$propertyName]['mapper'];
|
||||
|
||||
// todo: delete owned one object is not recommended since it can be owned by by something else? or does owns one mean that nothing else can have a relation to this one?
|
||||
|
||||
return $mapper::update($obj);
|
||||
return $mapper::update($obj, $relations, $depth);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1078,18 +1082,20 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @param string $propertyName Property name to initialize
|
||||
* @param mixed $obj Object to update
|
||||
* @param int $relations Create all relations as well
|
||||
* @param int $depth Depth of relations to update (default = 1 = none)
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function updateBelongsTo(string $propertyName, $obj)
|
||||
private static function updateBelongsTo(string $propertyName, $obj, int $relations = RelationType::ALL, int $depth = 1)
|
||||
{
|
||||
if (is_object($obj)) {
|
||||
if (\is_object($obj)) {
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$belongsTo[$propertyName]['mapper'];
|
||||
|
||||
return $mapper::update($obj);
|
||||
return $mapper::update($obj, $relations, $depth);
|
||||
}
|
||||
|
||||
return $obj;
|
||||
|
|
@ -1098,15 +1104,17 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
/**
|
||||
* Update object in db.
|
||||
*
|
||||
* @param object $obj Model to update
|
||||
* @param mixed $objId Model id
|
||||
* @param \ReflectionClass $refClass Reflection class
|
||||
* @param object $obj Model to update
|
||||
* @param mixed $objId Model id
|
||||
* @param \ReflectionClass $refClass Reflection class
|
||||
* @param int $relations Create all relations as well
|
||||
* @param int $depth Depth of relations to update (default = 1 = none)
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function updateModel(object $obj, $objId, \ReflectionClass $refClass = null) : void
|
||||
private static function updateModel(object $obj, $objId, \ReflectionClass $refClass = null, int $relations = RelationType::ALL, int $depth = 1) : void
|
||||
{
|
||||
$query = new Builder(self::$db);
|
||||
$query->prefix(self::$db->getPrefix())
|
||||
|
|
@ -1114,7 +1122,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
->where(static::$table . '.' . static::$primaryField, '=', $objId);
|
||||
|
||||
foreach (static::$columns as $key => $column) {
|
||||
$propertyName = \stripos($column['internal'], '/') !== false ? explode('/', $column['internal'])[0] : $column['internal'];
|
||||
$propertyName = \stripos($column['internal'], '/') !== false ? \explode('/', $column['internal'])[0] : $column['internal'];
|
||||
if (isset(static::$hasMany[$propertyName])
|
||||
|| isset(static::$hasOne[$propertyName])
|
||||
|| $column['internal'] === static::$primaryField
|
||||
|
|
@ -1130,24 +1138,24 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
}
|
||||
|
||||
if (isset(static::$ownsOne[$propertyName])) {
|
||||
$id = self::updateOwnsOne($propertyName, $property->getValue($obj));
|
||||
$id = self::updateOwnsOne($propertyName, $property->getValue($obj), $relations, $depth);
|
||||
$value = self::parseValue($column['type'], $id);
|
||||
|
||||
// todo: should not be done if the id didn't change. but for now don't know if id changed
|
||||
$query->set([static::$table . '.' . $column['name'] => $value], $column['type']);
|
||||
} elseif (isset(static::$belongsTo[$propertyName])) {
|
||||
$id = self::updateBelongsTo($propertyName, $property->getValue($obj));
|
||||
$id = self::updateBelongsTo($propertyName, $property->getValue($obj), $relations, $depth);
|
||||
$value = self::parseValue($column['type'], $id);
|
||||
|
||||
// todo: should not be done if the id didn't change. but for now don't know if id changed
|
||||
$query->set([static::$table . '.' . $column['name'] => $value], $column['type']);
|
||||
} elseif ($column['name'] !== static::$primaryField) {
|
||||
$tValue = $property->getValue($obj);
|
||||
if (stripos($column['internal'], '/') !== false) {
|
||||
if (\stripos($column['internal'], '/') !== false) {
|
||||
$path = \explode('/', $column['internal']);
|
||||
|
||||
array_shift($path);
|
||||
$path = implode('/', $path);
|
||||
\array_shift($path);
|
||||
$path = \implode('/', $path);
|
||||
$tValue = ArrayUtils::getArray($path, $tValue, '/');
|
||||
}
|
||||
$value = self::parseValue($column['type'], $tValue);
|
||||
|
|
@ -1168,12 +1176,13 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*
|
||||
* @param mixed $obj Object reference (gets filled with insert id)
|
||||
* @param int $relations Create all relations as well
|
||||
* @param int $depth Depth of relations to update (default = 1 = none)
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function update($obj, int $relations = RelationType::ALL)
|
||||
public static function update($obj, int $relations = RelationType::ALL, int $depth = 1)
|
||||
{
|
||||
self::extend(__CLASS__);
|
||||
|
||||
|
|
@ -1185,8 +1194,11 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$objId = self::getObjectId($obj, $refClass);
|
||||
$update = true;
|
||||
|
||||
// todo: maybe don't remove obj and just update cache... ? since it might have to be loaded again
|
||||
self::removeInitialized(static::class, $objId);
|
||||
if ($depth < 1) {
|
||||
return $objId;
|
||||
}
|
||||
|
||||
self::addInitialized(static::class, $objId, $obj);
|
||||
|
||||
if (empty($objId)) {
|
||||
$update = false;
|
||||
|
|
@ -1194,11 +1206,11 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
}
|
||||
|
||||
if ($relations === RelationType::ALL) {
|
||||
self::updateHasMany($refClass, $obj, $objId);
|
||||
self::updateHasMany($refClass, $obj, $objId, --$depth);
|
||||
}
|
||||
|
||||
if ($update) {
|
||||
self::updateModel($obj, $objId, $refClass);
|
||||
self::updateModel($obj, $objId, $refClass, --$depth);
|
||||
}
|
||||
|
||||
return $objId;
|
||||
|
|
@ -1243,7 +1255,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$relReflectionClass = null;
|
||||
|
||||
foreach ($values as $key => &$value) {
|
||||
if (!is_object($value)) {
|
||||
if (!\is_object($value)) {
|
||||
// Is scalar => already in database
|
||||
$objsIds[$key] = $value;
|
||||
|
||||
|
|
@ -1289,7 +1301,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*/
|
||||
private static function deleteOwnsOne(string $propertyName, $obj)
|
||||
{
|
||||
if (is_object($obj)) {
|
||||
if (\is_object($obj)) {
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$ownsOne[$propertyName]['mapper'];
|
||||
|
||||
|
|
@ -1314,7 +1326,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
*/
|
||||
private static function deleteBelongsTo(string $propertyName, $obj)
|
||||
{
|
||||
if (is_object($obj)) {
|
||||
if (\is_object($obj)) {
|
||||
/** @var string $mapper */
|
||||
$mapper = static::$belongsTo[$propertyName]['mapper'];
|
||||
|
||||
|
|
@ -1484,7 +1496,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$parts = \explode('\\', $class);
|
||||
$name = $parts[$c = (count($parts) - 1)];
|
||||
$parts[$c] = 'Null' . $name;
|
||||
$class = implode('\\', $parts);
|
||||
$class = \implode('\\', $parts);
|
||||
}
|
||||
|
||||
if (!isset($obj)) {
|
||||
|
|
@ -1777,7 +1789,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$aValue = [];
|
||||
$arrayPath = '';
|
||||
|
||||
if (stripos(static::$columns[$column]['internal'], '/') !== false) {
|
||||
if (\stripos(static::$columns[$column]['internal'], '/') !== false) {
|
||||
$hasPath = true;
|
||||
$path = \explode('/', static::$columns[$column]['internal']);
|
||||
$refProp = $refClass->getProperty($path[0]);
|
||||
|
|
@ -1786,8 +1798,8 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$refProp->setAccessible(true);
|
||||
}
|
||||
|
||||
array_shift($path);
|
||||
$arrayPath = implode('/', $path);
|
||||
\array_shift($path);
|
||||
$arrayPath = \implode('/', $path);
|
||||
$aValue = $refProp->getValue($obj);
|
||||
} else {
|
||||
$refProp = $refClass->getProperty(static::$columns[$column]['internal']);
|
||||
|
|
@ -1851,11 +1863,11 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
foreach ($result as $column => $value) {
|
||||
if (isset(static::$columns[$column]['internal'])) {
|
||||
$path = static::$columns[$column]['internal'];
|
||||
if (stripos($path, '/') !== false) {
|
||||
if (\stripos($path, '/') !== false) {
|
||||
$path = \explode('/', $path);
|
||||
|
||||
array_shift($path);
|
||||
$path = implode('/', $path);
|
||||
\array_shift($path);
|
||||
$path = \implode('/', $path);
|
||||
}
|
||||
|
||||
if (\in_array(static::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) {
|
||||
|
|
@ -1953,7 +1965,7 @@ class DataMapperAbstract implements DataMapperInterface
|
|||
$parts = \explode('\\', $class);
|
||||
$name = $parts[$c = (count($parts) - 1)];
|
||||
$parts[$c] = 'Null' . $name;
|
||||
$class = implode('\\', $parts);
|
||||
$class = \implode('\\', $parts);
|
||||
|
||||
return new $class();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ final class L11nManager
|
|||
public function loadLanguageFromFile(string $language, string $from, string $file) : void
|
||||
{
|
||||
$lang = [];
|
||||
if (file_exists($file)) {
|
||||
if (\file_exists($file)) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$lang = include $file;
|
||||
}
|
||||
|
|
@ -184,6 +184,6 @@ final class L11nManager
|
|||
*/
|
||||
public function getHtml(string $code, string $module, string $theme, $translation) : string
|
||||
{
|
||||
return htmlspecialchars($this->getText($code, $module, $theme, $translation));
|
||||
return \htmlspecialchars($this->getText($code, $module, $theme, $translation));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ declare(strict_types=1);
|
|||
namespace phpOMS\Math\Parser;
|
||||
|
||||
/**
|
||||
* Shape interface.
|
||||
* Basic math function evaluation.
|
||||
*
|
||||
* @package Framework
|
||||
* @license OMS License 1.0
|
||||
|
|
@ -27,10 +27,7 @@ class Evaluator
|
|||
/**
|
||||
* Evaluate function.
|
||||
*
|
||||
* Example: ('2*x^3-4x', ['x' => 99])
|
||||
*
|
||||
* @param string $formula Formula to differentiate
|
||||
* @param array $vars Variables to evaluate
|
||||
* @param string $equation Formula to evaluate
|
||||
*
|
||||
* @return float
|
||||
*
|
||||
|
|
@ -38,18 +35,118 @@ class Evaluator
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function evaluate(string $formula, array $vars) : float
|
||||
public static function evaluate(string $equation) : ?float
|
||||
{
|
||||
// todo: do i need array_values here?
|
||||
$formula = \str_replace(array_keys($vars), array_values($vars), $formula);
|
||||
|
||||
// todo: this is horrible in case things like mod etc. need to be supported
|
||||
if (\preg_match('#[^0-9\+\-\*\/\(\)]#', $formula)) {
|
||||
throw new \Exception('Bad elements');
|
||||
if (\preg_match('#[^0-9\+\-\*\/\(\)\ \^\.]#', $equation)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// todo: create parser
|
||||
$stack = [];
|
||||
$postfix = self::shuntingYard($equation);
|
||||
|
||||
return 0;
|
||||
foreach ($postfix as $i => $value) {
|
||||
if (\is_numeric($value)) {
|
||||
$stack[] = $value;
|
||||
} else {
|
||||
$a = self::parseValue(\array_pop($stack));
|
||||
$b = self::parseValue(\array_pop($stack));
|
||||
|
||||
if ($value === '+') {
|
||||
$stack[] = $a + $b;
|
||||
} elseif ($value === '-') {
|
||||
$stack[] = $b - $a;
|
||||
} elseif ($value === '*') {
|
||||
$stack[] = $a * $b;
|
||||
} elseif ($value === '/') {
|
||||
$stack[] = $b / $a;
|
||||
} elseif ($value === '^') {
|
||||
$stack[] = $b ** $a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = \array_pop($stack);
|
||||
|
||||
return \is_numeric($result) ? (float) $result : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse value.
|
||||
*
|
||||
* @param mixed $value Value to parse
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function parseValue($value)
|
||||
{
|
||||
return !\is_string($value) ? $value : (\stripos($value, '.') === false ? (int) $value : (float) $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shunting Yard algorithm.
|
||||
*
|
||||
* @param string $equation Equation to convert
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private static function shuntingYard(string $equation) : array
|
||||
{
|
||||
$stack = [];
|
||||
$operators = [
|
||||
'^' => ['precedence' => 4, 'order' => 1],
|
||||
'*' => ['precedence' => 3, 'order' => -1],
|
||||
'/' => ['precedence' => 3, 'order' => -1],
|
||||
'+' => ['precedence' => 2, 'order' => -1],
|
||||
'-' => ['precedence' => 2, 'order' => -1],
|
||||
];
|
||||
$output = [];
|
||||
|
||||
$equation = \str_replace(' ', '', $equation);
|
||||
$equation = \preg_split('/([\+\-\*\/\^\(\)])/', $equation, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
if ($equation === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$equation = \array_filter($equation, function($n) {
|
||||
return $n !== '';
|
||||
});
|
||||
|
||||
foreach ($equation as $i => $token) {
|
||||
if (\is_numeric($token)) {
|
||||
$output[] = $token;
|
||||
} elseif (\strpbrk($token, '^*/+-') !== false) {
|
||||
$o1 = $token;
|
||||
$o2 = end($stack);
|
||||
|
||||
while ($o2 !== false && \strpbrk($o2, '^*/+-') !== false
|
||||
&& (($operators[$o1]['order'] === -1 && $operators[$o1]['precedence'] <= $operators[$o2]['precedence'])
|
||||
|| ($operators[$o1]['order'] === 1 && $operators[$o1]['precedence'] < $operators[$o2]['precedence']))
|
||||
) {
|
||||
$output[] = \array_pop($stack);
|
||||
$o2 = end($stack);
|
||||
}
|
||||
|
||||
$stack[] = $o1;
|
||||
} elseif ($token === '(') {
|
||||
$stack[] = $token;
|
||||
} elseif ($token === ')') {
|
||||
while (end($stack) !== '(') {
|
||||
$output[] = \array_pop($stack);
|
||||
}
|
||||
|
||||
\array_pop($stack);
|
||||
}
|
||||
}
|
||||
|
||||
while (count($stack) > 0) {
|
||||
$output[] = \array_pop($stack);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ abstract class ModuleAbstract
|
|||
$lang = [];
|
||||
if (file_exists($oldPath = __DIR__ . '/../../Modules/' . static::MODULE_NAME . '/Theme/' . $destination . '/Lang/' . $language . '.lang.php')) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$lang = include $oldPath;
|
||||
return include $oldPath;
|
||||
}
|
||||
|
||||
return $lang;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,11 @@ use phpOMS\Math\Parser\Evaluator;
|
|||
|
||||
class EvaluatorTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testPlaceholder()
|
||||
public function testBasicEvaluation()
|
||||
{
|
||||
self::markTestIncomplete();
|
||||
self::assertEquals(4.5, Evaluator::evaluate('3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3 + 1.5'), '', 2);
|
||||
self::assertEquals(4.5, Evaluator::evaluate('3+4*2/(1-5)^2^3+1.5'), '', 2);
|
||||
self::assertEquals(null, Evaluator::evaluate('invalid'));
|
||||
self::assertEquals(null, Evaluator::evaluate('3+4*2/(1-5^2^3+1.5'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user