Skip to content

Commit

Permalink
[ExpressionLanguage] Add enum expression function
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandre-daubois committed Dec 15, 2022
1 parent d8d93c6 commit 63e5a9a
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Symfony/Component/ExpressionLanguage/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

6.3
---

* Add `enum` expression function

6.2
---

Expand Down
16 changes: 16 additions & 0 deletions src/Symfony/Component/ExpressionLanguage/ExpressionLanguage.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ public function registerProvider(ExpressionFunctionProviderInterface $provider)
protected function registerFunctions()
{
$this->addFunction(ExpressionFunction::fromPhp('constant'));

$this->addFunction(new ExpressionFunction('enum', function ($str): string {
return sprintf('\constant(%1$s)', $str);
}, function ($arguments, $str): \UnitEnum {
if (!\defined($str)) {
throw new \LogicException(sprintf('The enum case "%s" is not defined.', $str));
}

$value = \constant($str);

if (!$value instanceof \UnitEnum) {
throw new \LogicException(sprintf('The string "%s" is not the name of a valid enum case.', $str));
}

return $value;
}));
}

private function getLexer(): Lexer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ParsedExpression;
use Symfony\Component\ExpressionLanguage\SyntaxError;
use Symfony\Component\ExpressionLanguage\Tests\Fixtures\FooBackedEnum;
use Symfony\Component\ExpressionLanguage\Tests\Fixtures\FooEnum;
use Symfony\Component\ExpressionLanguage\Tests\Fixtures\TestProvider;

class ExpressionLanguageTest extends TestCase
Expand Down Expand Up @@ -78,6 +80,36 @@ public function testConstantFunction()
$this->assertEquals('\constant("PHP_VERSION")', $expressionLanguage->compile('constant("PHP_VERSION")'));
}

public function testEnumFunctionWithConstantThrows()
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('The string "PHP_VERSION" is not the name of a valid enum case.');
$expressionLanguage = new ExpressionLanguage();
$expressionLanguage->evaluate('enum("PHP_VERSION")');
}

public function testEnumFunctionWithInvalidEnumCaseThrows()
{
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('The enum case "\Invalid\Enum::Case" is not defined.');
$expressionLanguage = new ExpressionLanguage();
$expressionLanguage->evaluate('enum("\\\\Invalid\\\\Enum::Case")');
}

public function testEnumFunction()
{
$expressionLanguage = new ExpressionLanguage();
$this->assertSame(FooEnum::Foo, $expressionLanguage->evaluate('enum("Symfony\\\\Component\\\\ExpressionLanguage\\\\Tests\\\\Fixtures\\\\FooEnum::Foo")'));
}

public function testBackedEnumFunction()
{
$expressionLanguage = new ExpressionLanguage();
$this->assertSame(FooBackedEnum::Bar, $expressionLanguage->evaluate('enum("Symfony\\\\Component\\\\ExpressionLanguage\\\\Tests\\\\Fixtures\\\\FooBackedEnum::Bar")'));

$this->assertSame(FooBackedEnum::Bar->value, $expressionLanguage->evaluate('enum("Symfony\\\\Component\\\\ExpressionLanguage\\\\Tests\\\\Fixtures\\\\FooBackedEnum::Bar").value'));
}

public function testProviders()
{
$expressionLanguage = new ExpressionLanguage(null, [new TestProvider()]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Symfony\Component\ExpressionLanguage\Tests\Fixtures;

enum FooBackedEnum: string
{
case Bar = 'Foo';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Symfony\Component\ExpressionLanguage\Tests\Fixtures;

enum FooEnum
{
case Foo;
}

0 comments on commit 63e5a9a

Please sign in to comment.