@@ -245,7 +245,7 @@ public function __invoke(ServerRequestInterface $request)
245245 $ this ->assertEquals ('42 ' , (string ) $ response ->getBody ());
246246 }
247247
248- public function testCallableReturnsCallableForUndefaultWithStringDefaultViaAutowiringWillDefaultToStringValue ()
248+ public function testCallableReturnsCallableForUntypedWithStringDefaultViaAutowiringWillDefaultToStringValue ()
249249 {
250250 $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
251251
@@ -274,6 +274,35 @@ public function __invoke(ServerRequestInterface $request)
274274 $ this ->assertEquals ('"empty" ' , (string ) $ response ->getBody ());
275275 }
276276
277+ /**
278+ * @requires PHP 8
279+ */
280+ public function testCallableReturnsCallableForMixedWithStringDefaultViaAutowiringWillDefaultToStringValue ()
281+ {
282+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
283+
284+ $ controller = new class (null ) {
285+ private $ data = false ;
286+
287+ #[PHP8 ] public function __construct (mixed $ data = 'empty ' ) { $ this ->data = $ data ; }
288+
289+ public function __invoke (ServerRequestInterface $ request )
290+ {
291+ return new Response (200 , [], json_encode ($ this ->data ));
292+ }
293+ };
294+
295+ $ container = new Container ([]);
296+
297+ $ callable = $ container ->callable (get_class ($ controller ));
298+ $ this ->assertInstanceOf (\Closure::class, $ callable );
299+
300+ $ response = $ callable ($ request );
301+ $ this ->assertInstanceOf (ResponseInterface::class, $ response );
302+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
303+ $ this ->assertEquals ('"empty" ' , (string ) $ response ->getBody ());
304+ }
305+
277306 public function testCallableReturnsCallableForClassNameViaAutowiringWithFactoryFunctionForDependency ()
278307 {
279308 $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
@@ -517,6 +546,152 @@ public function __invoke()
517546 $ this ->assertEquals ('{"name":"Alice"} ' , (string ) $ response ->getBody ());
518547 }
519548
549+ public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresUntypedContainerVariable ()
550+ {
551+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
552+
553+ $ controller = new class (new Response ()) {
554+ private $ response ;
555+
556+ public function __construct (ResponseInterface $ response )
557+ {
558+ $ this ->response = $ response ;
559+ }
560+
561+ public function __invoke ()
562+ {
563+ return $ this ->response ;
564+ }
565+ };
566+
567+ $ container = new Container ([
568+ ResponseInterface::class => function ($ data ) {
569+ return new Response (200 , [], json_encode ($ data ));
570+ },
571+ 'data ' => (object ) ['name ' => 'Alice ' ]
572+ ]);
573+
574+ $ callable = $ container ->callable (get_class ($ controller ));
575+ $ this ->assertInstanceOf (\Closure::class, $ callable );
576+
577+ $ response = $ callable ($ request );
578+ $ this ->assertInstanceOf (ResponseInterface::class, $ response );
579+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
580+ $ this ->assertEquals ('{"name":"Alice"} ' , (string ) $ response ->getBody ());
581+ }
582+
583+ public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresUntypedContainerVariableWithFactory ()
584+ {
585+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
586+
587+ $ controller = new class (new Response ()) {
588+ private $ response ;
589+
590+ public function __construct (ResponseInterface $ response )
591+ {
592+ $ this ->response = $ response ;
593+ }
594+
595+ public function __invoke ()
596+ {
597+ return $ this ->response ;
598+ }
599+ };
600+
601+ $ container = new Container ([
602+ ResponseInterface::class => function ($ data ) {
603+ return new Response (200 , [], json_encode ($ data ));
604+ },
605+ 'data ' => function () {
606+ return (object ) ['name ' => 'Alice ' ];
607+ }
608+ ]);
609+
610+ $ callable = $ container ->callable (get_class ($ controller ));
611+ $ this ->assertInstanceOf (\Closure::class, $ callable );
612+
613+ $ response = $ callable ($ request );
614+ $ this ->assertInstanceOf (ResponseInterface::class, $ response );
615+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
616+ $ this ->assertEquals ('{"name":"Alice"} ' , (string ) $ response ->getBody ());
617+ }
618+
619+ /**
620+ * @requires PHP 8
621+ */
622+ public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresMixedContainerVariable ()
623+ {
624+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
625+
626+ $ controller = new class (new Response ()) {
627+ private $ response ;
628+
629+ public function __construct (ResponseInterface $ response )
630+ {
631+ $ this ->response = $ response ;
632+ }
633+
634+ public function __invoke ()
635+ {
636+ return $ this ->response ;
637+ }
638+ };
639+
640+ $ container = new Container ([
641+ ResponseInterface::class => function (mixed $ data ) {
642+ return new Response (200 , [], json_encode ($ data ));
643+ },
644+ 'data ' => (object ) ['name ' => 'Alice ' ]
645+ ]);
646+
647+ $ callable = $ container ->callable (get_class ($ controller ));
648+ $ this ->assertInstanceOf (\Closure::class, $ callable );
649+
650+ $ response = $ callable ($ request );
651+ $ this ->assertInstanceOf (ResponseInterface::class, $ response );
652+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
653+ $ this ->assertEquals ('{"name":"Alice"} ' , (string ) $ response ->getBody ());
654+ }
655+
656+ /**
657+ * @requires PHP 8
658+ */
659+ public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresMixedContainerVariableWithFactory ()
660+ {
661+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
662+
663+ $ controller = new class (new Response ()) {
664+ private $ response ;
665+
666+ public function __construct (ResponseInterface $ response )
667+ {
668+ $ this ->response = $ response ;
669+ }
670+
671+ public function __invoke ()
672+ {
673+ return $ this ->response ;
674+ }
675+ };
676+
677+ $ container = new Container ([
678+ ResponseInterface::class => function (mixed $ data ) {
679+ return new Response (200 , [], json_encode ($ data ));
680+ },
681+ 'data ' => function () {
682+ return (object ) ['name ' => 'Alice ' ];
683+ }
684+ ]);
685+
686+ $ callable = $ container ->callable (get_class ($ controller ));
687+ $ this ->assertInstanceOf (\Closure::class, $ callable );
688+
689+ $ response = $ callable ($ request );
690+ $ this ->assertInstanceOf (ResponseInterface::class, $ response );
691+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
692+ $ this ->assertEquals ('{"name":"Alice"} ' , (string ) $ response ->getBody ());
693+ }
694+
520695 public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableContainerVariables ()
521696 {
522697 $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
@@ -1284,13 +1459,31 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresUntypedA
12841459 $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
12851460
12861461 $ container = new Container ([
1287- \stdClass::class => function ($ data ) { return $ data ; }
1462+ \stdClass::class => function ($ undefined ) { return $ undefined ; }
1463+ ]);
1464+
1465+ $ callable = $ container ->callable (\stdClass::class);
1466+
1467+ $ this ->expectException (\BadMethodCallException::class);
1468+ $ this ->expectExceptionMessage ('Argument 1 ($undefined) of {closure}() has no type ' );
1469+ $ callable ($ request );
1470+ }
1471+
1472+ /**
1473+ * @requires PHP 8
1474+ */
1475+ public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresUndefinedMixedArgument ()
1476+ {
1477+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
1478+
1479+ $ container = new Container ([
1480+ \stdClass::class => function (mixed $ undefined ) { return $ undefined ; }
12881481 ]);
12891482
12901483 $ callable = $ container ->callable (\stdClass::class);
12911484
12921485 $ this ->expectException (\BadMethodCallException::class);
1293- $ this ->expectExceptionMessage ('Argument 1 ($data ) of {closure}() has no type ' );
1486+ $ this ->expectExceptionMessage ('Argument 1 ($undefined ) of {closure}() is not defined ' );
12941487 $ callable ($ request );
12951488 }
12961489
0 commit comments