Skip to content

Commit

Permalink
Add support for newlines in identity() (#1104)
Browse files Browse the repository at this point in the history
  • Loading branch information
julienfalque authored Jul 1, 2022
1 parent 7ae4a15 commit d523af2
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 10 deletions.
78 changes: 78 additions & 0 deletions fixtures/Integration/identity_newlines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
stdClass:
dummy:
newlinesReplacedWithSpaces: >
<(
new DateTime(
'2022'
.'-01'
.'-01',
)
)>
newlinesReplacedWithSpacesNoNewlineAtEnd: >-
<(
new DateTime(
'2022'
.'-01'
.'-02',
)
)>
newlinesReplacedWithSpacesAllNewlinesFromEnd: >+
<(
new DateTime(
'2022'
.'-01'
.'-03',
)
)>
newlinesKept: |
<(
new DateTime(
'2022'
.'-01'
.'-04',
)
)>
newlinesKeptNoNewlineAtEnd: |-
<(
new DateTime(
'2022'
.'-01'
.'-05',
)
)>
newlinesKeptAllNewlinesFromEnd: |+
<(
new DateTime(
'2022'
.'-01'
.'-06',
)
)>
12 changes: 12 additions & 0 deletions src/FixtureBuilder/ExpressionLanguage/Parser/SimpleParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ public function parse(string $value)
$parsedTokens = $this->parseToken($parsedTokens, $this->tokenParser, $token);
}

if (count($parsedTokens) > 1) {
$first = reset($parsedTokens);
if (is_string($first) && trim($first) === '') {
array_shift($parsedTokens);
}

$last = end($parsedTokens);
if (is_string($last) && trim($last) === '') {
array_pop($parsedTokens);
}
}

return (1 === count($parsedTokens))
? $parsedTokens[0]
: new ListValue($parsedTokens)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ final class FunctionTokenParser implements ChainableTokenParserInterface, Parser
use IsAServiceTrait;

/** @private */
const REGEX = '/^<(?<function>(.|\r?\n)+?)\((?<arguments>.*)\)>$/';
const REGEX = '/^\s*<(?<function>(.|\r?\n)+?)\((?<arguments>.*)\)>\s*$/s';

/**
* @var ArgumentEscaper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function canParse(Token $token): bool
public function parse(Token $token)
{
$value = $this->tokenizer->detokenize($token->getValue());
$realValue = preg_replace('/^<\((.*)\)>$/', '<identity($1)>', $value);
$realValue = preg_replace('/^<\((.*)\)>$/s', '<identity($1)>', $value);

return $this->decoratedTokenParser->parse(
new Token($realValue, new TokenType(TokenType::FUNCTION_TYPE))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -746,14 +746,11 @@ public function provideValues()
];
yield '[Optional] complete with superfluous space' => [
'80%? Y : Z ',
new ListValue([
new OptionalValue(
'80',
'Y',
'Z'
),
' ',
]),
new OptionalValue(
'80',
'Y',
'Z'
),
];
yield '[Optional] complete with negative number' => [
'-50%? Y: Z',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,35 @@ public function testLexValueAndParsesEachTokenToReturnAValue(): void
$tokenParserProphecy->parse(Argument::any())->shouldHaveBeenCalledTimes(2);
}

public function testIfTheLexProcessReturnsATokensSurroundedWithSpacesTheTrimsTheSpaces(): void
{
$value = 'foo';

$lexerProphecy = $this->prophesize(LexerInterface::class);
$lexerProphecy->lex($value)->willReturn([
$token1 = new Token("\n", new TokenType(TokenType::STRING_TYPE)),
$token2 = new Token('foo', new TokenType(TokenType::VARIABLE_TYPE)),
$token3 = new Token("\n", new TokenType(TokenType::STRING_TYPE)),
]);
/** @var LexerInterface $lexer */
$lexer = $lexerProphecy->reveal();

$tokenParserProphecy = $this->prophesize(TokenParserInterface::class);
$tokenParserProphecy->parse($token1)->willReturn("\n");
$tokenParserProphecy->parse($token2)->willReturn('parsed_foo');
$tokenParserProphecy->parse($token3)->willReturn("\n");
/** @var TokenParserInterface $tokenParser */
$tokenParser = $tokenParserProphecy->reveal();

$parser = new SimpleParser($lexer, $tokenParser);
$parsedValue = $parser->parse($value);

static::assertEquals(
'parsed_foo',
$parsedValue
);
}

public function testIfTheLexProcessReturnsMultipleTokensThenTheValueReturnedWillBeAListValue(): void
{
$value = 'foo';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,26 @@ public function testReplaceIdentityIntoAFunctionCallBeforeHandingItOverToItsDeco

$decoratedParserProphecy->parse(Argument::any())->shouldHaveBeenCalledTimes(1);
}

public function testSupportNewlines(): void
{
$token = new Token("<(new DateTime(\n '2021-12-29',\n))>", new TokenType(TokenType::IDENTITY_TYPE));

$decoratedParserProphecy = $this->prophesize(ChainableTokenParserInterface::class);
$decoratedParserProphecy
->parse(
new Token("<identity(new DateTime(\n '2021-12-29',\n))>", new TokenType(TokenType::FUNCTION_TYPE))
)
->willReturn($expected = 'foo')
;
/** @var ChainableTokenParserInterface $decoratedParser */
$decoratedParser = $decoratedParserProphecy->reveal();

$parser = new IdentityTokenParser($decoratedParser);
$actual = $parser->parse($token);

static::assertEquals($expected, $actual);

$decoratedParserProphecy->parse(Argument::any())->shouldHaveBeenCalledTimes(1);
}
}
21 changes: 21 additions & 0 deletions tests/Loader/LoaderIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Nelmio\Alice\Loader;

use DateTime;
use DateTimeInterface;
use InvalidArgumentException;
use LogicException;
Expand Down Expand Up @@ -1550,6 +1551,26 @@ public function testFunctionCallArgumentResolverWithObjectsKeepsSameInstances():
static::assertSame($dummy2, $dummy1->sibling);
}

public function testNewlinesInIdentity(): void
{
$objects = $this->loader->loadFile(self::FIXTURES_FILES_DIR.'/identity_newlines.yml')->getObjects();

$expected = new stdClass();
$expected->newlinesReplacedWithSpaces = new DateTime('2022-01-01');
$expected->newlinesReplacedWithSpacesNoNewlineAtEnd = new DateTime('2022-01-02');
$expected->newlinesReplacedWithSpacesAllNewlinesFromEnd = new DateTime('2022-01-03');
$expected->newlinesKept = new DateTime('2022-01-04');
$expected->newlinesKeptNoNewlineAtEnd = new DateTime('2022-01-05');
$expected->newlinesKeptAllNewlinesFromEnd = new DateTime('2022-01-06');

static::assertEquals(
[
'dummy' => $expected,
],
$objects
);
}

public function provideFixturesToInstantiate()
{
yield 'with default constructor – use default constructor' => [
Expand Down

0 comments on commit d523af2

Please sign in to comment.