diff --git a/fixtures/Bridge/Symfony/Application/AppKernel.php b/fixtures/Bridge/Symfony/Application/AppKernel.php
index 70d6d151a..49c409a49 100644
--- a/fixtures/Bridge/Symfony/Application/AppKernel.php
+++ b/fixtures/Bridge/Symfony/Application/AppKernel.php
@@ -19,7 +19,6 @@
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\HttpKernel\Kernel;
class AppKernel extends Kernel
@@ -63,7 +62,7 @@ public function registerContainerConfiguration(LoaderInterface $loader)
*/
public function build(ContainerBuilder $container)
{
- $container->addCompilerPass(new class implements CompilerPassInterface {
+ $container->addCompilerPass(new class() implements CompilerPassInterface {
public function process(ContainerBuilder $container)
{
foreach ($container->getDefinitions() as $id => $definition) {
diff --git a/src/Bridge/Symfony/Resources/config/fixture_builder/expression_language/token_parser.xml b/src/Bridge/Symfony/Resources/config/fixture_builder/expression_language/token_parser.xml
index 2022ec5b7..fecb56e9e 100644
--- a/src/Bridge/Symfony/Resources/config/fixture_builder/expression_language/token_parser.xml
+++ b/src/Bridge/Symfony/Resources/config/fixture_builder/expression_language/token_parser.xml
@@ -70,6 +70,11 @@
+
+
+
+
diff --git a/src/FixtureBuilder/ExpressionLanguage/Lexer/ReferenceLexer.php b/src/FixtureBuilder/ExpressionLanguage/Lexer/ReferenceLexer.php
index 594b7c504..800527f8c 100644
--- a/src/FixtureBuilder/ExpressionLanguage/Lexer/ReferenceLexer.php
+++ b/src/FixtureBuilder/ExpressionLanguage/Lexer/ReferenceLexer.php
@@ -35,6 +35,7 @@ final class ReferenceLexer implements LexerInterface
'/^@[^\ @]+\{.*,.*}/' => TokenType::LIST_REFERENCE_TYPE,
'/^@.*\*/' => TokenType::WILDCARD_REFERENCE_TYPE,
'/^@.*->.*/' => null,
+ '/^@\S+\$\S+/' => TokenType::VARIABLE_REFERENCE_TYPE,
'/^@\S+/' => TokenType::SIMPLE_REFERENCE_TYPE,
'/^@/' => TokenType::SIMPLE_REFERENCE_TYPE,
];
diff --git a/src/FixtureBuilder/ExpressionLanguage/Parser/FunctionFixtureReferenceParser.php b/src/FixtureBuilder/ExpressionLanguage/Parser/FunctionFixtureReferenceParser.php
index 0da6ac616..7902ee6cf 100644
--- a/src/FixtureBuilder/ExpressionLanguage/Parser/FunctionFixtureReferenceParser.php
+++ b/src/FixtureBuilder/ExpressionLanguage/Parser/FunctionFixtureReferenceParser.php
@@ -53,7 +53,7 @@ public function parse(string $value)
$mergedValues = array_reduce(
$parsedValue->getValue(),
[$this, 'mergeFunctionFixtureReferences'],
- $initial = []
+ []
);
return (1 === count($mergedValues))
diff --git a/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/SimpleReferenceTokenParser.php b/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/SimpleReferenceTokenParser.php
index 36893e335..048c35d5f 100644
--- a/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/SimpleReferenceTokenParser.php
+++ b/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/SimpleReferenceTokenParser.php
@@ -13,6 +13,7 @@
namespace Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable;
+use InvalidArgumentException;
use Nelmio\Alice\Definition\Value\FixtureReferenceValue;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\ChainableTokenParserInterface;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Token;
@@ -46,7 +47,7 @@ public function parse(Token $token): FixtureReferenceValue
try {
return new FixtureReferenceValue(substr($value, 1));
- } catch (\InvalidArgumentException $exception) {
+ } catch (InvalidArgumentException $exception) {
throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token, 0, $exception);
}
}
diff --git a/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/VariableReferenceTokenParser.php b/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/VariableReferenceTokenParser.php
new file mode 100644
index 000000000..026882ca3
--- /dev/null
+++ b/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/VariableReferenceTokenParser.php
@@ -0,0 +1,70 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable;
+
+use InvalidArgumentException;
+use Nelmio\Alice\Definition\Value\FixtureReferenceValue;
+use Nelmio\Alice\Definition\Value\FunctionCallValue;
+use Nelmio\Alice\Definition\Value\ListValue;
+use Nelmio\Alice\Definition\Value\ValueForCurrentValue;
+use Nelmio\Alice\Definition\Value\VariableValue;
+use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\ChainableTokenParserInterface;
+use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Token;
+use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\TokenType;
+use Nelmio\Alice\IsAServiceTrait;
+use Nelmio\Alice\Throwable\Exception\FixtureBuilder\ExpressionLanguage\ExpressionLanguageExceptionFactory;
+
+/**
+ * @internal
+ */
+final class VariableReferenceTokenParser implements ChainableTokenParserInterface
+{
+ use IsAServiceTrait;
+
+ /**
+ * @inheritdoc
+ */
+ public function canParse(Token $token): bool
+ {
+ return $token->getType() === TokenType::VARIABLE_REFERENCE_TYPE;
+ }
+
+ /**
+ * Parses expressions such as "@user$foo".
+ *
+ * {@inheritdoc}
+ */
+ public function parse(Token $token): FixtureReferenceValue
+ {
+ $parts = explode('$', $token->getValue());
+
+ $variable = $parts[1];
+
+ try {
+ return new FixtureReferenceValue(
+ new ListValue([
+ substr($parts[0], 1),
+ 'current' === $variable
+ ? new FunctionCallValue(
+ 'current',
+ [new ValueForCurrentValue()]
+ )
+ : new VariableValue($variable)
+ ])
+ );
+ } catch (InvalidArgumentException $exception) {
+ throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token, 0, $exception);
+ }
+ }
+}
diff --git a/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/VariableTokenParser.php b/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/VariableTokenParser.php
index 57d56c193..21a4f2a55 100644
--- a/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/VariableTokenParser.php
+++ b/src/FixtureBuilder/ExpressionLanguage/Parser/TokenParser/Chainable/VariableTokenParser.php
@@ -13,6 +13,8 @@
namespace Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable;
+use Nelmio\Alice\Definition\Value\FunctionCallValue;
+use Nelmio\Alice\Definition\Value\ValueForCurrentValue;
use Nelmio\Alice\Definition\Value\VariableValue;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\ChainableTokenParserInterface;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Token;
@@ -20,6 +22,7 @@
use Nelmio\Alice\IsAServiceTrait;
use Nelmio\Alice\Throwable\Exception\FixtureBuilder\ExpressionLanguage\ExpressionLanguageExceptionFactory;
use Nelmio\Alice\Throwable\Exception\FixtureBuilder\ExpressionLanguage\ParseException;
+use TypeError;
/**
* @internal
@@ -45,9 +48,18 @@ public function canParse(Token $token): bool
*/
public function parse(Token $token)
{
+ $variable = substr($token->getValue(), 1);
+
+ if ('current' === $variable) {
+ return new FunctionCallValue(
+ 'current',
+ [new ValueForCurrentValue()]
+ );
+ }
+
try {
- return new VariableValue(substr($token->getValue(), 1));
- } catch (\TypeError $error) {
+ return new VariableValue($variable);
+ } catch (TypeError $error) {
throw ExpressionLanguageExceptionFactory::createForUnparsableToken($token, 0, $error);
}
}
diff --git a/src/FixtureBuilder/ExpressionLanguage/TokenType.php b/src/FixtureBuilder/ExpressionLanguage/TokenType.php
index b0863b761..c75a1d972 100644
--- a/src/FixtureBuilder/ExpressionLanguage/TokenType.php
+++ b/src/FixtureBuilder/ExpressionLanguage/TokenType.php
@@ -36,6 +36,7 @@ final class TokenType
const RANGE_REFERENCE_TYPE = 'RANGE_REFERENCE_TYPE';
const PROPERTY_REFERENCE_TYPE = 'PROPERTY_REFERENCE_TYPE';
const METHOD_REFERENCE_TYPE = 'METHOD_REFERENCE_TYPE';
+ const VARIABLE_REFERENCE_TYPE = 'VARIABLE_REFERENCE_TYPE';
const VARIABLE_TYPE = 'VARIABLE_TYPE';
@@ -54,6 +55,7 @@ final class TokenType
self::RANGE_REFERENCE_TYPE => true,
self::PROPERTY_REFERENCE_TYPE => true,
self::METHOD_REFERENCE_TYPE => true,
+ self::VARIABLE_REFERENCE_TYPE => true,
self::VARIABLE_TYPE => true,
];
diff --git a/src/Loader/NativeLoader.php b/src/Loader/NativeLoader.php
index 0e7e41768..c098b2911 100644
--- a/src/Loader/NativeLoader.php
+++ b/src/Loader/NativeLoader.php
@@ -83,6 +83,7 @@
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable\StringArrayTokenParser;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable\StringTokenParser;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable\TolerantFunctionTokenParser;
+use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable\VariableReferenceTokenParser;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable\VariableTokenParser;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable\WildcardReferenceTokenParser;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\TokenParserRegistry;
@@ -468,6 +469,7 @@ protected function createExpressionLanguageTokenParser(): TokenParserInterface
new OptionalTokenParser(),
new ParameterTokenParser(),
new PropertyReferenceTokenParser(),
+ new VariableReferenceTokenParser(),
new SimpleReferenceTokenParser(),
new StringArrayTokenParser(),
new StringTokenParser($argumentEscaper),
diff --git a/tests/FixtureBuilder/ExpressionLanguage/Lexer/LexerIntegrationTest.php b/tests/FixtureBuilder/ExpressionLanguage/Lexer/LexerIntegrationTest.php
index f3df4ffab..5c0b87b6c 100644
--- a/tests/FixtureBuilder/ExpressionLanguage/Lexer/LexerIntegrationTest.php
+++ b/tests/FixtureBuilder/ExpressionLanguage/Lexer/LexerIntegrationTest.php
@@ -13,6 +13,7 @@
namespace Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Lexer;
+use InvalidArgumentException;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\LexerInterface;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Token;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\TokenType;
@@ -56,7 +57,7 @@ public function testCanLexValues(string $value, $expected)
)
);
}
- } catch (\InvalidArgumentException $exception) {
+ } catch (InvalidArgumentException $exception) {
if (null === $expected) {
return;
}
@@ -841,6 +842,12 @@ public function provideValues()
new Token('@user{1..2}->username', new TokenType(TokenType::PROPERTY_REFERENCE_TYPE)),
],
];
+ yield '[Reference] variable with prop' => [
+ '@user$current->username',
+ [
+ new Token('@user$current->username', new TokenType(TokenType::PROPERTY_REFERENCE_TYPE)),
+ ],
+ ];
yield '[Reference] left with prop' => [
'foo @user0->username',
[
@@ -1022,6 +1029,12 @@ public function provideValues()
new Token(' bar', new TokenType(TokenType::STRING_TYPE)),
],
];
+ yield '[Reference] reference variable' => [
+ '@user0$foo',
+ [
+ new Token('@user0$foo', new TokenType(TokenType::VARIABLE_REFERENCE_TYPE)),
+ ],
+ ];
yield '[Reference] reference function' => [
'@user0',
[
diff --git a/tests/FixtureBuilder/ExpressionLanguage/Parser/ParserIntegrationTest.php b/tests/FixtureBuilder/ExpressionLanguage/Parser/ParserIntegrationTest.php
index 5c46643f5..005fef7ec 100644
--- a/tests/FixtureBuilder/ExpressionLanguage/Parser/ParserIntegrationTest.php
+++ b/tests/FixtureBuilder/ExpressionLanguage/Parser/ParserIntegrationTest.php
@@ -890,6 +890,18 @@ public function provideValues()
'username'
),
];
+ yield '[Reference] variable with prop' => [
+ '@user$foo->username',
+ new FixturePropertyValue(
+ new FixtureReferenceValue(
+ new ListValue([
+ 'user',
+ new VariableValue('foo'),
+ ])
+ ),
+ 'username'
+ ),
+ ];
yield '[Reference] left with prop' => [
'foo @user0->username',
new ListValue([
@@ -1099,6 +1111,15 @@ public function provideValues()
' bar',
]),
];
+ yield '[Reference] reference variable' => [
+ '@user0$foo',
+ new FixtureReferenceValue(
+ new ListValue([
+ 'user0',
+ new VariableValue('foo')
+ ])
+ ),
+ ];
yield '[Reference] reference function' => [
'@user0',
new FixtureReferenceValue(
diff --git a/tests/Loader/LoaderIntegrationTest.php b/tests/Loader/LoaderIntegrationTest.php
index 55f9884c0..b9991d286 100644
--- a/tests/Loader/LoaderIntegrationTest.php
+++ b/tests/Loader/LoaderIntegrationTest.php
@@ -2025,6 +2025,36 @@ public function provideFixturesToGenerate()
],
];
+ yield 'dynamic reference with variable' => [
+ [
+ stdClass::class => [
+ 'dummy{1..2}' => [
+ 'name' => '',
+ ],
+ 'another_dummy{1..2}' => [
+ 'dummy' => '@dummy$current',
+ ],
+ ],
+ ],
+ [
+ 'parameters' => [],
+ 'objects' => [
+ 'dummy1' => $dummy1 = StdClassFactory::create([
+ 'name' => '1',
+ ]),
+ 'dummy2' => $dummy2 = StdClassFactory::create([
+ 'name' => '2',
+ ]),
+ 'another_dummy1' => StdClassFactory::create([
+ 'dummy' => $dummy1,
+ ]),
+ 'another_dummy2' => StdClassFactory::create([
+ 'dummy' => $dummy2,
+ ]),
+ ],
+ ],
+ ];
+
yield 'property reference value' => [
[
stdClass::class => [
@@ -2073,6 +2103,36 @@ public function provideFixturesToGenerate()
],
];
+ yield 'dynamic property reference value' => [
+ [
+ stdClass::class => [
+ 'dummy{1..2}' => [
+ 'name' => '',
+ ],
+ 'another_dummy{1..2}' => [
+ 'dummy' => '@dummy$current->name',
+ ],
+ ],
+ ],
+ [
+ 'parameters' => [],
+ 'objects' => [
+ 'dummy1' => $dummy1 = StdClassFactory::create([
+ 'name' => '1',
+ ]),
+ 'dummy2' => $dummy2 = StdClassFactory::create([
+ 'name' => '2',
+ ]),
+ 'another_dummy1' => StdClassFactory::create([
+ 'dummy' => '1',
+ ]),
+ 'another_dummy2' => StdClassFactory::create([
+ 'dummy' => '2',
+ ]),
+ ],
+ ],
+ ];
+
yield 'non existing property reference' => [
[
stdClass::class => [
@@ -2782,6 +2842,12 @@ public function provideFixturesToGenerate()
'dummy_{alice, bob}' => [
'val' => '',
],
+ 'dummy_var{1..2}' => [
+ 'val' => '$current',
+ ],
+ 'dummy_var_{alice, bob}' => [
+ 'val' => '$current',
+ ],
],
],
[
@@ -2799,6 +2865,18 @@ public function provideFixturesToGenerate()
'dummy_bob' => StdClassFactory::create([
'val' => 'bob',
]),
+ 'dummy_var1' => StdClassFactory::create([
+ 'val' => 1,
+ ]),
+ 'dummy_var2' => StdClassFactory::create([
+ 'val' => 2,
+ ]),
+ 'dummy_var_alice' => StdClassFactory::create([
+ 'val' => 'alice',
+ ]),
+ 'dummy_var_bob' => StdClassFactory::create([
+ 'val' => 'bob',
+ ]),
],
],
];