Skip to content

Commit d39984b

Browse files
[ExpressionLanguage] Add enum expression function
1 parent e558680 commit d39984b

File tree

5 files changed

+83
-0
lines changed

5 files changed

+83
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Add `enum` expression function
8+
49
6.2
510
---
611

ExpressionLanguage.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,19 @@ public function registerProvider(ExpressionFunctionProviderInterface $provider)
138138
protected function registerFunctions()
139139
{
140140
$this->addFunction(ExpressionFunction::fromPhp('constant'));
141+
142+
$this->addFunction(new ExpressionFunction('enum',
143+
static fn ($str): string => sprintf("(\constant(\$v = (%s))) instanceof \UnitEnum ? \constant(\$v) : throw new \TypeError(\sprintf('The string \"%%s\" is not the name of a valid enum case.', \$v))", $str),
144+
static function ($arguments, $str): \UnitEnum {
145+
$value = \constant($str);
146+
147+
if (!$value instanceof \UnitEnum) {
148+
throw new \TypeError(sprintf('The string "%s" is not the name of a valid enum case.', $str));
149+
}
150+
151+
return $value;
152+
}
153+
));
141154
}
142155

143156
private function getLexer(): Lexer

Tests/ExpressionLanguageTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
1919
use Symfony\Component\ExpressionLanguage\ParsedExpression;
2020
use Symfony\Component\ExpressionLanguage\SyntaxError;
21+
use Symfony\Component\ExpressionLanguage\Tests\Fixtures\FooBackedEnum;
22+
use Symfony\Component\ExpressionLanguage\Tests\Fixtures\FooEnum;
2123
use Symfony\Component\ExpressionLanguage\Tests\Fixtures\TestProvider;
2224

2325
class ExpressionLanguageTest extends TestCase
@@ -78,6 +80,53 @@ public function testConstantFunction()
7880
$this->assertEquals('\constant("PHP_VERSION")', $expressionLanguage->compile('constant("PHP_VERSION")'));
7981
}
8082

83+
public function testEnumFunctionWithConstantThrows()
84+
{
85+
$this->expectException(\TypeError::class);
86+
$this->expectExceptionMessage('The string "PHP_VERSION" is not the name of a valid enum case.');
87+
$expressionLanguage = new ExpressionLanguage();
88+
$expressionLanguage->evaluate('enum("PHP_VERSION")');
89+
}
90+
91+
public function testCompiledEnumFunctionWithConstantThrows()
92+
{
93+
$this->expectException(\TypeError::class);
94+
$this->expectExceptionMessage('The string "PHP_VERSION" is not the name of a valid enum case.');
95+
$expressionLanguage = new ExpressionLanguage();
96+
eval($expressionLanguage->compile('enum("PHP_VERSION")').';');
97+
}
98+
99+
public function testEnumFunction()
100+
{
101+
$expressionLanguage = new ExpressionLanguage();
102+
$this->assertSame(FooEnum::Foo, $expressionLanguage->evaluate('enum("Symfony\\\\Component\\\\ExpressionLanguage\\\\Tests\\\\Fixtures\\\\FooEnum::Foo")'));
103+
}
104+
105+
public function testCompiledEnumFunction()
106+
{
107+
$result = null;
108+
$expressionLanguage = new ExpressionLanguage();
109+
eval(sprintf('$result = %s;', $expressionLanguage->compile('enum("Symfony\\\\Component\\\\ExpressionLanguage\\\\Tests\\\\Fixtures\\\\FooEnum::Foo")')));
110+
111+
$this->assertSame(FooEnum::Foo, $result);
112+
}
113+
114+
public function testBackedEnumFunction()
115+
{
116+
$expressionLanguage = new ExpressionLanguage();
117+
$this->assertSame(FooBackedEnum::Bar, $expressionLanguage->evaluate('enum("Symfony\\\\Component\\\\ExpressionLanguage\\\\Tests\\\\Fixtures\\\\FooBackedEnum::Bar")'));
118+
$this->assertSame('Foo', $expressionLanguage->evaluate('enum("Symfony\\\\Component\\\\ExpressionLanguage\\\\Tests\\\\Fixtures\\\\FooBackedEnum::Bar").value'));
119+
}
120+
121+
public function testCompiledEnumFunctionWithBackedEnum()
122+
{
123+
$result = null;
124+
$expressionLanguage = new ExpressionLanguage();
125+
eval(sprintf('$result = %s;', $expressionLanguage->compile('enum("Symfony\\\\Component\\\\ExpressionLanguage\\\\Tests\\\\Fixtures\\\\FooBackedEnum::Bar")')));
126+
127+
$this->assertSame(FooBackedEnum::Bar, $result);
128+
}
129+
81130
public function testProviders()
82131
{
83132
$expressionLanguage = new ExpressionLanguage(null, [new TestProvider()]);

Tests/Fixtures/FooBackedEnum.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\ExpressionLanguage\Tests\Fixtures;
4+
5+
enum FooBackedEnum: string
6+
{
7+
case Bar = 'Foo';
8+
}

Tests/Fixtures/FooEnum.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\ExpressionLanguage\Tests\Fixtures;
4+
5+
enum FooEnum
6+
{
7+
case Foo;
8+
}

0 commit comments

Comments
 (0)