@@ -211,15 +211,15 @@ public function testCreateDefinition()
211
211
$ pass ->process ($ container );
212
212
213
213
$ 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 ));
215
215
216
- $ dunglasDefinition = $ container ->getDefinition ('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas ' );
216
+ $ dunglasDefinition = $ container ->getDefinition ('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas ' );
217
217
$ this ->assertEquals (__NAMESPACE__ .'\Dunglas ' , $ dunglasDefinition ->getClass ());
218
218
$ this ->assertFalse ($ dunglasDefinition ->isPublic ());
219
219
$ 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 ));
221
221
222
- $ lilleDefinition = $ container ->getDefinition ('autowired.symfony\component\dependencyinjection\tests\compiler\lille ' );
222
+ $ lilleDefinition = $ container ->getDefinition ('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille ' );
223
223
$ this ->assertEquals (__NAMESPACE__ .'\Lille ' , $ lilleDefinition ->getClass ());
224
224
}
225
225
@@ -429,6 +429,107 @@ public function testOptionalScalarArgsNotPassedIfLast()
429
429
);
430
430
}
431
431
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
+
432
533
public function testIgnoreServiceWithClassNotExisting ()
433
534
{
434
535
$ container = new ContainerBuilder ();
@@ -443,6 +544,37 @@ public function testIgnoreServiceWithClassNotExisting()
443
544
444
545
$ this ->assertTrue ($ container ->hasDefinition ('bar ' ));
445
546
}
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
+ }
446
578
}
447
579
448
580
class Foo
@@ -598,3 +730,91 @@ public function __construct(A $a, $foo = 'default_val', Lille $lille)
598
730
{
599
731
}
600
732
}
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
+ }
0 commit comments