public function provideHasValueSet() { $baseValue = new UniqueValue('foo', 'temporary value'); // Checks for null (yield '[null value] empty' => [new UniqueValuesPool(), $baseValue->withValue(null), false]); (yield '[null value] with `null' => [$this->createPoolWithValue(null), $baseValue->withValue(null), true]); (yield '[null value] with `false' => [$this->createPoolWithValue(false), $baseValue->withValue(null), false]); (yield '[null value] with empty array' => [$this->createPoolWithValue([]), $baseValue->withValue(null), false]); (yield '[null value] with empty string' => [$this->createPoolWithValue(''), $baseValue->withValue(null), false]); // Full checks for a scalar value (yield '[`true`] empty' => [new UniqueValuesPool(), $baseValue->withValue(true), false]); (yield '[`true`] with `true`' => [$this->createPoolWithValue(true), $baseValue->withValue(true), true]); (yield '[`true`] with `1`' => [$this->createPoolWithValue(1), $baseValue->withValue(true), false]); (yield '[`true`] with `-1`' => [$this->createPoolWithValue(-1), $baseValue->withValue(true), false]); (yield '[`true`] with `"1"`' => [$this->createPoolWithValue('1'), $baseValue->withValue(true), false]); (yield '[`true`] with `"-1"`' => [$this->createPoolWithValue('-1'), $baseValue->withValue(true), false]); (yield '[`true`] with `"alice"`' => [$this->createPoolWithValue('alice'), $baseValue->withValue(true), false]); // Check objects (yield 'with two equivalent objects' => [$this->createPoolWithValue(new \stdClass()), $baseValue->withValue(new \stdClass()), true]); (yield 'with two non-equivalent objects' => [$this->createPoolWithValue(new \stdClass()), $baseValue->withValue(StdClassFactory::create(['foo' => 'bar'])), false]); (yield 'with two equivalent objects (2)' => [$this->createPoolWithValue(StdClassFactory::create(['relatedDummy' => StdClassFactory::create(['foo' => 'bar'])])), $baseValue->withValue(StdClassFactory::create(['relatedDummy' => StdClassFactory::create(['foo' => 'bar'])])), true]); (yield 'with two non-equivalent objects (2)' => [$this->createPoolWithValue(StdClassFactory::create(['relatedDummy' => StdClassFactory::create(['foo' => 'bar'])])), $baseValue->withValue(StdClassFactory::create(['relatedDummy' => StdClassFactory::create(['foo' => new \stdClass()])])), false]); // Checks arrays (yield 'two identical arrays' => [$this->createPoolWithValue([]), $baseValue->withValue([]), true]); (yield 'two equivalent arrays' => [$this->createPoolWithValue([10, 20]), $baseValue->withValue([20, 10]), true]); (yield 'two equivalent arrays (2)' => [$this->createPoolWithValue([10, 'foo' => new \stdClass(), 20]), $baseValue->withValue([20, 10, 'foo' => new \stdClass()]), true]); (yield 'two non-equivalent arrays (2)' => [$this->createPoolWithValue([10, 20, 30]), $baseValue->withValue([20, 10]), false]); (yield 'two non-equivalent arrays (3)' => [$this->createPoolWithValue([1]), $baseValue->withValue([true]), false]); (yield 'two non-equivalent arrays (4)' => [$this->createPoolWithValue([10, 'foo' => StdClassFactory::create(['foo' => 'bar']), 20]), $baseValue->withValue([20, 10, 'foo' => new \stdClass()]), false]); }
public function testDelegatesImmutabilityToTheDecoratedObject() { // Case where the decorated object is mutable $decoratedObject = new SimpleObject('dummy', $instance = new \stdClass()); $object = new CompleteObject($decoratedObject); $instance->foo = 'bar'; $object->getInstance()->foz = 'baz'; $clone = clone $object; $instance->fao = 'bor'; $clone->getInstance()->faz = 'boz'; $this->assertEquals(StdClassFactory::create(['foo' => 'bar', 'foz' => 'baz', 'fao' => 'bor', 'faz' => 'boz']), $object->getInstance()); $this->assertEquals($object->getInstance(), $clone->getInstance()); // Case where the decorated object is partially immutable: cloning does create a new instance $decoratedObject = new ImmutableByCloneObject('dummy', $instance = new \stdClass()); $object = new CompleteObject($decoratedObject); $instance->foo = 'bar'; $object->getInstance()->foz = 'baz'; $clone = clone $object; $instance->fao = 'bor'; $clone->getInstance()->faz = 'boz'; $this->assertEquals(StdClassFactory::create(['foo' => 'bar', 'foz' => 'baz', 'fao' => 'bor']), $object->getInstance()); $this->assertEquals(StdClassFactory::create(['foo' => 'bar', 'foz' => 'baz', 'faz' => 'boz']), $clone->getInstance()); // Case where the decorated object is truly immutable $decoratedObject = new ImmutableObject('dummy', $instance = new \stdClass()); $object = new CompleteObject($decoratedObject); $instance->foo = 'bar'; $object->getInstance()->foz = 'baz'; $clone = clone $object; $instance->fao = 'bor'; $clone->getInstance()->faz = 'boz'; $this->assertEquals(new \stdClass(), $object->getInstance()); $this->assertEquals(new \stdClass(), $clone->getInstance()); }
public function testGenerateObjects() { $loadedParameters = new ParameterBag(['loaded' => true]); $injectedParameters = new ParameterBag(['injected' => true]); $fixture = new DummyFixture('dummy'); $fixtures = (new FixtureBag())->with($fixture); $objects = new ObjectBag(['std' => new \stdClass()]); $set = new FixtureSet($loadedParameters, $injectedParameters, $fixtures, $objects); $resolvedParameters = $injectedParameters->with(new Parameter('loaded', true)); $resolvedSet = new ResolvedFixtureSet($resolvedParameters, $fixtures, $objects); $resolverProphecy = $this->prophesize(FixtureSetResolverInterface::class); $resolverProphecy->resolve($set)->willReturn($resolvedSet); /** @var FixtureSetResolverInterface $resolver */ $resolver = $resolverProphecy->reveal(); $context = new GenerationContext(); $objectGeneratorProphecy = $this->prophesize(ObjectGeneratorInterface::class); $objectGeneratorProphecy->generate($fixture, $resolvedSet, $context)->willReturn($objectsAfterFirstPass = $objects->with(new SimpleObject('foo', StdClassFactory::create(['pass' => 'first'])))); $contextAfterFirstPass = clone $context; $contextAfterFirstPass->setToSecondPass(); $objectGeneratorProphecy->generate($fixture, new ResolvedFixtureSet($resolvedSet->getParameters(), $resolvedSet->getFixtures(), $objectsAfterFirstPass), $contextAfterFirstPass)->willReturn($objectsAfterFirstPass = $objects->with(new SimpleObject('foo', StdClassFactory::create(['pass' => 'second'])))); /** @var ObjectGeneratorInterface $objectGenerator */ $objectGenerator = $objectGeneratorProphecy->reveal(); $expected = new ObjectSet($resolvedParameters, $objects->with(new SimpleObject('foo', StdClassFactory::create(['pass' => 'second'])))); $generator = new DoublePassGenerator($resolver, $objectGenerator); $actual = $generator->generate($set); $this->assertEquals($expected, $actual); $resolverProphecy->resolve(Argument::any())->shouldHaveBeenCalledTimes(1); $objectGeneratorProphecy->generate(Argument::cetera())->shouldHaveBeenCalledTimes(2); }
public function testIsMutable() { $value = new \stdClass(); $definition = new Property('username', $value); // Mutate injected value $value->foo = 'bar'; // Mutate returned value $definition->getValue()->ping = 'pong'; $expected = StdClassFactory::create(['foo' => 'bar', 'ping' => 'pong']); $actual = $definition->getValue(); $this->assertEquals($expected, $actual); }
public function testNamedConstructor() { $reference = 'user0'; $instance = StdClassFactory::create(['original' => true]); $originalInstance = clone $instance; $object = new SimpleObject($reference, $instance); $newInstance = StdClassFactory::create(['original' => false]); $originalNewInstance = clone $newInstance; $newObject = $object->withInstance($newInstance); $this->assertEquals(new SimpleObject($reference, $originalInstance), $object); $this->assertEquals(new SimpleObject($reference, $originalNewInstance), $newObject); }
public function testCanCreateANewInstanceWithArguments() { $method = 'setUsername'; $arguments = null; $definition = new SimpleMethodCall($method, $arguments); $newArguments = [$arg0 = new \stdClass()]; $newDefinition = $definition->withArguments($newArguments); // Mutate before reading values $arg0->foo = 'bar'; $this->assertInstanceOf(SimpleMethodCall::class, $newDefinition); $this->assertNull($definition->getCaller()); $this->assertEquals($method, $definition->getMethod()); $this->assertEquals($arguments, $definition->getArguments()); $this->assertEquals($method, $definition->__toString()); $this->assertNull($newDefinition->getCaller()); $this->assertEquals($method, $newDefinition->getMethod()); $this->assertEquals([StdClassFactory::create(['foo' => 'bar'])], $newDefinition->getArguments()); $this->assertEquals($method, $newDefinition->__toString()); }
public function testCanCreateANewInstanceWithArguments() { $methodCall = new SimpleMethodCall('getUsername', null); $definition = new OptionalMethodCall($methodCall, new OptionalFlag(30)); $newArguments = [$arg0 = new \stdClass()]; $newDefinition = $definition->withArguments($newArguments); // Mutate arguments before reading it $arg0->foo = 'bar'; $this->assertInstanceOf(OptionalMethodCall::class, $newDefinition); $this->assertEquals($methodCall->getCaller(), $definition->getCaller()); $this->assertEquals(30, $definition->getPercentage()); $this->assertEquals($methodCall->getMethod(), $definition->getMethod()); $this->assertEquals($methodCall->getArguments(), $definition->getArguments()); $this->assertEquals($methodCall->getCaller(), $newDefinition->getCaller()); $this->assertEquals(30, $newDefinition->getPercentage()); $this->assertEquals($methodCall->getMethod(), $newDefinition->getMethod()); $this->assertEquals([StdClassFactory::create(['foo' => 'bar'])], $newDefinition->getArguments()); }
public function testStdClassPropertiesAreReadableOnlyIfTheyExists() { $object = StdClassFactory::create(['foo' => 'bar']); $accessor = new StdPropertyAccessor(new FakePropertyAccessor()); $this->assertTrue($accessor->isReadable($object, 'foo')); $this->assertFalse($accessor->isReadable($object, 'foz')); }
public function testCanCreateANewInstanceWithArguments() { $caller = new InstantiatedReference('user.factory'); $method = 'setUsername'; $arguments = [new \stdClass()]; $definition = new MethodCallWithReference($caller, $method, $arguments); $newArguments = [$arg0 = new \stdClass()]; $newDefinition = $definition->withArguments($newArguments); // Mutate argument before reading it $arg0->foo = 'bar'; $this->assertInstanceOf(MethodCallWithReference::class, $newDefinition); $this->assertEquals($caller, $definition->getCaller()); $this->assertEquals($method, $definition->getMethod()); $this->assertEquals($arguments, $definition->getArguments()); $this->assertEquals($caller, $newDefinition->getCaller()); $this->assertEquals($method, $newDefinition->getMethod()); $this->assertEquals([StdClassFactory::create(['foo' => 'bar'])], $newDefinition->getArguments()); }
public function provideFixturesToGenerate() { (yield 'empty instance' => [[\stdClass::class => ['dummy' => []]], ['parameters' => [], 'objects' => ['dummy' => new \stdClass()]]]); (yield 'static value' => [[\stdClass::class => ['dummy' => ['foo' => 'bar']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar'])]]]); (yield 'reference value' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['dummy' => '@dummy']]], ['parameters' => [], 'objects' => ['dummy' => $dummy = StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['dummy' => $dummy])]]]); (yield 'inverted reference value' => [[\stdClass::class => ['another_dummy' => ['dummy' => '@dummy'], 'dummy' => ['foo' => 'bar']]], ['parameters' => [], 'objects' => ['dummy' => $dummy = StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['dummy' => $dummy])]]]); (yield 'dynamic reference' => [[\stdClass::class => ['dummy{1..2}' => ['name' => '<current()>'], 'another_dummy{1..2}' => ['dummy' => '@dummy<current()>']]], ['parameters' => [], 'objects' => ['dummy1' => $dummy1 = StdClassFactory::create(['name' => '1']), 'dummy2' => $dummy2 = StdClassFactory::create(['name' => '2']), 'another_dummy1' => StdClassFactory::create(['dummy' => $dummy1]), 'another_dummy2' => StdClassFactory::create(['dummy' => $dummy2])]]]); (yield 'inverted dynamic reference' => [[\stdClass::class => ['dummy{1..2}' => ['relatedDummy' => '@another_dummy<current()>'], 'another_dummy{1..2}' => ['name' => '<current()>']]], ['parameters' => [], 'objects' => ['another_dummy1' => $anotherDummy1 = StdClassFactory::create(['name' => '1']), 'another_dummy2' => $anotherDummy2 = StdClassFactory::create(['name' => '2']), 'dummy1' => StdClassFactory::create(['relatedDummy' => $anotherDummy1]), 'dummy2' => StdClassFactory::create(['relatedDummy' => $anotherDummy2])]]]); (yield 'property reference value' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['foo' => '@dummy->foo']]], ['parameters' => [], 'objects' => ['dummy' => $dummy = StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['foo' => 'bar'])]]]); (yield 'inverted property reference value' => [[\stdClass::class => ['dummy' => ['name' => '@another_dummy->name'], 'another_dummy' => ['name' => 'foo']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['name' => 'foo']), 'another_dummy' => StdClassFactory::create(['name' => 'foo'])]]]); (yield 'non existing property reference' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['foo' => '@dummy->bob']]], null]); (yield 'property reference value with a getter' => [[DummyWithGetter::class => ['dummy' => ['name' => 'foo'], 'another_dummy' => ['name' => '@dummy->name']]], ['parameters' => [], 'objects' => ['dummy' => $dummy = (new DummyWithGetter())->setName('foo'), 'another_dummy' => (new DummyWithGetter())->setName('__get__foo')]]]); (yield 'inverted property reference value with a getter' => [[DummyWithGetter::class => ['dummy' => ['name' => '@another_dummy->name'], 'another_dummy' => ['name' => 'foo']]], ['parameters' => [], 'objects' => ['dummy' => $dummy = (new DummyWithGetter())->setName('__get__foo'), 'another_dummy' => (new DummyWithGetter())->setName('foo')]]]); (yield 'array value' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['dummies' => ['@dummy', '@dummy', '@dummy']]]], ['parameters' => [], 'objects' => ['dummy' => $dummy = StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['dummies' => [$dummy, $dummy, $dummy]])]]]); (yield 'wildcard reference value' => [[\stdClass::class => ['dummy_0' => ['foo' => 'bar'], 'another_dummy' => ['dummy' => '@dummy*']]], ['parameters' => [], 'objects' => ['dummy_0' => $dummy = StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['dummy' => $dummy])]]]); (yield 'wildcard property reference value' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['foo' => '@dummy*->foo']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['foo' => 'bar'])]]]); (yield 'dynamic array value' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['dummies' => '3x @dummy']]], ['parameters' => [], 'objects' => ['dummy' => $dummy = StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['dummies' => [$dummy, $dummy, $dummy]])]]]); (yield 'array value' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['dummies' => ['@dummy', '@dummy', '@dummy']]]], ['parameters' => [], 'objects' => ['dummy' => $dummy = StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['dummies' => [$dummy, $dummy, $dummy]])]]]); (yield 'dynamic array value with wildcard' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['dummies' => '3x @dummy*']]], ['parameters' => [], 'objects' => ['dummy' => $dummy = StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['dummies' => [$dummy, $dummy, $dummy]])]]]); (yield 'objects with dots in their references' => [[\stdClass::class => ['user.alice' => ['username' => 'alice'], 'user.alias.alice_alias' => ['username' => '@user.alice->username'], 'user.deep_alias' => ['username' => '@user.alias.alice_alias->username']]], ['parameters' => [], 'objects' => ['user.alice' => StdClassFactory::create(['username' => 'alice']), 'user.alias.alice_alias' => StdClassFactory::create(['username' => 'alice']), 'user.deep_alias' => StdClassFactory::create(['username' => 'alice'])]]]); (yield '[special characters] references with underscores' => [[\stdClass::class => ['user_alice' => ['username' => 'alice'], 'user_alias' => ['username' => '@user_alice->username'], 'user_deep_alias' => ['username' => '@user_alias->username']]], ['parameters' => [], 'objects' => ['user_alice' => StdClassFactory::create(['username' => 'alice']), 'user_alias' => StdClassFactory::create(['username' => 'alice']), 'user_deep_alias' => StdClassFactory::create(['username' => 'alice'])]]]); (yield '[special characters] references with slashes' => [[\stdClass::class => ['user/alice' => ['username' => 'alice'], 'user/alias/alice_alias' => ['username' => '@user/alice->username'], 'user/deep_alias' => ['username' => '@user/alias/alice_alias->username']]], ['parameters' => [], 'objects' => ['user/alice' => StdClassFactory::create(['username' => 'alice']), 'user/alias/alice_alias' => StdClassFactory::create(['username' => 'alice']), 'user/deep_alias' => StdClassFactory::create(['username' => 'alice'])]]]); (yield '[provider] faker functions' => [[\stdClass::class => ['dummy' => ['foo' => '<numberBetween(0, 0)>']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 0])]]]); (yield '[function] call PHP native function' => [[\stdClass::class => ['dummy' => ['foo' => '<strtolower("BAR")>']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar'])]]]); (yield '[self reference] alone' => [[\stdClass::class => ['dummy' => ['itself' => '@self']]], ['parameters' => [], 'objects' => ['dummy' => (function () { $dummy = new \stdClass(); $dummy->itself = $dummy; return $dummy; })()]]]); (yield '[self reference] evaluated with a function' => [[\stdClass::class => ['dummy' => ['itself' => '@<("self")>']]], ['parameters' => [], 'objects' => ['dummy' => (function () { $dummy = new \stdClass(); $dummy->itself = $dummy; return $dummy; })()]]]); (yield '[self reference] property' => [[\stdClass::class => ['dummy' => ['foo' => 'bar', 'itself' => '@self']]], ['parameters' => [], 'objects' => ['dummy' => (function () { $dummy = new \stdClass(); $dummy->foo = 'bar'; $dummy->itself = $dummy; return $dummy; })()]]]); (yield 'identity provider' => [[\stdClass::class => ['dummy' => ['foo' => 'bar', 'identity_foo' => '<identity($foo)>'], 'another_dummy' => ['foo' => 'bar_baz', 'identity_foo' => '<identity(str_replace("_", " ", $foo))>']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar', 'identity_foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['foo' => 'bar_baz', 'identity_foo' => 'bar baz'])]]]); (yield '[self reference] alone' => [[\stdClass::class => ['dummy' => ['itself' => '@self']]], ['parameters' => [], 'objects' => ['dummy' => (function () { $dummy = new \stdClass(); $dummy->itself = $dummy; return $dummy; })()]]]); (yield '[self reference] property' => [[\stdClass::class => ['dummy' => ['foo' => 'bar', 'itself' => '@self']]], ['parameters' => [], 'objects' => ['dummy' => (function () { $dummy = new \stdClass(); $dummy->foo = 'bar'; $dummy->itself = $dummy; return $dummy; })()]]]); (yield '[variable] nominal' => [[\Nelmio\Alice\Entity\DummyWithGetter::class => ['dummy' => ['foo' => 'bar', 'fooVal' => '$foo'], 'another_dummy' => ['foo' => 'bar', 'fooVal' => '@self->foo']]], ['parameters' => [], 'objects' => ['dummy' => (function (\Nelmio\Alice\Entity\DummyWithGetter $dummy) { $dummy->setFoo('bar'); $dummy->fooVal = 'bar'; return $dummy; })(new \Nelmio\Alice\Entity\DummyWithGetter()), 'another_dummy' => (function (\Nelmio\Alice\Entity\DummyWithGetter $dummy) { $dummy->setFoo('bar'); $dummy->fooVal = 'rab'; return $dummy; })(new \Nelmio\Alice\Entity\DummyWithGetter())]]]); (yield '[variable] variables are scoped to the fixture' => [[\Nelmio\Alice\Entity\DummyWithGetter::class => ['dummy' => ['foo' => 'bar', 'fooVal' => '$foo'], 'another_dummy' => ['foo' => '$foo']]], null]); (yield '[identity] evaluate the argument as if it was a plain PHP function' => [[\stdClass::class => ['dummy' => ['foo' => '<("Hello"." "."world!")>', 'bar' => '<(str_replace("_", " ", "Hello_world!"))>']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'Hello world!', 'bar' => 'Hello world!'])]]]); (yield '[identity] has access to variables' => [[\stdClass::class => ['dummy' => ['foo' => 'bar', 'foz' => '<($foo)>']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar', 'foz' => 'bar'])]]]); (yield '[identity] has access to fixtures' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['foo' => '<(@dummy->foo)>']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['foo' => 'bar'])]]]); (yield '[identity] has access to current' => [[\stdClass::class => ['dummy_{1..2}' => ['foo' => '<($current)>']]], ['parameters' => [], 'objects' => ['dummy_1' => StdClassFactory::create(['foo' => '1']), 'dummy_2' => StdClassFactory::create(['foo' => '2'])]]]); (yield '[templating] templates are not returned' => [[\stdClass::class => ['base_dummy (template)' => [], 'dummy' => []]], ['parameters' => [], 'objects' => ['dummy' => new \stdClass()]]]); (yield '[templating] nominal' => [[\stdClass::class => ['base_dummy (template)' => ['foo' => 'bar'], 'another_base_dummy (template)' => ['foo' => 'baz', 'ping' => 'pong'], 'dummy0 (extends base_dummy, extends another_base_dummy)' => ['foo' => 'baz', 'ping' => 'pong'], 'dummy1 (extends another_base_dummy, extends base_dummy)' => ['foo' => 'bar', 'ping' => 'pong']]], ['parameters' => [], 'objects' => ['dummy0' => StdClassFactory::create(['foo' => 'baz', 'ping' => 'pong']), 'dummy1' => StdClassFactory::create(['foo' => 'bar', 'ping' => 'pong'])]]]); (yield '[current] nominal' => [[\stdClass::class => ['dummy{1..2}' => ['val' => '<current()>'], 'dummy_{alice, bob}' => ['val' => '<current()>']]], ['parameters' => [], 'objects' => ['dummy1' => StdClassFactory::create(['val' => 1]), 'dummy2' => StdClassFactory::create(['val' => 2]), 'dummy_alice' => StdClassFactory::create(['val' => 'alice']), 'dummy_bob' => StdClassFactory::create(['val' => 'bob'])]]]); (yield '[current] in constructor' => [[DummyWithConstructorParam::class => ['dummy{1..2}' => ['__construct' => ['<current()>']], 'dummy_{alice, bob}' => ['__construct' => ['<current()>']]]], ['parameters' => [], 'objects' => ['dummy1' => new DummyWithConstructorParam(1), 'dummy2' => new DummyWithConstructorParam(2), 'dummy_alice' => new DummyWithConstructorParam('alice'), 'dummy_bob' => new DummyWithConstructorParam('bob')]]]); (yield 'at literal is not resolved' => [[\stdClass::class => ['dummy' => ['atValues' => ['\\@<("hello")>', '\\\\', '\\\\\\@foo', '\\\\foo']]]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['atValues' => ['@hello', '\\', '\\@foo', '\\foo']])]]]); (yield '[parameter] simple' => [['parameters' => ['foo' => 'bar'], \stdClass::class => ['dummy' => ['foo' => '<{foo}>']]], ['parameters' => ['foo' => 'bar'], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar'])]]]); (yield '[parameter] array parameter' => [['parameters' => ['foo' => ['bar']], \stdClass::class => ['dummy' => ['foo' => '<randomElement(<{foo}>)>']]], ['parameters' => ['foo' => ['bar']], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar'])]]]); (yield '[parameter] composite parameter' => [['parameters' => ['foo' => 'NaN', 'bar' => 'Bat', 'composite' => '<{foo}> <{bar}>!'], \stdClass::class => ['dummy' => ['foo' => '<{foo}> <{bar}>!'], 'another_dummy' => ['foo' => '<{composite}>']]], ['parameters' => ['foo' => 'NaN', 'bar' => 'Bat', 'composite' => 'NaN Bat!'], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'NaN Bat!']), 'another_dummy' => StdClassFactory::create(['foo' => 'NaN Bat!'])]]]); (yield '[parameter] nested parameter' => [['parameters' => ['param1' => 2, 'param2' => 1, 'param3' => '<{param<{param2}>}>'], 'objects' => []], ['parameters' => ['param1' => 2, 'param2' => 1, 'param3' => '2'], 'objects' => []]]); (yield '[parameter] circular reference' => [['parameters' => ['foo' => '<{bar}>', 'bar' => '<{foo}>']], null]); (yield 'dynamic array with scalar value' => [[\stdClass::class => ['dummy' => ['foo' => '5x bar']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => ['bar', 'bar', 'bar', 'bar', 'bar']])]]]); (yield 'object circular reference' => [[DummyWithConstructorParam::class => ['dummy' => ['__construct' => ['@another_dummy']], 'another_dummy' => ['__construct' => ['@dummy']]]], null]); (yield 'has proper stdClass support' => [[\stdClass::class => ['dummy' => ['foo' => 'bar'], 'another_dummy' => ['foo' => '@dummy->foo']]], ['parameters' => [], 'objects' => ['dummy' => StdClassFactory::create(['foo' => 'bar']), 'another_dummy' => StdClassFactory::create(['foo' => 'bar'])]]]); }
public function testIfTheReferenceRefersToAnInstantiatedFixtureAndRequiresToBeCompleteThenGenerateIt() { $value = new FixtureReferenceValue('dummy'); $fixture = new FakeFixture(); $set = ResolvedFixtureSetFactory::create(null, $fixtures = (new FixtureBag())->with($referredFixture = new SimpleFixture('dummy', 'Dummy', SpecificationBagFactory::create())), (new ObjectBag())->with(new SimpleObject('dummy', $expectedInstance = new \stdClass()))); $scope = []; $context = new GenerationContext(); $context->markAsNeedsCompleteGeneration(); $generatorContext = new GenerationContext(); $generatorContext->markIsResolvingFixture('dummy'); $generatorContext->markAsNeedsCompleteGeneration(); $generatorProphecy = $this->prophesize(ObjectGeneratorInterface::class); $generatorProphecy->generate($referredFixture, $set, $generatorContext)->willReturn($objects = new ObjectBag(['dummy' => $expectedInstance = StdClassFactory::create(['complete' => true])])); /** @var ObjectGeneratorInterface $generator */ $generator = $generatorProphecy->reveal(); $expected = new ResolvedValueWithFixtureSet($expectedInstance, ResolvedFixtureSetFactory::create(null, $fixtures, $objects)); $resolver = new FixtureReferenceResolver($generator); $actual = $resolver->resolve($value, $fixture, $set, $scope, $context); $this->assertEquals($expected, $actual); $this->assertEquals($context, $generatorContext); $generatorProphecy->generate(Argument::cetera())->shouldHaveBeenCalledTimes(1); }