Skip to content

Commit

Permalink
Fixed evaluation of short circuit operators
Browse files Browse the repository at this point in the history
  • Loading branch information
florianv authored and fabpot committed Feb 27, 2014
1 parent 81e27d2 commit 3a46a8e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
12 changes: 9 additions & 3 deletions src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php
Expand Up @@ -83,9 +83,10 @@ public function evaluate($functions, $values)
{
$operator = $this->attributes['operator'];
$left = $this->nodes['left']->evaluate($functions, $values);
$right = $this->nodes['right']->evaluate($functions, $values);

if (isset(self::$functions[$operator])) {
$right = $this->nodes['right']->evaluate($functions, $values);

if ('not in' == $operator) {
return !call_user_func('in_array', $left, $right);
}
Expand All @@ -96,10 +97,15 @@ public function evaluate($functions, $values)
switch ($operator) {
case 'or':
case '||':
return $left || $right;
return $left || $this->nodes['right']->evaluate($functions, $values);
case 'and':
case '&&':
return $left && $right;
return $left && $this->nodes['right']->evaluate($functions, $values);
}

$right = $this->nodes['right']->evaluate($functions, $values);

switch ($operator) {
case '|':
return $left | $right;
case '^':
Expand Down
Expand Up @@ -12,7 +12,6 @@
namespace Symfony\Component\ExpressionLanguage\Tests;

use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ParsedExpression;

class ExpressionLanguageTest extends \PHPUnit_Framework_TestCase
{
Expand Down Expand Up @@ -54,4 +53,47 @@ public function testConstantFunction()
$expressionLanguage = new ExpressionLanguage();
$this->assertEquals('constant("PHP_VERSION")', $expressionLanguage->compile('constant("PHP_VERSION")'));
}

/**
* @dataProvider shortCircuitProviderEvaluate
*/
public function testShortCircuitOperatorsEvaluate($expression, array $values, $expected)
{
$expressionLanguage = new ExpressionLanguage();
$this->assertEquals($expected, $expressionLanguage->evaluate($expression, $values));
}

/**
* @dataProvider shortCircuitProviderCompile
*/
public function testShortCircuitOperatorsCompile($expression, array $names, $expected)
{
$result = null;
$expressionLanguage = new ExpressionLanguage();
eval(sprintf('$result = %s;', $expressionLanguage->compile($expression, $names)));
$this->assertSame($expected, $result);
}

public function shortCircuitProviderEvaluate()
{
$object = $this->getMockBuilder('stdClass')->setMethods(array('foo'))->getMock();
$object->expects($this->never())->method('foo');

return array(
array('false and object.foo()', array('object' => $object), false),
array('false && object.foo()', array('object' => $object), false),
array('true || object.foo()', array('object' => $object), true),
array('true or object.foo()', array('object' => $object), true),
);
}

public function shortCircuitProviderCompile()
{
return array(
array('false and foo', array('foo' => 'foo'), false),
array('false && foo', array('foo' => 'foo'), false),
array('true || foo', array('foo' => 'foo'), true),
array('true or foo', array('foo' => 'foo'), true),
);
}
}

0 comments on commit 3a46a8e

Please sign in to comment.