Skip to content

Commit

Permalink
Fix duplicate calls (nelmio#865)
Browse files Browse the repository at this point in the history
Rework of nelmio#858 which was not completely covering the issue.
  • Loading branch information
theofidry authored Feb 20, 2018
1 parent f19035c commit bedcd53
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 96 deletions.
41 changes: 0 additions & 41 deletions fixtures/Entity/DummyWithThrowableSetter.php

This file was deleted.

49 changes: 49 additions & 0 deletions fixtures/Entity/OnceTimerDummy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/*
* This file is part of the Alice package.
*
* (c) Nelmio <[email protected]>
*
* 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\Entity;

use BadMethodCallException;

class OnceTimerDummy
{
private $relatedDummy;
private $hydrate = false;
private $call = false;

public function setHydrate($hydrate) {
if ($this->hydrate) {
throw new BadMethodCallException();
}

$this->hydrate = $hydrate;
}

public function call($call)
{
if ($this->call) {
throw new BadMethodCallException();
}

$this->call = $call;
}

public function setRelatedDummy($dummy)
{
if (null !== $this->relatedDummy) {
throw new BadMethodCallException();
}

$this->relatedDummy = $dummy;
}
}
2 changes: 2 additions & 0 deletions src/Generator/DoublePassGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ public function generate(FixtureSet $fixtureSet): ObjectSet
private function generateFixtures(ResolvedFixtureSet $set, GenerationContext $context): ResolvedFixtureSet
{
$fixtures = $set->getFixtures();

foreach ($fixtures as $fixture) {
$objects = $this->generator->generate($fixture, $set, $context);

$set = $set->withObjects($objects);
}

Expand Down
10 changes: 9 additions & 1 deletion src/Generator/ObjectGenerator/SimpleObjectGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Nelmio\Alice\Generator\ObjectGenerator;

use Nelmio\Alice\Definition\Object\CompleteObject;
use Nelmio\Alice\FixtureInterface;
use Nelmio\Alice\Generator\CallerInterface;
use Nelmio\Alice\Generator\GenerationContext;
Expand Down Expand Up @@ -103,6 +104,13 @@ private function completeObject(
$set = $this->hydrator->hydrate($instantiatedObject, $set, $context);
$hydratedObject = $set->getObjects()->get($fixture);

return $this->caller->doCallsOn($hydratedObject, $set, $context);
$set = $this->caller->doCallsOn($hydratedObject, $set, $context);
$configuredObject = $set->getObjects()->get($fixture);

return $set->withObjects(
$set->getObjects()->with(
new CompleteObject($configuredObject)
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function resolve(FixtureSet $unresolvedFixtureSet): ResolvedFixtureSet

$fixtures = $resolvedFixtureSet->getFixtures();
$objects = $resolvedFixtureSet->getObjects();

foreach ($fixtures as $fixture) {
if ($objects->has($fixture)) {
$objects = $objects->without($fixture);
Expand Down
22 changes: 12 additions & 10 deletions src/Generator/Resolver/Value/Chainable/FixtureReferenceResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private function resolveReferredFixture(
string $referredFixtureId,
ResolvedFixtureSet $fixtureSet,
GenerationContext $context,
bool $passIncompleteObject = null
bool $passIncompleteObject = false
): ResolvedValueWithFixtureSet {
if ($fixtureSet->getObjects()->has($referredFixture)) {
$referredObject = $fixtureSet->getObjects()->get($referredFixture);
Expand All @@ -141,21 +141,23 @@ private function resolveReferredFixture(
try {
$needsCompleteGeneration = $context->needsCompleteGeneration();

if (!$passIncompleteObject) {
$context->markAsNeedsCompleteGeneration();
}
// Attempts to provide a complete object whenever possible
$passIncompleteObject ? $context->unmarkAsNeedsCompleteGeneration() : $context->markAsNeedsCompleteGeneration();

$context->markIsResolvingFixture($referredFixtureId);
$objects = $this->generator->generate($referredFixture, $fixtureSet, $context);
$fixtureSet = $fixtureSet->withObjects($objects);

if (false === $needsCompleteGeneration) {
$generatedObject = $objects->get($referredFixture);
$objects = $objects->with(new CompleteObject($generatedObject));
// Restore the context
$needsCompleteGeneration ? $context->markAsNeedsCompleteGeneration() : $context->unmarkAsNeedsCompleteGeneration();
// if (false === $needsCompleteGeneration) {
// $generatedObject = $objects->get($referredFixture);
// $objects = $objects->with(new CompleteObject($generatedObject));

$context->unmarkAsNeedsCompleteGeneration();
}
// $context->unmarkAsNeedsCompleteGeneration();
// }

$fixtureSet = $fixtureSet->withObjects($objects);
// $fixtureSet = $fixtureSet->withObjects($objects);

return new ResolvedValueWithFixtureSet(
$fixtureSet->getObjects()->get($referredFixture)->getInstance(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

use Nelmio\Alice\Definition\Fixture\FakeFixture;
use Nelmio\Alice\Definition\Fixture\SimpleFixture;
use Nelmio\Alice\Definition\Object\CompleteObject;
use Nelmio\Alice\Definition\Object\SimpleObject;
use Nelmio\Alice\Definition\SpecificationBagFactory;
use Nelmio\Alice\Definition\Value\DummyValue;
Expand Down Expand Up @@ -198,7 +197,7 @@ public function testIfTheReferenceRefersToANonInstantiatedFixtureThenGenerateItB
$generatorProphecy
->generate($referredFixture, $set, $generatorContext)
->willReturn(
$objects = new ObjectBag(['dummy' => $generatedObject = new SimpleObject('dummy', $expectedInstance = new \stdClass())])
$objects = new ObjectBag(['dummy' => $expectedInstance = new \stdClass()])
)
;
/** @var ObjectGeneratorInterface $generator */
Expand All @@ -209,7 +208,7 @@ public function testIfTheReferenceRefersToANonInstantiatedFixtureThenGenerateItB
ResolvedFixtureSetFactory::create(
null,
$fixtures,
$objects = $objects->with(new CompleteObject($generatedObject))
$objects
)
);

Expand Down
108 changes: 67 additions & 41 deletions tests/Loader/LoaderIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1883,42 +1883,13 @@ public function provideFixturesToHydrate()

public function provideFixturesToGenerate()
{

yield '[construct] with reference to object with throwable setter' => [
[
FixtureEntity\DummyWithThrowableSetter::class => [
'another_dummy' => [
'val' => 1
]
],
FixtureEntity\DummyWithConstructorParam::class => [
'dummy' => [
'__construct' => [
'@another_dummy'
]
]
]
],
[
'parameters' => [],
'objects' => [
'another_dummy' => $anotherDummy1 = (function (FixtureEntity\DummyWithThrowableSetter $anotherDummy1) {
$anotherDummy1->setVal(1);

return $anotherDummy1;
})(new FixtureEntity\DummyWithThrowableSetter()),
'dummy' => $dummy1 = new FixtureEntity\DummyWithConstructorParam($anotherDummy1),
]
]
];

yield '[construct] with reference to object with throwable setter and caller' => [
[
FixtureEntity\DummyWithThrowableSetter::class => [
FixtureEntity\OnceTimerDummy::class => [
'another_dummy' => [
'hydrated' => true,
'hydrate' => true,
'__calls' => [
['setVal' => [1]],
['call' => [true]],
]
]
],
Expand All @@ -1933,12 +1904,12 @@ public function provideFixturesToGenerate()
[
'parameters' => [],
'objects' => [
'another_dummy' => $anotherDummy1 = (function (FixtureEntity\DummyWithThrowableSetter $anotherDummy1) {
$anotherDummy1->setVal(1);
$anotherDummy1->setHydrated(true);
'another_dummy' => $yetAnotherDummy1 = (function (FixtureEntity\OnceTimerDummy $anotherDummy1) {
$anotherDummy1->call(true);
$anotherDummy1->setHydrate(true);
return $anotherDummy1;
})(new FixtureEntity\DummyWithThrowableSetter()),
'dummy' => $dummy1 = new FixtureEntity\DummyWithConstructorParam($anotherDummy1),
})(new FixtureEntity\OnceTimerDummy()),
'dummy' => $dummy1 = new FixtureEntity\DummyWithConstructorParam($yetAnotherDummy1),
]
]
];
Expand Down Expand Up @@ -2081,14 +2052,14 @@ public function provideFixturesToGenerate()
[
'parameters' => [],
'objects' => [
'another_dummy1' => $anotherDummy1 = StdClassFactory::create([
'another_dummy1' => $yetAnotherDummy1 = StdClassFactory::create([
'name' => '1',
]),
'another_dummy2' => $anotherDummy2 = StdClassFactory::create([
'name' => '2',
]),
'dummy1' => StdClassFactory::create([
'relatedDummy' => $anotherDummy1,
'relatedDummy' => $yetAnotherDummy1,
]),
'dummy2' => StdClassFactory::create([
'relatedDummy' => $anotherDummy2,
Expand Down Expand Up @@ -3597,6 +3568,61 @@ public function provideFixturesToGenerate()
];
})();

// https://github.com/nelmio/alice/issues/851
yield 'construct with multiple references to objects with throwable setter' => (function () {
return [
[
FixtureEntity\OnceTimerDummy::class => [
'dummy' => [
'relatedDummy' => '@anotherDummy',
'hydrate' => true,
'__calls' => [
['call' => [true]],
]
],
'anotherDummy' => [
'relatedDummy' => '@yetAnotherDummy',
'hydrate' => true,
'__calls' => [
['call' => [true]],
]
],
'yetAnotherDummy' => [
'hydrate' => true,
'__calls' => [
['call' => [true]],
]
]
]
],
[
'parameters' => [],
'objects' => [
'yetAnotherDummy' => $yetAnotherDummy = (function (FixtureEntity\OnceTimerDummy $dummy) {
$dummy->setHydrate(true);
$dummy->call(true);

return $dummy;
})(new FixtureEntity\OnceTimerDummy()),
'anotherDummy' => $anotherDummy = (function (FixtureEntity\OnceTimerDummy $dummy, $relatedDummy) {
$dummy->setRelatedDummy($relatedDummy);
$dummy->setHydrate(true);
$dummy->call(true);

return $dummy;
})(new FixtureEntity\OnceTimerDummy(), $yetAnotherDummy),
'dummy' => $dummy = (function (FixtureEntity\OnceTimerDummy $dummy, $relatedDummy) {
$dummy->setRelatedDummy($relatedDummy);
$dummy->setHydrate(true);
$dummy->call(true);

return $dummy;
})(new FixtureEntity\OnceTimerDummy(), $anotherDummy),
]
]
];
})();

// https://github.com/nelmio/alice/issues/770
yield 'typed parameters' => (function () {
return [
Expand All @@ -3619,8 +3645,8 @@ public function provideFixturesToGenerate()
],
'objects' => [
'dummy' => StdClassFactory::create([
'intParam' => 100,
'stringParam' => '100',
'intParam' => 100,
'stringParam' => '100',
]),
],
],
Expand Down

0 comments on commit bedcd53

Please sign in to comment.