Skip to content

Commit

Permalink
Fix reference range flags usage with templates (#979)
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-iwaniec authored and theofidry committed Mar 14, 2019
1 parent b286b56 commit b1b2a51
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Nelmio\Alice\FixtureInterface;
use Nelmio\Alice\IsAServiceTrait;
use Nelmio\Alice\Throwable\Exception\LogicExceptionFactory;
use Nelmio\Alice\Throwable\Exception\FixtureBuilder\Denormalizer\FlagParser\FlagParserExceptionFactory;

final class ReferenceRangeNameDenormalizer implements ChainableFixtureDenormalizerInterface, FlagParserAwareInterface
{
Expand Down Expand Up @@ -82,8 +83,13 @@ public function denormalize(
throw LogicExceptionFactory::createForCannotDenormalizerForChainableFixtureBuilderDenormalizer(__METHOD__);
}

if (null === $this->flagParser) {
throw FlagParserExceptionFactory::createForExpectedMethodToBeCalledIfHasAParser(__METHOD__);
}

$referencedName = $matches['name'];
$allFlag = ($matches['flag'] ?? null) === '*';
$idFlags = $this->flagParser->parse($fixtureId);

$fixtureIds = $this->buildReferencedValues($builtFixtures, $referencedName, $allFlag);

Expand All @@ -99,7 +105,7 @@ public function denormalize(
$fixtureIdPrefix . $referencedFixtureId,
$className,
$specs,
$flags,
$idFlags->mergeWith($flags),
$valueForCurrent
)
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
<?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\Denormalizer\Fixture\Chainable;

use Nelmio\Alice\Definition\Fixture\SimpleFixture;
use Nelmio\Alice\Definition\Fixture\SimpleFixtureWithFlags;
use Nelmio\Alice\Definition\Fixture\TemplatingFixture;
use Nelmio\Alice\Definition\Flag\ExtendFlag;
use Nelmio\Alice\Definition\FlagBag;
use Nelmio\Alice\Definition\MethodCallBag;
use Nelmio\Alice\Definition\PropertyBag;
use Nelmio\Alice\Definition\ServiceReference\FixtureReference;
use Nelmio\Alice\Definition\SpecificationBag;
use Nelmio\Alice\FixtureBag;
use Nelmio\Alice\FixtureBuilder\Denormalizer\Fixture\ChainableFixtureDenormalizerInterface;
use Nelmio\Alice\FixtureBuilder\Denormalizer\Fixture\SpecificationBagDenormalizer\DummySpecificationBagDenormalizer;
use Nelmio\Alice\FixtureBuilder\Denormalizer\Fixture\SpecificationsDenormalizerInterface;
use Nelmio\Alice\FixtureBuilder\Denormalizer\FlagParser\DummyFlagParser;
use Nelmio\Alice\FixtureBuilder\Denormalizer\FlagParserInterface;
use Prophecy\Argument;
use ReflectionClass;

/**
* @covers \Nelmio\Alice\FixtureBuilder\Denormalizer\Fixture\Chainable\ReferenceRangeNameDenormalizer
*/
class ReferenceRangeNameDenormalizerTest extends ChainableDenormalizerTest
{
/**
* @inheritdoc
*/
public function setUp()
{
$this->denormalizer = new ReferenceRangeNameDenormalizer(
new DummySpecificationBagDenormalizer(),
new DummyFlagParser()
);
}

public function testIsAChainableDenormalizer()
{
$this->assertTrue(is_a(ReferenceRangeNameDenormalizer::class, ChainableFixtureDenormalizerInterface::class, true));
}

public function testIsNotClonable()
{
$this->assertFalse((new ReflectionClass(ReferenceRangeNameDenormalizer::class))->isCloneable());
}

/**
* @expectedException \Nelmio\Alice\Throwable\Exception\FixtureBuilder\Denormalizer\FlagParser\FlagParserNotFoundException
* @expectedExceptionMessage Expected method "Nelmio\Alice\FixtureBuilder\Denormalizer\Fixture\Chainable\ReferenceRangeNameDenormalizer::denormalize" to be called only if it has a flag parser.
*/
public function testCannotDenormalizeFixtureIfHasNoFlagParser()
{
/** @var SpecificationsDenormalizerInterface $specsDenormalizer */
$specsDenormalizer = $this->prophesize(SpecificationsDenormalizerInterface::class)->reveal();

$denormalizer = new ReferenceRangeNameDenormalizer($specsDenormalizer);
$denormalizer->denormalize(new FixtureBag(), 'Nelmio\Alice\Entity\User', 'user_{@account}', [], new FlagBag(''));
}

public function testTemplateFlagsAreProperlyParsed()
{
$valueForCurrent = new TemplatingFixture(
new SimpleFixtureWithFlags(
new SimpleFixture(
'userDetails',
'Nelmio\Alice\Entity\UserDetails',
new SpecificationBag(null, new PropertyBag(), new MethodCallBag())
),
new FlagBag('userDetails')
)
);

$fixtures = (new FixtureBag())->with($valueForCurrent);
$className = 'Nelmio\Alice\Entity\User';
$reference = 'user_{@userDetails} (extends timestamp)';
$fixtureName = 'user_userDetails';
$specs = [];
$flags = new FlagBag('');
$parsedFlags = (new FlagBag($fixtureName))->withFlag(new ExtendFlag(new FixtureReference('timestamp')));

$flagParserProphecy = $this->prophesize(FlagParserInterface::class);
$flagParserProphecy
->parse($reference)
->willReturn($parsedFlags)
;
/** @var FlagParserInterface $flagParser */
$flagParser = $flagParserProphecy->reveal();

$specsDenormalizerProphecy = $this->prophesize(SpecificationsDenormalizerInterface::class);
$expectedSpecs = new SpecificationBag(null, new PropertyBag(), new MethodCallBag());
$specsDenormalizerProphecy
->denormalize(Argument::type(SimpleFixture::class), $flagParser, $specs)
->willReturn($expectedSpecs)
;
/** @var SpecificationsDenormalizerInterface $specsDenormalizer */
$specsDenormalizer = $specsDenormalizerProphecy->reveal();

$denormalizer = (new ReferenceRangeNameDenormalizer($specsDenormalizer))->withFlagParser($flagParser);
$actual = $denormalizer->denormalize($fixtures, $className, $reference, $specs, $flags);

$expected = $fixtures->with(
new TemplatingFixture(
new SimpleFixtureWithFlags(
new SimpleFixture(
$fixtureName,
$className,
$expectedSpecs,
$valueForCurrent
),
$parsedFlags
)
)
);

$this->assertEquals($expected, $actual);

$flagParserProphecy->parse(Argument::any())->shouldHaveBeenCalledTimes(1);
$specsDenormalizerProphecy->denormalize(Argument::cetera())->shouldHaveBeenCalledTimes(1);
}

/**
* @dataProvider provideSimpleFixtures
*/
public function testCanBuildSimpleFixtures($name)
{
$this->assertCannotBuild($name);
}

/**
* @dataProvider provideListFixtures
*/
public function testCanBuildListFixtures($name)
{
$this->assertCannotBuild($name);
}

/**
* @dataProvider provideMalformedListFixtures
*/
public function testCanBuildMalformedListFixtures($name)
{
$this->assertCannotBuild($name);
}

/**
* @dataProvider provideSegmentFixtures
*/
public function testCanBuildSegmentFixtures($name)
{
$this->assertCannotBuild($name);
}

/**
* @dataProvider provideMalformedSegmentFixtures
*/
public function testCanBuildMalformedSegmentFixtures($name)
{
$this->assertCannotBuild($name);
}

/**
* @dataProvider provideSimpleFixtures
*/
public function testBuildSimpleFixtures($name, $expected)
{
$this->markAsInvalidCase();
}

/**
* @dataProvider provideListFixtures
*/
public function testBuildListFixtures($name, $expected)
{
$this->markAsInvalidCase();
}

/**
* @dataProvider provideMalformedListFixtures
*/
public function testBuildMalformedListFixtures($name, $expected)
{
$this->markAsInvalidCase();
}

/**
* @dataProvider provideSegmentFixtures
*/
public function testBuildSegmentFixtures($name, $expected)
{
$this->markAsInvalidCase();
}

/**
* @dataProvider provideMalformedSegmentFixtures
*/
public function testBuildMalformedSegmentFixtures($name, $expected)
{
$this->markAsInvalidCase();
}
}
38 changes: 38 additions & 0 deletions tests/Loader/LoaderIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3195,6 +3195,44 @@ public function provideFixturesToGenerate()
],
];

yield '[templating] reference range' => [
[
stdClass::class => [
'detailedDummy (template)' => [
'field' => 'value',
],
'dummy_1' => [
'email' => 'dummy1@mail.com',
],
'dummy_2' => [
'email' => 'dummy2@mail.com',
],
'detailedDummy_{@dummy_*} (extends detailedDummy)' => [
'dummy' => '<current()>'
],
],
],
[
'parameters' => [],
'objects' => [
'dummy_1' => $dummy1 = StdClassFactory::create([
'email' => 'dummy1@mail.com',
]),
'dummy_2' => $dummy2 = StdClassFactory::create([
'email' => 'dummy2@mail.com',
]),
'detailedDummy_dummy_1' => StdClassFactory::create([
'field' => 'value',
'dummy' => $dummy1
]),
'detailedDummy_dummy_2' => StdClassFactory::create([
'field' => 'value',
'dummy' => $dummy2
]),
],
],
];

yield '[current] nominal' => [
[
stdClass::class => [
Expand Down

0 comments on commit b1b2a51

Please sign in to comment.