/** * @param TemplatingFixture $fixture * @param FixtureReference[] $extendedFixtureReferences * @param FixtureBag $unresolvedFixtures * @param TemplatingFixtureBag $resolvedFixtures * @param ResolvingContext $context * * @throws FixtureNotFoundException * * @return array The first element is a FixtureBag with all the extended fixtures and the second is a * TemplatingFixtureBag which may contain new fixtures (from the resolution) */ private function resolveExtendedFixtures(TemplatingFixture $fixture, array $extendedFixtureReferences, FixtureBag $unresolvedFixtures, TemplatingFixtureBag $resolvedFixtures, ResolvingContext $context) : array { $fixtures = new FixtureBag(); foreach ($extendedFixtureReferences as $reference) { $fixtureId = $reference->getId(); $context->add($fixtureId); if (false === $unresolvedFixtures->has($fixtureId)) { throw FixtureNotFoundExceptionFactory::create($fixtureId); } if ($resolvedFixtures->has($fixtureId)) { if (false === $resolvedFixtures->hasTemplate($fixtureId)) { throw InvalidArgumentExceptionFactory::createForFixtureExtendingANonTemplateFixture($fixture, $fixtureId); } $fixtures = $fixtures->with($resolvedFixtures->getTemplate($fixtureId)); continue; } $unresolvedFixture = $unresolvedFixtures->get($fixtureId); if (false === $unresolvedFixture instanceof TemplatingFixture) { throw InvalidArgumentExceptionFactory::createForFixtureExtendingANonTemplateFixture($fixture, $fixtureId); } $resolvedFixtures = $this->resolve($unresolvedFixtures->get($fixtureId), $unresolvedFixtures, $resolvedFixtures, $context); $fixtures = $fixtures->with($resolvedFixtures->get($fixtureId)); } return [$fixtures, $resolvedFixtures]; }
public function testThrowsAnExceptionWhenACircularReferenceIsDetected() { $context = new ResolvingContext('bar'); $context->checkForCircularReference('foo'); $context->add('foo'); $context->checkForCircularReference('foo'); $context->add('foo'); try { $context->checkForCircularReference('foo'); $this->fail('Expected exception to be thrown.'); } catch (CircularReferenceException $exception) { $this->assertEquals('Circular reference detected for the parameter "foo" while resolving ["bar", "foo"].', $exception->getMessage()); } $context = new ResolvingContext('foo'); $context->checkForCircularReference('foo'); $context->add('foo'); try { $context->checkForCircularReference('foo'); $this->fail('Expected exception to be thrown.'); } catch (CircularReferenceException $exception) { $this->assertEquals('Circular reference detected for the parameter "foo" while resolving ["foo"].', $exception->getMessage()); } }
/** * @param ParameterResolverInterface $resolver * @param Parameter $parameter Parameter being resolved * @param string $key Key of the parameter that need to be resolved to resolve $parameter * @param ParameterBag $unresolvedParameters * @param ParameterBag $resolvedParameters * @param ResolvingContext $context * * @return ParameterBag */ private function resolveStringKey(ParameterResolverInterface $resolver = null, Parameter $parameter, string $key, ParameterBag $unresolvedParameters, ParameterBag $resolvedParameters, ResolvingContext $context) : ParameterBag { if ($resolvedParameters->has($key)) { return $resolvedParameters; } if (false === $unresolvedParameters->has($key)) { throw ParameterNotFoundExceptionFactory::createForWhenResolvingParameter($key, $parameter); } $context->checkForCircularReference($key); $context->add($key); if (null === $resolver) { throw ResolverNotFoundExceptionFactory::createUnexpectedCall(__METHOD__); } return $resolver->resolve(new Parameter($key, $unresolvedParameters->get($key)), $unresolvedParameters, $resolvedParameters, $context); }
/** * @inheritdoc */ public function resolve(Parameter $unresolvedArrayParameter, ParameterBag $unresolvedParameters, ParameterBag $resolvedParameters, ResolvingContext $context = null) : ParameterBag { if (null === $this->resolver) { throw ResolverNotFoundExceptionFactory::createUnexpectedCall(__METHOD__); } $context = ResolvingContext::createFrom($context, $unresolvedArrayParameter->getKey()); $resolvedArray = []; /* @var array $unresolvedArray */ $unresolvedArray = $unresolvedArrayParameter->getValue(); foreach ($unresolvedArray as $index => $unresolvedValue) { // Iterate over all the values of the array to resolve each of them $resolvedParameters = $this->resolver->resolve(new Parameter((string) $index, $unresolvedValue), $unresolvedParameters, $resolvedParameters, $context); $resolvedArray[$index] = $resolvedParameters->get((string) $index); $resolvedParameters = $resolvedParameters->without((string) $index); } $resolvedParameters = $resolvedParameters->with($unresolvedArrayParameter->withValue($resolvedArray)); return $resolvedParameters; }
/** * @param string $id * * @throws CircularReferenceException */ public function markIsResolvingFixture(string $id) { $this->resolving->add($id); $this->resolving->checkForCircularReference($id); }
public function testReuseContextIfOneIsFoundWhenResolvingDynamicParameter() { $parameter = new Parameter('foo', '<{bar}>'); $unresolvedParameters = new ParameterBag(['bar' => 'unresolved(bar)']); $resolvedParameters = new ParameterBag(); $context = new ResolvingContext('ping'); $context->add('foo'); $expected = new ParameterBag(['bar' => 'Mad Hatter', 'foo' => 'Mad Hatter']); $injectedResolverProphecy = $this->prophesize(ParameterResolverInterface::class); $injectedResolverProphecy->resolve(new Parameter('bar', 'unresolved(bar)'), $unresolvedParameters, $resolvedParameters, $context)->willReturn(new ParameterBag(['bar' => 'Mad Hatter'])); /* @var ParameterResolverInterface $injectedResolver */ $injectedResolver = $injectedResolverProphecy->reveal(); $resolver = (new StringParameterResolver())->withResolver($injectedResolver); $result = $resolver->resolve($parameter, $unresolvedParameters, $resolvedParameters, $context); $this->assertEquals($expected, $result); $injectedResolverProphecy->resolve(Argument::cetera())->shouldHaveBeenCalledTimes(1); }
public function provideContexts() { return ['no context' => [null, new ResolvingContext('array_param')], 'context that does not contain the parameter being resolved' => [new ResolvingContext('unrelated'), (function () { $context = new ResolvingContext('unrelated'); $context->add('array_param'); return $context; })()], 'context that contains the parameter being resolved' => [(function () { $context = new ResolvingContext('unrelated'); $context->add('array_param'); return $context; })(), (function () { $context = new ResolvingContext('unrelated'); $context->add('array_param'); return $context; })()]]; }
public function provideContexts() { return ['no context' => [null], 'empty context' => [new ResolvingContext()], 'context with random value' => [(function () { $context = new ResolvingContext(); $context->add('name'); return $context; })()]]; }