Exemple #1
0
 public function testSimpleEngine()
 {
     $this->expectOutputString(implode(PHP_EOL, ['Rule 1 (Red Products) triggered for Red Bricks.', 'Rule 5 (Toys) triggered for Red Bricks.', 'Rule 3 (Green Socks) triggered for Green Soft Socks.', 'Rule 4 (Socks) triggered for Green Soft Socks.', 'Rule 6 (Clothes) triggered for Green Soft Socks.', 'Rule 4 (Socks) triggered for Yellow Sporty Socks.', 'Rule 6 (Clothes) triggered for Yellow Sporty Socks.', 'Rule 5 (Toys) triggered for Lego Blocks.', 'Rule 6 (Clothes) triggered for Black Adidas Jacket.']) . PHP_EOL);
     $exceptions = new Exception\ExceptionCollectorHandler();
     $engine = new Engine($exceptions);
     $action = new Action\PrintAction();
     foreach ($this->getProducts() as $product) {
         $context = new Context\ProductContext($product);
         $engine->execute($context, $this->getRules(), $action);
     }
     $this->assertSame('', implode(PHP_EOL, $exceptions->getExceptions()), 'RuleEngine should not generate errors.');
 }
Exemple #2
0
 public function testRuleEngineSometimesFaultyAction()
 {
     $productData = ['Product 1' => [], 'Product 2' => [], 'Product 3' => []];
     $rules = [new GenericRule(1, 'Always triggered', 'true')];
     $expectedRules = ['Product 1' => ['Always triggered'], 'Product 2' => [], 'Product 3' => ['Always triggered']];
     $expectedExceptions = ['Exception encountered while executing action ' . CallbackAction::class . ' for rule 1 (Always triggered) within ' . DynamicContext::class . ': Exception thrown for Product 2.'];
     $matchingRules = array_fill_keys(array_keys($productData), []);
     $exceptionHandler = new Exception\ExceptionCollectorHandler();
     $engine = new Engine($exceptionHandler);
     foreach ($productData as $productName => $productValues) {
         $action = new CallbackAction(function ($eval, $context, RuleInterface $rule) use($productName, &$matchingRules) {
             if ($productName == 'Product 2') {
                 throw new \Exception("Exception thrown for {$productName}.");
             }
             $matchingRules[$productName][] = $rule->getName();
         });
         $engine->execute($this->getContext($productValues), $rules, $action);
     }
     $this->assertEquals($expectedRules, $matchingRules);
     $errorMesgs = array_map(function (\Exception $exception) {
         return $exception->getMessage();
     }, $exceptionHandler->getExceptions());
     $this->assertEquals($expectedExceptions, $errorMesgs, 'Engine exceptions were not as expected.');
 }
Exemple #3
0
// Provide code compiled from rule conditions
$output_generated = '';
$eval = new Rune\Util\SymfonyEvaluator();
$maxLength = 0;
foreach ($rules as $rule) {
    $maxLength = max($maxLength, strlen($rule->getName()));
}
foreach ($rules as $rule) {
    try {
        $eval->setFunctions($descriptor->getFunctions());
        $eval->setVariables($descriptor->getVariables());
        $code = $eval->compile($rule->getCondition());
    } catch (\Exception $ex) {
        $code = 'Compile Error (' . get_class($ex) . '): ' . $ex->getMessage();
    }
    $output_generated .= str_pad($rule->getName(), $maxLength) . ' => ' . $code . PHP_EOL;
}
// Provide triggered rules and any generated errors
ob_start();
foreach ($products as $product) {
    $context = new Context\ProductContext($product);
    $engine->execute($context, $rules, $action);
}
$output_result = htmlspecialchars(ob_get_clean(), ENT_QUOTES);
$output_errors = implode(PHP_EOL, $exceptionHandler->getExceptions());
// Provide some details use for dynamic editor
$json_tokens = json_encode(['constants' => [['name' => 'true', 'type' => 'boolean'], ['name' => 'false', 'type' => 'boolean'], ['name' => 'null', 'type' => 'null']], 'operators' => ['+', '-', '*', '/', '%', '**', '&', '|', '^', '==', '===', '!=', '!==', '<', '>', '<=', '>=', 'matches', 'not', '!', 'and', '&&', 'or', '||', '~', 'in', 'not in', '..', '?', '?:', ':'], 'variables' => array_values($descriptor->getVariableTypeInfo()), 'functions' => array_values($descriptor->getFunctionTypeInfo()), 'typeinfo' => $descriptor->getDetailedTypeInfo()]);
$json_categories = json_encode($data['categories']);
$json_products = json_encode($data['products']);
$json_rules = json_encode($data['rules']);
require_once 'view.php';