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