+ public function testOptionalArgsNoRequiredForCoreClasses()
+ {
+ $container = new ContainerBuilder();
+
+ $container->register('foo', \SplFileObject::class)
+ ->addArgument('foo.txt')
+ ->setAutowired(true);
+
+ (new AutowirePass())->process($container);
+
+ $definition = $container->getDefinition('foo');
+ $this->assertEquals(
+ array('foo.txt'),
+ $definition->getArguments()
+ );
+ }
+
+ public function testSetterInjection()
+ {
+ $container = new ContainerBuilder();
+ $container->register(Foo::class);
+ $container->register(A::class);
+ $container->register(CollisionA::class);
+ $container->register(CollisionB::class);
+
+ // manually configure *one* call, to override autowiring
+ $container
+ ->register('setter_injection', SetterInjection::class)
+ ->setAutowired(true)
+ ->addMethodCall('setWithCallsConfigured', array('manual_arg1', 'manual_arg2'))
+ ;
+
+ (new ResolveClassPass())->process($container);
+ (new AutowireRequiredMethodsPass())->process($container);
+ (new AutowirePass())->process($container);
+
+ $methodCalls = $container->getDefinition('setter_injection')->getMethodCalls();
+
+ $this->assertEquals(
+ array('setWithCallsConfigured', 'setFoo', 'setDependencies', 'setChildMethodWithoutDocBlock'),
+ array_column($methodCalls, 0)
+ );
+
+ // test setWithCallsConfigured args
+ $this->assertEquals(
+ array('manual_arg1', 'manual_arg2'),
+ $methodCalls[0][1]
+ );
+ // test setFoo args
+ $this->assertEquals(
+ array(new TypedReference(Foo::class, Foo::class, SetterInjection::class)),
+ $methodCalls[1][1]
+ );
+ }
+
+ public function testExplicitMethodInjection()
+ {
+ $container = new ContainerBuilder();
+ $container->register(Foo::class);
+ $container->register(A::class);
+ $container->register(CollisionA::class);
+ $container->register(CollisionB::class);
+
+ $container
+ ->register('setter_injection', SetterInjection::class)
+ ->setAutowired(true)
+ ->addMethodCall('notASetter', array())
+ ;
+
+ (new ResolveClassPass())->process($container);
+ (new AutowireRequiredMethodsPass())->process($container);
+ (new AutowirePass())->process($container);
+
+ $methodCalls = $container->getDefinition('setter_injection')->getMethodCalls();
+
+ $this->assertEquals(
+ array('notASetter', 'setFoo', 'setDependencies', 'setWithCallsConfigured', 'setChildMethodWithoutDocBlock'),
+ array_column($methodCalls, 0)
+ );
+ $this->assertEquals(
+ array(new TypedReference(A::class, A::class, SetterInjection::class)),
+ $methodCalls[0][1]
+ );
+ }
+
+ /**
+ * @group legacy
+ * @expectedDeprecation Relying on service auto-registration for type "Symfony\Component\DependencyInjection\Tests\Compiler\A" is deprecated since Symfony 3.4 and won't be supported in 4.0. Create a service named "Symfony\Component\DependencyInjection\Tests\Compiler\A" instead.
+ */
+ public function testTypedReference()
+ {
+ $container = new ContainerBuilder();
+
+ $container
+ ->register('bar', Bar::class)
+ ->setProperty('a', array(new TypedReference(A::class, A::class, Bar::class)))
+ ;
+
+ $pass = new AutowirePass();
+ $pass->process($container);
+
+ $this->assertSame(A::class, $container->getDefinition('autowired.'.A::class)->getClass());
+ }
+