4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\ExpressionLanguage\Tests;
14 use Symfony\Component\ExpressionLanguage\ExpressionFunction;
15 use PHPUnit\Framework\TestCase;
16 use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
17 use Symfony\Component\ExpressionLanguage\Tests\Fixtures\TestProvider;
19 class ExpressionLanguageTest extends TestCase
21 public function testCachedParse()
23 $cacheMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock();
24 $savedParsedExpression = null;
25 $expressionLanguage = new ExpressionLanguage($cacheMock);
28 ->expects($this->exactly(2))
31 ->will($this->returnCallback(function () use (&$savedParsedExpression) {
32 return $savedParsedExpression;
36 ->expects($this->exactly(1))
38 ->with('1 + 1//', $this->isInstanceOf('Symfony\Component\ExpressionLanguage\ParsedExpression'))
39 ->will($this->returnCallback(function ($key, $expression) use (&$savedParsedExpression) {
40 $savedParsedExpression = $expression;
44 $parsedExpression = $expressionLanguage->parse('1 + 1', array());
45 $this->assertSame($savedParsedExpression, $parsedExpression);
47 $parsedExpression = $expressionLanguage->parse('1 + 1', array());
48 $this->assertSame($savedParsedExpression, $parsedExpression);
51 public function testConstantFunction()
53 $expressionLanguage = new ExpressionLanguage();
54 $this->assertEquals(PHP_VERSION, $expressionLanguage->evaluate('constant("PHP_VERSION")'));
56 $expressionLanguage = new ExpressionLanguage();
57 $this->assertEquals('constant("PHP_VERSION")', $expressionLanguage->compile('constant("PHP_VERSION")'));
60 public function testProviders()
62 $expressionLanguage = new ExpressionLanguage(null, array(new TestProvider()));
63 $this->assertEquals('foo', $expressionLanguage->evaluate('identity("foo")'));
64 $this->assertEquals('"foo"', $expressionLanguage->compile('identity("foo")'));
68 * @dataProvider shortCircuitProviderEvaluate
70 public function testShortCircuitOperatorsEvaluate($expression, array $values, $expected)
72 $expressionLanguage = new ExpressionLanguage();
73 $this->assertEquals($expected, $expressionLanguage->evaluate($expression, $values));
77 * @dataProvider shortCircuitProviderCompile
79 public function testShortCircuitOperatorsCompile($expression, array $names, $expected)
82 $expressionLanguage = new ExpressionLanguage();
83 eval(sprintf('$result = %s;', $expressionLanguage->compile($expression, $names)));
84 $this->assertSame($expected, $result);
87 public function shortCircuitProviderEvaluate()
89 $object = $this->getMockBuilder('stdClass')->setMethods(array('foo'))->getMock();
90 $object->expects($this->never())->method('foo');
93 array('false and object.foo()', array('object' => $object), false),
94 array('false && object.foo()', array('object' => $object), false),
95 array('true || object.foo()', array('object' => $object), true),
96 array('true or object.foo()', array('object' => $object), true),
100 public function shortCircuitProviderCompile()
103 array('false and foo', array('foo' => 'foo'), false),
104 array('false && foo', array('foo' => 'foo'), false),
105 array('true || foo', array('foo' => 'foo'), true),
106 array('true or foo', array('foo' => 'foo'), true),
110 public function testCachingForOverriddenVariableNames()
112 $expressionLanguage = new ExpressionLanguage();
113 $expression = 'a + b';
114 $expressionLanguage->evaluate($expression, array('a' => 1, 'b' => 1));
115 $result = $expressionLanguage->compile($expression, array('a', 'B' => 'b'));
116 $this->assertSame('($a + $B)', $result);
119 public function testCachingWithDifferentNamesOrder()
121 $cacheMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock();
122 $expressionLanguage = new ExpressionLanguage($cacheMock);
123 $savedParsedExpressions = array();
125 ->expects($this->exactly(2))
127 ->will($this->returnCallback(function ($key) use (&$savedParsedExpressions) {
128 return isset($savedParsedExpressions[$key]) ? $savedParsedExpressions[$key] : null;
132 ->expects($this->exactly(1))
134 ->will($this->returnCallback(function ($key, $expression) use (&$savedParsedExpressions) {
135 $savedParsedExpressions[$key] = $expression;
139 $expression = 'a + b';
140 $expressionLanguage->compile($expression, array('a', 'B' => 'b'));
141 $expressionLanguage->compile($expression, array('B' => 'b', 'a'));
145 * @dataProvider getRegisterCallbacks
146 * @expectedException \LogicException
148 public function testRegisterAfterParse($registerCallback)
150 $el = new ExpressionLanguage();
151 $el->parse('1 + 1', array());
152 $registerCallback($el);
156 * @dataProvider getRegisterCallbacks
157 * @expectedException \LogicException
159 public function testRegisterAfterEval($registerCallback)
161 $el = new ExpressionLanguage();
162 $el->evaluate('1 + 1');
163 $registerCallback($el);
167 * @dataProvider getRegisterCallbacks
168 * @expectedException \LogicException
170 public function testRegisterAfterCompile($registerCallback)
172 $el = new ExpressionLanguage();
173 $el->compile('1 + 1');
174 $registerCallback($el);
177 public function getRegisterCallbacks()
181 function (ExpressionLanguage $el) {
182 $el->register('fn', function () {}, function () {});
186 function (ExpressionLanguage $el) {
187 $el->addFunction(new ExpressionFunction('fn', function () {}, function () {}));
191 function (ExpressionLanguage $el) {
192 $el->registerProvider(new TestProvider());