@@ -309,6 +309,145 @@ public function testAttributesAreFallbacks()
309309
310310 $ this ->assertEquals (['z ' => new TypedReference ('service_attr_first ' , MultiTagHelloNamedService::class)], $ services );
311311 }
312+
313+ public function testTaggedIteratorWithDefaultNameMethod ()
314+ {
315+ $ container = new ContainerBuilder ();
316+ $ container ->register ('service ' , ClassWithDefaultNameMethod::class)->addTag ('my_custom_tag ' );
317+
318+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
319+
320+ $ tag = new TaggedIteratorArgument ('my_custom_tag ' );
321+ $ services = $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
322+ $ this ->assertEquals ([new Reference ('service ' )], $ services );
323+ }
324+
325+ public function testIndexedIteratorUsesTagAttributeOverDefaultMethod ()
326+ {
327+ $ container = new ContainerBuilder ();
328+ $ container ->register ('service.a ' , ServiceWithStaticGetType::class)
329+ ->addTag ('my_tag ' , ['type ' => 'from_tag ' ]);
330+
331+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
332+
333+ $ tag = new TaggedIteratorArgument ('my_tag ' , 'type ' , 'getType ' );
334+ $ services = $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
335+
336+ $ this ->assertArrayHasKey ('from_tag ' , $ services );
337+ $ this ->assertArrayNotHasKey ('from_static_method ' , $ services );
338+ $ this ->assertInstanceOf (TypedReference::class, $ services ['from_tag ' ]);
339+ $ this ->assertSame ('service.a ' , (string ) $ services ['from_tag ' ]);
340+ }
341+
342+ public function testIndexedIteratorUsesDefaultMethodAsFallback ()
343+ {
344+ $ container = new ContainerBuilder ();
345+ $ container ->register ('service.a ' , ServiceWithStaticGetType::class)
346+ ->addTag ('my_tag ' );
347+
348+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
349+
350+ $ tag = new TaggedIteratorArgument ('my_tag ' , 'type ' , 'getType ' );
351+ $ services = $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
352+
353+ $ this ->assertArrayHasKey ('from_static_method ' , $ services );
354+ $ this ->assertArrayNotHasKey ('from_tag ' , $ services );
355+ $ this ->assertInstanceOf (TypedReference::class, $ services ['from_static_method ' ]);
356+ }
357+
358+ public function testIndexedIteratorUsesTagIndexAndDefaultPriorityMethod ()
359+ {
360+ $ container = new ContainerBuilder ();
361+
362+ $ container ->register ('service.a ' , ServiceWithStaticPriority::class)
363+ ->addTag ('my_tag ' , ['type ' => 'tag_index ' ]);
364+
365+ $ container ->register ('service.b ' , \stdClass::class)
366+ ->addTag ('my_tag ' , ['type ' => 'another_index ' ]);
367+
368+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
369+
370+ $ tag = new TaggedIteratorArgument ('my_tag ' , 'type ' , null , 'getPriority ' );
371+ $ services = $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
372+
373+ $ this ->assertArrayHasKey ('tag_index ' , $ services );
374+ $ this ->assertSame ('service.a ' , (string ) $ services ['tag_index ' ]);
375+
376+ $ this ->assertSame (['tag_index ' , 'another_index ' ], array_keys ($ services ));
377+ }
378+
379+ public function testTaggedLocatorWithProvidedIndexAttributeAndNonStaticDefaultIndexMethod ()
380+ {
381+ $ container = new ContainerBuilder ();
382+ $ container ->register ('service ' , NonStaticDefaultIndexClass::class)
383+ ->addTag ('my_custom_tag ' , ['type ' => 'foo ' ]);
384+
385+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
386+ $ tag = new TaggedIteratorArgument ('my_custom_tag ' , 'type ' , 'getType ' );
387+
388+ $ services = $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
389+ $ this ->assertEquals (['foo ' => new TypedReference ('service ' , NonStaticDefaultIndexClass::class)], $ services );
390+ }
391+
392+ public function testTaggedLocatorWithoutIndexAttributeAndNonStaticDefaultIndexMethod ()
393+ {
394+ $ this ->expectException (InvalidArgumentException::class);
395+ $ this ->expectExceptionMessage (\sprintf ('Either method "%s::getType()" should be static or tag "my_custom_tag" on service "service" is missing attribute "type". ' , NonStaticDefaultIndexClass::class));
396+
397+ $ container = new ContainerBuilder ();
398+ $ container ->register ('service ' , NonStaticDefaultIndexClass::class)
399+ ->addTag ('my_custom_tag ' );
400+
401+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
402+ $ tag = new TaggedIteratorArgument ('my_custom_tag ' , 'type ' , 'getType ' );
403+
404+ $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
405+ }
406+
407+ public function testMergingAsTaggedItemWithEmptyTagAndNonStaticBusinessMethod ()
408+ {
409+ $ container = new ContainerBuilder ();
410+ $ container ->register ('service ' , AsTaggedItemClassWithBusinessMethod::class)
411+ ->setAutoconfigured (true )
412+ ->addTag ('my_custom_tag ' );
413+
414+ (new ResolveInstanceofConditionalsPass ())->process ($ container );
415+
416+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
417+ $ tag = new TaggedIteratorArgument ('my_custom_tag ' , 'index ' );
418+
419+ $ services = $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
420+ $ this ->assertEquals (['bar ' => new TypedReference ('service ' , AsTaggedItemClassWithBusinessMethod::class)], $ services );
421+ }
422+
423+ public function testPriorityFallbackWithoutIndexAndStaticPriorityMethod ()
424+ {
425+ $ container = new ContainerBuilder ();
426+ $ container ->register ('service ' , StaticPriorityClass::class)
427+ ->addTag ('my_custom_tag ' );
428+
429+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
430+ $ tag = new TaggedIteratorArgument ('my_custom_tag ' , null , null , false , 'getDefaultPriority ' );
431+
432+ $ services = $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
433+ $ this ->assertEquals ([new Reference ('service ' )], $ services );
434+ }
435+
436+ public function testMultiTagsWithMixedAttributesAndNonStaticDefault ()
437+ {
438+ $ container = new ContainerBuilder ();
439+ $ container ->register ('service ' , MultiTagNonStaticClass::class)
440+ ->addTag ('my_custom_tag ' , ['type ' => 'foo ' ])
441+ ->addTag ('my_custom_tag ' );
442+
443+ $ priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation ();
444+ $ tag = new TaggedIteratorArgument ('my_custom_tag ' , 'type ' , 'getType ' );
445+
446+ $ services = $ priorityTaggedServiceTraitImplementation ->test ($ tag , $ container );
447+ $ this ->assertCount (2 , $ services );
448+ $ this ->assertArrayHasKey ('foo ' , $ services );
449+ $ this ->assertArrayHasKey ('default ' , $ services );
450+ }
312451}
313452
314453class PriorityTaggedServiceTraitImplementation
@@ -342,3 +481,60 @@ interface HelloInterface
342481{
343482 public static function getFooBar (): string ;
344483}
484+
485+ class ClassWithDefaultNameMethod
486+ {
487+ public function getDefaultName (): string
488+ {
489+ return 'foo ' ;
490+ }
491+ }
492+
493+ class ServiceWithStaticGetType
494+ {
495+ public static function getType (): string
496+ {
497+ return 'from_static_method ' ;
498+ }
499+ }
500+
501+ class ServiceWithStaticPriority
502+ {
503+ public static function getPriority (): int
504+ {
505+ return 10 ;
506+ }
507+ }
508+
509+ class NonStaticDefaultIndexClass
510+ {
511+ public function getType (): string
512+ {
513+ return 'foo ' ;
514+ }
515+ }
516+
517+ #[AsTaggedItem(index: 'bar ' )]
518+ class AsTaggedItemClassWithBusinessMethod
519+ {
520+ public function getDefaultName (): string
521+ {
522+ return 'ignored ' ;
523+ }
524+ }
525+
526+ class StaticPriorityClass
527+ {
528+ public static function getDefaultPriority (): int
529+ {
530+ return 10 ;
531+ }
532+ }
533+
534+ class MultiTagNonStaticClass
535+ {
536+ public static function getType (): string
537+ {
538+ return 'default ' ;
539+ }
540+ }
0 commit comments