Skip to content

Commit 38e2f9e

Browse files
Merge branch '2.7' into 2.8
* 2.7: [DI] Dont share service when no id provided Fix Container and PhpDumper test inaccuracies [DI] Fix missing new line after private alias [ClassLoader] Throw an exception if the cache is not writeable Fixing regression in TwigEngine exception handling.
2 parents 90920c5 + 2bfb62e commit 38e2f9e

File tree

6 files changed

+241
-19
lines changed

6 files changed

+241
-19
lines changed

ContainerBuilder.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV
449449
}
450450

451451
if (!array_key_exists($id, $this->definitions) && isset($this->aliasDefinitions[$id])) {
452-
return $this->get($this->aliasDefinitions[$id], $invalidBehavior);
452+
return $this->get((string) $this->aliasDefinitions[$id], $invalidBehavior);
453453
}
454454

455455
try {
@@ -1145,15 +1145,15 @@ private function callMethod($service, $call)
11451145
/**
11461146
* Shares a given service in the container.
11471147
*
1148-
* @param Definition $definition
1149-
* @param mixed $service
1150-
* @param string $id
1148+
* @param Definition $definition
1149+
* @param mixed $service
1150+
* @param string|null $id
11511151
*
11521152
* @throws InactiveScopeException
11531153
*/
11541154
private function shareService(Definition $definition, $service, $id)
11551155
{
1156-
if ($definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
1156+
if (null !== $id && $definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
11571157
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
11581158
throw new InactiveScopeException($id, $scope);
11591159
}

Dumper/YamlDumper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ private function addServiceAlias($alias, $id)
188188
return sprintf(" %s: '@%s'\n", $alias, $id);
189189
}
190190

191-
return sprintf(" %s:\n alias: %s\n public: false", $alias, $id);
191+
return sprintf(" %s:\n alias: %s\n public: false\n", $alias, $id);
192192
}
193193

194194
/**

Tests/Compiler/AutowirePassTest.php

Lines changed: 224 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,15 @@ public function testCreateDefinition()
211211
$pass->process($container);
212212

213213
$this->assertCount(1, $container->getDefinition('coop_tilleuls')->getArguments());
214-
$this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0));
214+
$this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0));
215215

216-
$dunglasDefinition = $container->getDefinition('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas');
216+
$dunglasDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas');
217217
$this->assertEquals(__NAMESPACE__.'\Dunglas', $dunglasDefinition->getClass());
218218
$this->assertFalse($dunglasDefinition->isPublic());
219219
$this->assertCount(1, $dunglasDefinition->getArguments());
220-
$this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\lille', $dunglasDefinition->getArgument(0));
220+
$this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille', $dunglasDefinition->getArgument(0));
221221

222-
$lilleDefinition = $container->getDefinition('autowired.symfony\component\dependencyinjection\tests\compiler\lille');
222+
$lilleDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille');
223223
$this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
224224
}
225225

@@ -429,6 +429,107 @@ public function testOptionalScalarArgsNotPassedIfLast()
429429
);
430430
}
431431

432+
public function testSetterInjection()
433+
{
434+
$container = new ContainerBuilder();
435+
$container->register('app_foo', Foo::class);
436+
$container->register('app_a', A::class);
437+
$container->register('app_collision_a', CollisionA::class);
438+
$container->register('app_collision_b', CollisionB::class);
439+
440+
// manually configure *one* call, to override autowiring
441+
$container
442+
->register('setter_injection', SetterInjection::class)
443+
->setAutowiredMethods(array('__construct', 'set*'))
444+
->addMethodCall('setWithCallsConfigured', array('manual_arg1', 'manual_arg2'))
445+
;
446+
447+
$pass = new AutowirePass();
448+
$pass->process($container);
449+
450+
$methodCalls = $container->getDefinition('setter_injection')->getMethodCalls();
451+
452+
// grab the call method names
453+
$actualMethodNameCalls = array_map(function ($call) {
454+
return $call[0];
455+
}, $methodCalls);
456+
$this->assertEquals(
457+
array('setWithCallsConfigured', 'setFoo', 'setDependencies'),
458+
$actualMethodNameCalls
459+
);
460+
461+
// test setWithCallsConfigured args
462+
$this->assertEquals(
463+
array('manual_arg1', 'manual_arg2'),
464+
$methodCalls[0][1]
465+
);
466+
// test setFoo args
467+
$this->assertEquals(
468+
array(new Reference('app_foo')),
469+
$methodCalls[1][1]
470+
);
471+
}
472+
473+
public function testExplicitMethodInjection()
474+
{
475+
$container = new ContainerBuilder();
476+
$container->register('app_foo', Foo::class);
477+
$container->register('app_a', A::class);
478+
$container->register('app_collision_a', CollisionA::class);
479+
$container->register('app_collision_b', CollisionB::class);
480+
481+
$container
482+
->register('setter_injection', SetterInjection::class)
483+
->setAutowiredMethods(array('setFoo', 'notASetter'))
484+
;
485+
486+
$pass = new AutowirePass();
487+
$pass->process($container);
488+
489+
$methodCalls = $container->getDefinition('setter_injection')->getMethodCalls();
490+
491+
$actualMethodNameCalls = array_map(function ($call) {
492+
return $call[0];
493+
}, $methodCalls);
494+
$this->assertEquals(
495+
array('setFoo', 'notASetter'),
496+
$actualMethodNameCalls
497+
);
498+
}
499+
500+
/**
501+
* @dataProvider getCreateResourceTests
502+
*/
503+
public function testCreateResourceForClass($className, $isEqual)
504+
{
505+
$startingResource = AutowirePass::createResourceForClass(
506+
new \ReflectionClass(__NAMESPACE__.'\ClassForResource')
507+
);
508+
$newResource = AutowirePass::createResourceForClass(
509+
new \ReflectionClass(__NAMESPACE__.'\\'.$className)
510+
);
511+
512+
// hack so the objects don't differ by the class name
513+
$startingReflObject = new \ReflectionObject($startingResource);
514+
$reflProp = $startingReflObject->getProperty('class');
515+
$reflProp->setAccessible(true);
516+
$reflProp->setValue($startingResource, __NAMESPACE__.'\\'.$className);
517+
518+
if ($isEqual) {
519+
$this->assertEquals($startingResource, $newResource);
520+
} else {
521+
$this->assertNotEquals($startingResource, $newResource);
522+
}
523+
}
524+
525+
public function getCreateResourceTests()
526+
{
527+
return array(
528+
array('IdenticalClassResource', true),
529+
array('ClassChangedConstructorArgs', false),
530+
);
531+
}
532+
432533
public function testIgnoreServiceWithClassNotExisting()
433534
{
434535
$container = new ContainerBuilder();
@@ -443,6 +544,37 @@ public function testIgnoreServiceWithClassNotExisting()
443544

444545
$this->assertTrue($container->hasDefinition('bar'));
445546
}
547+
548+
/**
549+
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
550+
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "setter_injection_collision". Multiple services exist for this interface (c1, c2).
551+
* @expectedExceptionCode 1
552+
*/
553+
public function testSetterInjectionCollisionThrowsException()
554+
{
555+
$container = new ContainerBuilder();
556+
557+
$container->register('c1', CollisionA::class);
558+
$container->register('c2', CollisionB::class);
559+
$aDefinition = $container->register('setter_injection_collision', SetterInjectionCollision::class);
560+
$aDefinition->setAutowiredMethods(array('__construct', 'set*'));
561+
562+
$pass = new AutowirePass();
563+
$pass->process($container);
564+
}
565+
566+
public function testLogUnusedPatterns()
567+
{
568+
$container = new ContainerBuilder();
569+
570+
$definition = $container->register('foo', Foo::class);
571+
$definition->setAutowiredMethods(array('not', 'exist*'));
572+
573+
$pass = new AutowirePass();
574+
$pass->process($container);
575+
576+
$this->assertEquals(array(AutowirePass::class.': Autowiring\'s patterns "not", "exist*" for service "foo" don\'t match any method.'), $container->getCompiler()->getLog());
577+
}
446578
}
447579

448580
class Foo
@@ -598,3 +730,91 @@ public function __construct(A $a, $foo = 'default_val', Lille $lille)
598730
{
599731
}
600732
}
733+
734+
/*
735+
* Classes used for testing createResourceForClass
736+
*/
737+
class ClassForResource
738+
{
739+
public function __construct($foo, Bar $bar = null)
740+
{
741+
}
742+
743+
public function setBar(Bar $bar)
744+
{
745+
}
746+
}
747+
class IdenticalClassResource extends ClassForResource
748+
{
749+
}
750+
751+
class ClassChangedConstructorArgs extends ClassForResource
752+
{
753+
public function __construct($foo, Bar $bar, $baz)
754+
{
755+
}
756+
}
757+
758+
class SetterInjection
759+
{
760+
public function setFoo(Foo $foo)
761+
{
762+
// should be called
763+
}
764+
765+
public function setDependencies(Foo $foo, A $a)
766+
{
767+
// should be called
768+
}
769+
770+
public function setBar()
771+
{
772+
// should not be called
773+
}
774+
775+
public function setNotAutowireable(NotARealClass $n)
776+
{
777+
// should not be called
778+
}
779+
780+
public function setArgCannotAutowire($foo)
781+
{
782+
// should not be called
783+
}
784+
785+
public function setOptionalNotAutowireable(NotARealClass $n = null)
786+
{
787+
// should not be called
788+
}
789+
790+
public function setOptionalNoTypeHint($foo = null)
791+
{
792+
// should not be called
793+
}
794+
795+
public function setOptionalArgNoAutowireable($other = 'default_val')
796+
{
797+
// should not be called
798+
}
799+
800+
public function setWithCallsConfigured(A $a)
801+
{
802+
// this method has a calls configured on it
803+
// should not be called
804+
}
805+
806+
public function notASetter(A $a)
807+
{
808+
// should be called only when explicitly specified
809+
}
810+
}
811+
812+
class SetterInjectionCollision
813+
{
814+
public function setMultipleInstancesForOneArg(CollisionInterface $collision)
815+
{
816+
// The CollisionInterface cannot be autowired - there are multiple
817+
818+
// should throw an exception
819+
}
820+
}

Tests/ContainerTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public function testSet()
134134
{
135135
$sc = new Container();
136136
$sc->set('foo', $foo = new \stdClass());
137-
$this->assertEquals($foo, $sc->get('foo'), '->set() sets a service');
137+
$this->assertSame($foo, $sc->get('foo'), '->set() sets a service');
138138
}
139139

140140
public function testSetWithNullResetTheService()
@@ -204,15 +204,15 @@ public function testGet()
204204
{
205205
$sc = new ProjectServiceContainer();
206206
$sc->set('foo', $foo = new \stdClass());
207-
$this->assertEquals($foo, $sc->get('foo'), '->get() returns the service for the given id');
208-
$this->assertEquals($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
209-
$this->assertEquals($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
210-
$this->assertEquals($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
211-
$this->assertEquals($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
212-
$this->assertEquals($sc->__foo_baz, $sc->get('foo\\baz'), '->get() returns the service if a get*Method() is defined');
207+
$this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id');
208+
$this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
209+
$this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
210+
$this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
211+
$this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
212+
$this->assertSame($sc->__foo_baz, $sc->get('foo\\baz'), '->get() returns the service if a get*Method() is defined');
213213

214214
$sc->set('bar', $bar = new \stdClass());
215-
$this->assertEquals($bar, $sc->get('bar'), '->get() prefers to return a service defined with set() than one defined with a getXXXMethod()');
215+
$this->assertSame($bar, $sc->get('bar'), '->get() prefers to return a service defined with set() than one defined with a getXXXMethod()');
216216

217217
try {
218218
$sc->get('');

Tests/Dumper/PhpDumperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ public function testOverrideServiceWhenUsingADumpedContainer()
230230
$container->set('bar', $bar = new \stdClass());
231231
$container->setParameter('foo_bar', 'foo_bar');
232232

233-
$this->assertEquals($bar, $container->get('bar'), '->set() overrides an already defined service');
233+
$this->assertSame($bar, $container->get('bar'), '->set() overrides an already defined service');
234234
}
235235

236236
public function testOverrideServiceWhenUsingADumpedContainerAndServiceIsUsedFromAnotherOne()

Tests/Fixtures/yaml/services6.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ services:
2121
another_alias_for_foo:
2222
alias: foo
2323
public: false
24+
another_third_alias_for_foo:
25+
alias: foo
2426
decorator_service:
2527
decorates: decorated
2628
decorator_service_with_name:

0 commit comments

Comments
 (0)