From 3d8167a5740ccbfbf2f4f12207d6db5b587aaea1 Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Sun, 5 May 2019 09:34:16 +0200 Subject: [PATCH] Failing falsy order-dependent fixtures (#963) --- .../Fixture/SimpleFixtureBagDenormalizer.php | 42 ++++++++++++------ tests/Loader/SimpleFilesLoaderTest.php | 44 +++++++++++++++++++ 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/src/FixtureBuilder/Denormalizer/Fixture/SimpleFixtureBagDenormalizer.php b/src/FixtureBuilder/Denormalizer/Fixture/SimpleFixtureBagDenormalizer.php index 884f8df2e..fc042b0c1 100644 --- a/src/FixtureBuilder/Denormalizer/Fixture/SimpleFixtureBagDenormalizer.php +++ b/src/FixtureBuilder/Denormalizer/Fixture/SimpleFixtureBagDenormalizer.php @@ -18,11 +18,12 @@ use Nelmio\Alice\FixtureBuilder\Denormalizer\FixtureBagDenormalizerInterface; use Nelmio\Alice\FixtureBuilder\Denormalizer\FlagParserInterface; use Nelmio\Alice\IsAServiceTrait; +use Nelmio\Alice\Throwable\Exception\FixtureBuilder\Denormalizer\UnexpectedValueException; final class SimpleFixtureBagDenormalizer implements FixtureBagDenormalizerInterface { use IsAServiceTrait; - + /** * @var FixtureDenormalizerInterface */ @@ -56,7 +57,12 @@ public function __construct(FixtureDenormalizerInterface $fixtureDenormalizer, F public function denormalize(array $data): FixtureBag { $fixtures = new FixtureBag(); - foreach ($data as $fqcnWithFlags => $rawFixtureSet) { + + $alreadyRetried = []; + while ($result = array_splice($data, 0, 1)) { + $fqcnWithFlags = key($result); + $rawFixtureSet = current($result); + $flags = $this->flagParser->parse($fqcnWithFlags); $fqcn = $flags->getKey(); @@ -69,22 +75,30 @@ public function denormalize(array $data): FixtureBag ) ); } + try { + foreach ($rawFixtureSet as $reference => $specs) { + if (null === $specs) { + $specs = []; + } - foreach ($rawFixtureSet as $reference => $specs) { - if (null === $specs) { - $specs = []; + $fixtures = $this->fixtureDenormalizer->denormalize( + $fixtures, + $fqcn, + $reference, + $specs ?? [], + $flags + ); + } + } catch (UnexpectedValueException $exception) { + if (!isset($alreadyRetried[$fqcnWithFlags])) { + $data[$fqcnWithFlags] = $rawFixtureSet; + $alreadyRetried[$fqcnWithFlags] = true; + } else { + throw $exception; } - - $fixtures = $this->fixtureDenormalizer->denormalize( - $fixtures, - $fqcn, - $reference, - $specs ?? [], - $flags - ); } } - + return $fixtures; } } diff --git a/tests/Loader/SimpleFilesLoaderTest.php b/tests/Loader/SimpleFilesLoaderTest.php index 5f596e631..6c0fd682f 100644 --- a/tests/Loader/SimpleFilesLoaderTest.php +++ b/tests/Loader/SimpleFilesLoaderTest.php @@ -17,6 +17,8 @@ use Nelmio\Alice\FilesLoaderInterface; use Nelmio\Alice\ObjectSetFactory; use Nelmio\Alice\ParserInterface; +use Nelmio\Alice\User; +use Nelmio\Alice\UserDetail; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use ReflectionClass; @@ -104,4 +106,46 @@ public function testLoadFilesAndReturnsAnObjectSet() $parserProphecy->parse(Argument::cetera())->shouldHaveBeenCalledTimes(3); $dataLoaderProphecy->loadData(Argument::cetera())->shouldHaveBeenCalledTimes(1); } + + public function testLoadFilesWithDifferentOrder() + { + $file1 = 'dummy1.yml'; + $file2 = 'dummy2.yml'; + + $file1Data = [ + User::class => [ + 'user1' => [ + 'name' => '', + ], + ], + ]; + $file2Data = [ + UserDetail::class => [ + 'userdetail_{@user*}' => [ + 'email' => '', + ], + 'userdetail_single_{@user1}' => [ + 'email' => '', + ], + ], + ]; + + $parserProphecy = $this->prophesize(ParserInterface::class); + $parserProphecy->parse($file1)->willReturn($file1Data); + $parserProphecy->parse($file2)->willReturn($file2Data); + /** @var ParserInterface $parser */ + $parser = $parserProphecy->reveal(); + + $loader = new SimpleFilesLoader($parser, new IsolatedLoader()); + + $objects = $loader->loadFiles([$file2, $file1], [], [])->getObjects(); + self::assertArrayHasKey('user1', $objects); + self::assertArrayHasKey('userdetail_user1', $objects); + self::assertArrayHasKey('userdetail_single_user1', $objects); + + $objects = $loader->loadFiles([$file1, $file2], [], [])->getObjects(); + self::assertArrayHasKey('user1', $objects); + self::assertArrayHasKey('userdetail_user1', $objects); + self::assertArrayHasKey('userdetail_single_user1', $objects); + } }