Skip to content

Commit

Permalink
Fix usage with current (#836)
Browse files Browse the repository at this point in the history
Allow to use `$current` variable outside of the identity context and
more peticuliarly allow to use expressions such as `@user$current`.

Closes #761
  • Loading branch information
theofidry authored Nov 17, 2017
1 parent 358543e commit c7eaf6f
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 7 deletions.
3 changes: 1 addition & 2 deletions fixtures/Bridge/Symfony/Application/AppKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
<tag name="nelmio_alice.fixture_builder.expression_language.chainable_token_parser" />
</service>

<service id="nelmio_alice.fixture_builder.expression_language.parser.token_parser.chainable.variable_reference_token_parser"
class="Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable\VariableReferenceTokenParser">
<tag name="nelmio_alice.fixture_builder.expression_language.chainable_token_parser" />
</service>

<service id="nelmio_alice.fixture_builder.expression_language.parser.token_parser.chainable.simple_reference_token_parser"
class="Nelmio\Alice\FixtureBuilder\ExpressionLanguage\Parser\TokenParser\Chainable\SimpleReferenceTokenParser">
<tag name="nelmio_alice.fixture_builder.expression_language.chainable_token_parser" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function parse(string $value)
$mergedValues = array_reduce(
$parsedValue->getValue(),
[$this, 'mergeFunctionFixtureReferences'],
$initial = []
[]
);

return (1 === count($mergedValues))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

/*
* This file is part of the Alice package.
*
* (c) Nelmio <hello@nelm.io>
*
* 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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@

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;
use Nelmio\Alice\FixtureBuilder\ExpressionLanguage\TokenType;
use Nelmio\Alice\IsAServiceTrait;
use Nelmio\Alice\Throwable\Exception\FixtureBuilder\ExpressionLanguage\ExpressionLanguageExceptionFactory;
use Nelmio\Alice\Throwable\Exception\FixtureBuilder\ExpressionLanguage\ParseException;
use TypeError;

/**
* @internal
Expand All @@ -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);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/FixtureBuilder/ExpressionLanguage/TokenType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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,
];

Expand Down
2 changes: 2 additions & 0 deletions src/Loader/NativeLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -468,6 +469,7 @@ protected function createExpressionLanguageTokenParser(): TokenParserInterface
new OptionalTokenParser(),
new ParameterTokenParser(),
new PropertyReferenceTokenParser(),
new VariableReferenceTokenParser(),
new SimpleReferenceTokenParser(),
new StringArrayTokenParser(),
new StringTokenParser($argumentEscaper),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -56,7 +57,7 @@ public function testCanLexValues(string $value, $expected)
)
);
}
} catch (\InvalidArgumentException $exception) {
} catch (InvalidArgumentException $exception) {
if (null === $expected) {
return;
}
Expand Down Expand Up @@ -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',
[
Expand Down Expand Up @@ -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<current()>',
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down Expand Up @@ -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<foo()>',
new FixtureReferenceValue(
Expand Down
78 changes: 78 additions & 0 deletions tests/Loader/LoaderIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,36 @@ public function provideFixturesToGenerate()
],
];

yield 'dynamic reference with variable' => [
[
stdClass::class => [
'dummy{1..2}' => [
'name' => '<current()>',
],
'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 => [
Expand Down Expand Up @@ -2073,6 +2103,36 @@ public function provideFixturesToGenerate()
],
];

yield 'dynamic property reference value' => [
[
stdClass::class => [
'dummy{1..2}' => [
'name' => '<current()>',
],
'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 => [
Expand Down Expand Up @@ -2782,6 +2842,12 @@ public function provideFixturesToGenerate()
'dummy_{alice, bob}' => [
'val' => '<current()>',
],
'dummy_var{1..2}' => [
'val' => '$current',
],
'dummy_var_{alice, bob}' => [
'val' => '$current',
],
],
],
[
Expand All @@ -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',
]),
],
],
];
Expand Down

0 comments on commit c7eaf6f

Please sign in to comment.