mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-22 01:58:47 +02:00
enhance nikic evaluators + test with/without nikic lib
This commit is contained in:
@@ -3,7 +3,14 @@
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Scalar;
|
||||
use Exception;
|
||||
|
||||
use function array_merge;
|
||||
|
||||
@@ -30,7 +37,13 @@ class ConstExprEvaluator {
|
||||
/** @var callable|null */
|
||||
private $fallbackEvaluator;
|
||||
|
||||
/**
|
||||
/** @var array $functions_whitelist */
|
||||
private $functions_whitelist;
|
||||
|
||||
/** @var array staticcalls_whitelist */
|
||||
private $staticcalls_whitelist;
|
||||
|
||||
/**
|
||||
* Create a constant expression evaluator.
|
||||
*
|
||||
* The provided fallback evaluator is invoked whenever a subexpression cannot be evaluated. See
|
||||
@@ -44,8 +57,21 @@ class ConstExprEvaluator {
|
||||
"Expression of type {$expr->getType()} cannot be evaluated"
|
||||
);
|
||||
};
|
||||
|
||||
$this->functions_whitelist=[];
|
||||
$this->staticcalls_whitelist=[];
|
||||
}
|
||||
|
||||
public function setFunctionsWhitelist(array $functions_whitelist): void
|
||||
{
|
||||
$this->functions_whitelist = $functions_whitelist;
|
||||
}
|
||||
|
||||
public function setStaticcallsWhitelist(array $staticcalls_whitelist): void
|
||||
{
|
||||
$this->staticcalls_whitelist = $staticcalls_whitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Silently evaluates a constant expression into a PHP value.
|
||||
*
|
||||
@@ -145,6 +171,41 @@ class ConstExprEvaluator {
|
||||
return $this->evaluateConstFetch($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\Isset_) {
|
||||
return $this->evaluateIsset($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\ClassConstFetch) {
|
||||
return $this->evaluateClassConstFetch($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\Cast) {
|
||||
return $this->evaluateCast($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\StaticPropertyFetch) {
|
||||
return $this->evaluateStaticPropertyFetch($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\FuncCall) {
|
||||
return $this->evaluateFuncCall($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\Variable) {
|
||||
return $this->evaluateVariable($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\StaticCall) {
|
||||
return $this->evaluateStaticCall($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\NullsafePropertyFetch||$expr instanceof Expr\PropertyFetch) {
|
||||
return $this->evaluatePropertyFetch($expr);
|
||||
}
|
||||
|
||||
if ($expr instanceof Expr\NullsafeMethodCall||$expr instanceof Expr\MethodCall) {
|
||||
return $this->evaluateMethodCall($expr);
|
||||
}
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
@@ -225,13 +286,253 @@ class ConstExprEvaluator {
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateConstFetch(Expr\ConstFetch $expr) {
|
||||
$name = $expr->name->toLowerString();
|
||||
switch ($name) {
|
||||
case 'null': return null;
|
||||
case 'false': return false;
|
||||
case 'true': return true;
|
||||
}
|
||||
try {
|
||||
$name = $expr->name;
|
||||
if(! is_string($name)){
|
||||
//PHP_VERSION_ID usecase
|
||||
$name = $name->name;
|
||||
}
|
||||
|
||||
if (defined($name)){
|
||||
return constant($name);
|
||||
}
|
||||
} catch(\Throwable $t){}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateIsset(Expr\Isset_ $expr) {
|
||||
try {
|
||||
foreach ($expr->vars as $var){
|
||||
$var = $this->evaluate($var);
|
||||
if (! isset($var)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch(\Throwable $t){
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateClassConstFetch(Expr\ClassConstFetch $expr) {
|
||||
try {
|
||||
$classname = $expr->class->name;
|
||||
$property = $expr->name->name;
|
||||
|
||||
if ('class' === $property){
|
||||
return $classname;
|
||||
}
|
||||
|
||||
if (class_exists($classname)){
|
||||
$class = new \ReflectionClass($classname);
|
||||
if (array_key_exists($property, $class->getConstants())) {
|
||||
$oReflectionConstant = $class->getReflectionConstant($property);
|
||||
if ($oReflectionConstant->isPublic()){
|
||||
return $class->getConstant($property);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(\Throwable $t){}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateCast(Expr\Cast $expr) {
|
||||
try {
|
||||
$subexpr = $this->evaluate($expr->expr);
|
||||
$type = get_class($expr);
|
||||
switch ($type){
|
||||
case Expr\Cast\Array_::class:
|
||||
return (array) $subexpr;
|
||||
|
||||
case Expr\Cast\Bool_::class:
|
||||
return (bool) $subexpr;
|
||||
|
||||
case Expr\Cast\Double::class:
|
||||
switch ($expr->getAttribute("kind")){
|
||||
case Expr\Cast\Double::KIND_DOUBLE:
|
||||
return (double) $subexpr;
|
||||
|
||||
case Expr\Cast\Double::KIND_FLOAT:
|
||||
case Expr\Cast\Double::KIND_REAL:
|
||||
return (float) $subexpr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Expr\Cast\Int_::class:
|
||||
return (int) $subexpr;
|
||||
|
||||
case Expr\Cast\Object_::class:
|
||||
return (object) $subexpr;
|
||||
|
||||
case Expr\Cast\String_::class:
|
||||
return (string) $subexpr;
|
||||
}
|
||||
} catch(\Throwable $t){
|
||||
}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateStaticPropertyFetch(Expr\StaticPropertyFetch $expr)
|
||||
{
|
||||
try {
|
||||
$classname = $expr->class->name;
|
||||
if ($expr->name instanceof Identifier){
|
||||
$property = $expr->name->name;
|
||||
} else {
|
||||
$property = $this->evaluate($expr->name);
|
||||
}
|
||||
|
||||
if (class_exists($classname)){
|
||||
$class = new \ReflectionClass($classname);
|
||||
if (array_key_exists($property, $class->getStaticProperties())) {
|
||||
$oReflectionProperty = $class->getProperty($property);
|
||||
if ($oReflectionProperty->isPublic()){
|
||||
return $class->getStaticPropertyValue($property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateFuncCall(Expr\FuncCall $expr)
|
||||
{
|
||||
try {
|
||||
if ($expr->name instanceof Name){
|
||||
$function = $expr->name->name;
|
||||
} else {
|
||||
$function = $this->evaluate($expr->name);
|
||||
}
|
||||
|
||||
if (! in_array($function, $this->functions_whitelist)){
|
||||
throw new Exception("FuncCall $function not supported");
|
||||
}
|
||||
|
||||
$args=[];
|
||||
foreach ($expr->args as $arg){
|
||||
/** @var \PhpParser\Node\Arg $arg */
|
||||
$args[]=$arg->value->value;
|
||||
}
|
||||
|
||||
$reflection_function = new \ReflectionFunction($function);
|
||||
return $reflection_function->invoke(...$args);
|
||||
}
|
||||
catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateVariable(Expr\Variable $expr)
|
||||
{
|
||||
try {
|
||||
$name = $expr->name;
|
||||
if (! is_null($name) && isset($name)) {
|
||||
global $$name;
|
||||
return $$name;
|
||||
}
|
||||
} catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateStaticCall(Expr\StaticCall $expr)
|
||||
{
|
||||
try {
|
||||
$classname = $expr->class->name;
|
||||
if ($expr->name instanceof Identifier){
|
||||
$methodname = $expr->name->name;
|
||||
} else {
|
||||
$methodname = $this->evaluate($expr->name);
|
||||
}
|
||||
|
||||
$static_call_description = "$classname::$methodname";
|
||||
if (! in_array($static_call_description, $this->staticcalls_whitelist)){
|
||||
throw new Exception("StaticCall $static_call_description not supported");
|
||||
}
|
||||
|
||||
$args=[];
|
||||
foreach ($expr->args as $arg){
|
||||
/** @var \PhpParser\Node\Arg $arg */
|
||||
$args[]=$arg->value->value;
|
||||
}
|
||||
|
||||
$class = new \ReflectionClass($classname);
|
||||
$method = $class->getMethod($methodname);
|
||||
if ($method->isPublic()){
|
||||
return $method->invokeArgs(null, $args);
|
||||
}
|
||||
} catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluatePropertyFetch(Expr\NullsafePropertyFetch|Expr\PropertyFetch $expr)
|
||||
{
|
||||
try {
|
||||
$var = $this->evaluateVariable($expr->var);
|
||||
if (is_null($var)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($expr->name instanceof Identifier){
|
||||
$name = $expr->name->name;
|
||||
} else {
|
||||
$name = $this->evaluate($expr->name);
|
||||
}
|
||||
|
||||
$reflectionClass = new \ReflectionClass(get_class($var));
|
||||
$property = $reflectionClass->getProperty($name);
|
||||
if ($property->isPublic()){
|
||||
return $property->getValue($var);
|
||||
}
|
||||
} catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
/** @return mixed */
|
||||
private function evaluateMethodCall(Expr\MethodCall|Expr\NullsafeMethodCall $expr)
|
||||
{
|
||||
try {
|
||||
$var = $this->evaluateVariable($expr->var);
|
||||
if (is_null($var)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$args=[];
|
||||
foreach ($expr->args as $arg){
|
||||
/** @var \PhpParser\Node\Arg $arg */
|
||||
$args[]=$arg->value->value;
|
||||
}
|
||||
|
||||
if ($expr->name instanceof Identifier){
|
||||
$name = $expr->name->name;
|
||||
} else {
|
||||
$name = $this->evaluate($expr->name);
|
||||
}
|
||||
$reflectionClass = new \ReflectionClass(get_class($var));
|
||||
$method = $reflectionClass->getMethod($name);
|
||||
if ($method->isPublic()){
|
||||
return $method->invokeArgs($var, $args);
|
||||
}
|
||||
} catch (\Throwable $t) {}
|
||||
|
||||
return ($this->fallbackEvaluator)($expr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,23 +12,10 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
|
||||
|
||||
public static function EvaluateExpressionProvider() {
|
||||
return [
|
||||
'ConstFetch: false' => [ 'sExpression' => 'false'],
|
||||
'ConstFetch: (false)' => [ 'sExpression' => 'false'],
|
||||
'ConstFetch: true' => [ 'sExpression' => 'true'],
|
||||
'ConstFetch: (true)' => [ 'sExpression' => 'true'],
|
||||
'ClassConstFetch: public existing constant' => [ 'sExpression' => 'SetupUtils::PHP_MIN_VERSION'],
|
||||
'ClassConstFetch: unknown constant' => [ 'sExpression' => 'SetupUtils::UNKNOWN_CONSTANT'],
|
||||
'ClassConstFetch: unknown class:constant' => [ 'sExpression' => 'GabuZomeuUnknownClass::UNKNOWN_CONSTANT'],
|
||||
'ClassConstFetch: unknown class:class' => [ 'sExpression' => 'GabuZomeuUnknownClass::class'],
|
||||
'ClassConstFetch: private existing constant' => [
|
||||
'sExpression' => 'Combodo\iTop\Test\UnitTest\Setup\ModuleDiscovery\PhpExpressionEvaluatorTest::PRIVATE_CONSTANT',
|
||||
'forced_expected' => null,
|
||||
],
|
||||
'StaticProperty: public existing constant' => [ 'sExpression' => 'Combodo\iTop\Test\UnitTest\Setup\ModuleDiscovery\PhpExpressionEvaluatorTest::$STATIC_PROPERTY'],
|
||||
'StaticProperty: private existing constant' => [
|
||||
'sExpression' => 'Combodo\iTop\Test\UnitTest\Setup\ModuleDiscovery\PhpExpressionEvaluatorTest::$PRIVATE_STATIC_PROPERTY',
|
||||
'forced_expected' => null,
|
||||
],
|
||||
'Array: [1000 => "a"]' => ['sExpression' => '[1000 => "a"]'],
|
||||
'Array: ["a"]' => ['sExpression' => '["a"]'],
|
||||
'Array dict: ["a"=>"b"]' => ['sExpression' => '["a"=>"b"]'],
|
||||
'ArrayDimFetch: $_SERVER[\'toto\']' => ['sExpression' => '$_SERVER[\'toto\']'],
|
||||
'BinaryOperator: false|true' => [ 'sExpression' => 'false|true'],
|
||||
'BinaryOperator: false||true' => [ 'sExpression' => 'false||true'],
|
||||
'BinaryOperator: false&&true' => [ 'sExpression' => 'false&&true'],
|
||||
@@ -41,36 +28,8 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
|
||||
'BinaryOperator: 1 <= 1' => [ 'sExpression' => '1 <= 1'],
|
||||
'BinaryOperator: PHP_VERSION_ID == PHP_VERSION_ID' => [ 'sExpression' => 'PHP_VERSION_ID == PHP_VERSION_ID'],
|
||||
'BinaryOperator: PHP_VERSION_ID != PHP_VERSION_ID' => [ 'sExpression' => 'PHP_VERSION_ID != PHP_VERSION_ID'],
|
||||
'FuncCall: function_exists(\'ldap_connect\')' => [ 'sExpression' => 'function_exists(\'ldap_connect\')'],
|
||||
'FuncCall: function_exists(\'gabuzomeushouldnotexist\')' => [ 'sExpression' => 'function_exists(\'gabuzomeushouldnotexist\')'],
|
||||
'UnaryMinus: -1' => ['sExpression' => '-1'],
|
||||
'UnaryPlus: +1' => ['sExpression' => '+1'],
|
||||
'Concat: "a"."b"' => ['sExpression' => '"a"."b"'],
|
||||
'ArrayDimFetch: $_SERVER[\'toto\']' => ['sExpression' => '$_SERVER[\'toto\']'],
|
||||
//'Variable: $_SERVER' => ['sExpression' => '$_SERVER'],
|
||||
'Variable: $oNonNullVar' => ['sExpression' => '$oNonNullVar'],
|
||||
'Array: [1000 => "a"]' => ['sExpression' => '[1000 => "a"]'],
|
||||
'Array: ["a"]' => ['sExpression' => '["a"]'],
|
||||
'Array dict: ["a"=>"b"]' => ['sExpression' => '["a"=>"b"]'],
|
||||
'StaticCall utils::GetItopVersionWikiSyntax()' => ['sExpression' => 'utils::GetItopVersionWikiSyntax()'],
|
||||
'NullsafePropertyFetch: $oNullVar?->b' => ['sExpression' => '$oNullVar?->b'],
|
||||
'NullsafePropertyFetch: $oEvaluationFakeClass?->bIsOk' => ['sExpression' => '$oEvaluationFakeClass?->bIsOk'],
|
||||
'PropertyFetch: $oEvaluationFakeClass->bIsOk' => ['sExpression' => '$oEvaluationFakeClass->bIsOk'],
|
||||
'NullsafeMethodCall: $oEvaluationFakeClass?->GetName()' => ['sExpression' => '$oEvaluationFakeClass?->GetName()'],
|
||||
'NullsafeMethodCall: $oEvaluationFakeClass?->GetLongName("aa")' => ['sExpression' => '$oEvaluationFakeClass?->GetLongName("aa")'],
|
||||
'MethodCall: $oEvaluationFakeClass->GetName()' => ['sExpression' => '$oEvaluationFakeClass->GetName()'],
|
||||
'MethodCall: $oEvaluationFakeClass->GetLongName("aa")' => ['sExpression' => '$oEvaluationFakeClass->GetLongName("aa")'],
|
||||
'Coalesce: $oNullVar ?? 1' => ['sExpression' => '$oNullVar ?? 1'],
|
||||
'Coalesce: $oNonNullVar ?? 1' => ['sExpression' => '$oNonNullVar ?? 1'],
|
||||
'Isset: isset($a)' => ['sExpression' => 'isset($a)'],
|
||||
'Isset: isset($a, $_SERVER)' => ['sExpression' => 'isset($a, $_SERVER)'],
|
||||
'Isset: isset($_SERVER)' => ['sExpression' => 'isset($_SERVER)'],
|
||||
'Isset: isset($_SERVER, $a)' => ['sExpression' => 'isset($_SERVER, $a)'],
|
||||
'BitwiseNot: ~3' => ['sExpression' => '~3'],
|
||||
'Mod: 3%2' => ['sExpression' => '3%2'],
|
||||
'BitwiseXor: 3^2' => ['sExpression' => '3^2'],
|
||||
'Ternary: (true) ? 1 : 2' => ['sExpression' => '(true) ? 1 : 2'],
|
||||
'Ternary: (false) ? 1 : 2' => ['sExpression' => '(false) ? 1 : 2'],
|
||||
'Cast: (array)3' => ['sExpression' => '(array)3'],
|
||||
'Cast: (bool)1' => ['sExpression' => '(bool)1'],
|
||||
'Cast: (bool)0' => ['sExpression' => '(bool)0'],
|
||||
@@ -78,24 +37,96 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
|
||||
'Cast: (float)3' => ['sExpression' => '(float)3'],
|
||||
'Cast: (int)3' => ['sExpression' => '(int)3'],
|
||||
'Cast: (object)3' => ['sExpression' => '(object)3'],
|
||||
'Cast: (string)$oEvaluationFakeClass' => ['sExpression' => '(string)$oEvaluationFakeClass'],
|
||||
'Cast: (string) $oEvaluationFakeClass' => ['sExpression' => '(string) $oEvaluationFakeClass', "toString"],
|
||||
'ClassConstFetch: public existing constant' => [ 'sExpression' => 'SetupUtils::PHP_MIN_VERSION'],
|
||||
'ClassConstFetch: unknown constant' => [ 'sExpression' => 'SetupUtils::UNKNOWN_CONSTANT'],
|
||||
'ClassConstFetch: unknown class:constant' => [ 'sExpression' => 'GabuZomeuUnknownClass::UNKNOWN_CONSTANT'],
|
||||
'ClassConstFetch: unknown class:class' => [ 'sExpression' => 'GabuZomeuUnknownClass::class'],
|
||||
'ClassConstFetch: private existing constant' => [
|
||||
'sExpression' => 'Combodo\iTop\Test\UnitTest\Setup\ModuleDiscovery\PhpExpressionEvaluatorTest::PRIVATE_CONSTANT',
|
||||
'forced_expected' => null,
|
||||
],
|
||||
'Coalesce: $oNullVar ?? 1' => ['sExpression' => '$oNullVar ?? 1', 1],
|
||||
'Coalesce: $oNonNullVar ?? 1' => ['sExpression' => '$oNonNullVar ?? 1', 1],
|
||||
'Coalesce: $oGlobalNonNullVar ?? 1' => ['sExpression' => '$oGlobalNonNullVar ?? 1', "a"],
|
||||
'Concat: "a"."b"' => ['sExpression' => '"a"."b"'],
|
||||
'ConstFetch: false' => [ 'sExpression' => 'false'],
|
||||
'ConstFetch: (false)' => [ 'sExpression' => 'false'],
|
||||
'ConstFetch: true' => [ 'sExpression' => 'true'],
|
||||
'ConstFetch: (true)' => [ 'sExpression' => 'true'],
|
||||
'FuncCall: function_exists(\'ldap_connect\')' => [ 'sExpression' => 'function_exists(\'ldap_connect\')'],
|
||||
'FuncCall: function_exists(\'gabuzomeushouldnotexist\')' => [ 'sExpression' => 'function_exists(\'gabuzomeushouldnotexist\')'],
|
||||
'Isset: isset($oNonNullVar)' => ['sExpression' => 'isset($oNonNullVar)', false],
|
||||
'Isset: isset($oGlobalNonNullVar)' => ['sExpression' => 'isset($oGlobalNonNullVar)', true],
|
||||
'Isset: isset($a, $_SERVER)' => ['sExpression' => 'isset($a, $_SERVER)', false],
|
||||
'Isset: isset($_SERVER)' => ['sExpression' => 'isset($_SERVER)', true],
|
||||
'Isset: isset($_SERVER, $a)' => ['sExpression' => 'isset($_SERVER, $a)', false],
|
||||
'Isset: isset($oGlobalNonNullVar, $_SERVER)' => ['sExpression' => 'isset($oGlobalNonNullVar, $_SERVER)', true],
|
||||
'MethodCall: $oEvaluationFakeClass->GetName()' => ['sExpression' => '$oEvaluationFakeClass->GetName()', "gabuzomeu"],
|
||||
'MethodCall: $oEvaluationFakeClass->GetLongName("aa")' => ['sExpression' => '$oEvaluationFakeClass->GetLongName("aa")', "gabuzomeu_aa"],
|
||||
'Mod: 3%2' => ['sExpression' => '3%2'],
|
||||
'NullsafeMethodCall: $oNullVar?->GetName()' => ['sExpression' => '$oNullVar?->GetName()', null],
|
||||
'NullsafeMethodCall: $oNullVar?->GetLongName("aa")' => ['sExpression' => '$oNullVar?->GetLongName("aa")', null],
|
||||
'NullsafeMethodCall: $oEvaluationFakeClass?->GetName()' => ['sExpression' => '$oEvaluationFakeClass?->GetName()', "gabuzomeu"],
|
||||
'NullsafeMethodCall: $oEvaluationFakeClass?->GetLongName("aa")' => ['sExpression' => '$oEvaluationFakeClass?->GetLongName("aa")', "gabuzomeu_aa"],
|
||||
'NullsafePropertyFetch: $oNullVar?->b' => ['sExpression' => '$oNullVar?->b', null],
|
||||
'NullsafePropertyFetch: $oEvaluationFakeClass?->iIsOk' => ['sExpression' => '$oEvaluationFakeClass?->iIsOk', "IsOkValue"],
|
||||
'PropertyFetch: $oEvaluationFakeClass->iIsOk' => ['sExpression' => '$oEvaluationFakeClass->iIsOk', "IsOkValue"],
|
||||
'StaticCall utils::GetItopVersionWikiSyntax()' => ['sExpression' => 'utils::GetItopVersionWikiSyntax()'],
|
||||
'StaticProperty: public existing constant' => [ 'sExpression' => 'Combodo\iTop\Test\UnitTest\Sources\PhpParser\Evaluation\PhpExpressionEvaluatorTest::$STATIC_PROPERTY'],
|
||||
'StaticProperty: private existing constant' => [
|
||||
'sExpression' => 'Combodo\iTop\Test\UnitTest\Setup\ModuleDiscovery\PhpExpressionEvaluatorTest::$PRIVATE_STATIC_PROPERTY',
|
||||
'forced_expected' => null,
|
||||
],
|
||||
'Ternary: (true) ? 1 : 2' => ['sExpression' => '(true) ? 1 : 2'],
|
||||
'Ternary: (false) ? 1 : 2' => ['sExpression' => '(false) ? 1 : 2'],
|
||||
'UnaryMinus: -1' => ['sExpression' => '-1'],
|
||||
'UnaryPlus: +1' => ['sExpression' => '+1'],
|
||||
'Variable: $_SERVER' => ['sExpression' => '$_SERVER', ['toto' => 'titi']],
|
||||
'Variable: $oNonNullVar' => ['sExpression' => '$oNonNullVar', null],
|
||||
'Variable: $oGlobalNonNullVar' => ['sExpression' => '$oGlobalNonNullVar', "a"],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider EvaluateExpressionProvider
|
||||
*/
|
||||
public function testEvaluateExpression($sExpression, $forced_expected="NOTPROVIDED")
|
||||
public function testEvaluateExpressionWithItopAlgo($sExpression, $forced_expected="NOTPROVIDED")
|
||||
{
|
||||
$oNullVar=null;
|
||||
$this->evaluateExpressionWithMode($sExpression, $forced_expected, PhpExpressionEvaluator::ITOP_ALGO);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider EvaluateExpressionProvider
|
||||
*/
|
||||
public function testEvaluateExpressionWithLibAndItopFallback($sExpression, $forced_expected="NOTPROVIDED")
|
||||
{
|
||||
$this->evaluateExpressionWithMode($sExpression, $forced_expected, PhpExpressionEvaluator::LIB_AND_FALLBACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider EvaluateExpressionProvider
|
||||
*/
|
||||
public function testEvaluateExpressionWithLibOnly($sExpression, $forced_expected="NOTPROVIDED")
|
||||
{
|
||||
$this->evaluateExpressionWithMode($sExpression, $forced_expected, PhpExpressionEvaluator::LIB_ONLY);
|
||||
}
|
||||
|
||||
public function evaluateExpressionWithMode($sExpression, $forced_expected, $iMode)
|
||||
{
|
||||
global $oGlobalNonNullVar;
|
||||
$oGlobalNonNullVar="a";
|
||||
$oNonNullVar="a";
|
||||
|
||||
$oNullVar=null;
|
||||
$_SERVER=[
|
||||
'toto' => 'titi',
|
||||
];
|
||||
|
||||
global $oEvaluationFakeClass;
|
||||
$oEvaluationFakeClass = new EvaluationFakeClass();
|
||||
|
||||
$res = PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateExpression($sExpression);
|
||||
$res = PhpExpressionEvaluator::GetInstance()->ParseAndEvaluateExpression($sExpression, $iMode);
|
||||
if ($forced_expected === "NOTPROVIDED"){
|
||||
$this->assertEquals($this->UnprotectedComputeExpression($sExpression), $res, $sExpression);
|
||||
} else {
|
||||
@@ -159,7 +190,7 @@ class PhpExpressionEvaluatorTest extends ItopDataTestCase {
|
||||
}
|
||||
|
||||
class EvaluationFakeClass {
|
||||
public bool $bIsOk=true;
|
||||
public string $iIsOk="IsOkValue";
|
||||
|
||||
public function GetName()
|
||||
{
|
||||
@@ -173,6 +204,6 @@ class EvaluationFakeClass {
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return "a";
|
||||
return "toString";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user