@@ -274,6 +274,77 @@ public function __invoke(ServerRequestInterface $request)
274274 $ this ->assertEquals ('{"name":"Alice"} ' , (string ) $ response ->getBody ());
275275 }
276276
277+ public function testCallableReturnsCallableForClassNameMappedFromFactoryWithStringVariableMappedFromFactory ()
278+ {
279+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
280+
281+ $ controller = new class (new \stdClass ()) {
282+ private $ data ;
283+
284+ public function __construct (\stdClass $ data )
285+ {
286+ $ this ->data = $ data ;
287+ }
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+ \stdClass::class => function (string $ username ) {
297+ return (object ) ['name ' => $ username ];
298+ },
299+ 'username ' => function () {
300+ return 'Alice ' ;
301+ }
302+ ]);
303+
304+ $ callable = $ container ->callable (get_class ($ controller ));
305+
306+ $ response = $ callable ($ request );
307+ $ this ->assertInstanceOf (ResponseInterface::class, $ response );
308+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
309+ $ this ->assertEquals ('{"name":"Alice"} ' , (string ) $ response ->getBody ());
310+ }
311+
312+ public function testCallableReturnsCallableForClassNameReferencingVariableMappedFromFactoryReferencingVariable ()
313+ {
314+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
315+
316+ $ controller = new class (new \stdClass ()) {
317+ private $ data ;
318+
319+ public function __construct (\stdClass $ data )
320+ {
321+ $ this ->data = $ data ;
322+ }
323+
324+ public function __invoke (ServerRequestInterface $ request )
325+ {
326+ return new Response (200 , [], json_encode ($ this ->data ));
327+ }
328+ };
329+
330+ $ container = new Container ([
331+ \stdClass::class => function (string $ username ) {
332+ return (object ) ['name ' => $ username ];
333+ },
334+ 'username ' => function (string $ role ) {
335+ return strtoupper ($ role );
336+ },
337+ 'role ' => 'admin '
338+ ]);
339+
340+ $ callable = $ container ->callable (get_class ($ controller ));
341+
342+ $ response = $ callable ($ request );
343+ $ this ->assertInstanceOf (ResponseInterface::class, $ response );
344+ $ this ->assertEquals (200 , $ response ->getStatusCode ());
345+ $ this ->assertEquals ('{"name":"ADMIN"} ' , (string ) $ response ->getBody ());
346+ }
347+
277348 public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesUnknownVariable ()
278349 {
279350 $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
@@ -305,7 +376,71 @@ public function __invoke(ServerRequestInterface $request)
305376 $ callable ($ request );
306377 }
307378
308- public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesVariableOfUnexpectedType ()
379+ public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesRecursiveVariable ()
380+ {
381+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
382+
383+ $ controller = new class (new \stdClass ()) {
384+ private $ data ;
385+
386+ public function __construct (\stdClass $ data )
387+ {
388+ $ this ->data = $ data ;
389+ }
390+
391+ public function __invoke (ServerRequestInterface $ request )
392+ {
393+ return new Response (200 , [], json_encode ($ this ->data ));
394+ }
395+ };
396+
397+ $ container = new Container ([
398+ \stdClass::class => function (string $ stdClass ) {
399+ return (object ) ['name ' => $ stdClass ];
400+ }
401+ ]);
402+
403+ $ callable = $ container ->callable (get_class ($ controller ));
404+
405+ $ this ->expectException (\BadMethodCallException::class);
406+ $ this ->expectExceptionMessage ('Container variable $stdClass is recursive ' );
407+ $ callable ($ request );
408+ }
409+
410+ public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesVariableMappedWithUnexpectedType ()
411+ {
412+ $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
413+
414+ $ controller = new class ('' ) {
415+ private $ data ;
416+
417+ public function __construct (string $ stdClass )
418+ {
419+ $ this ->data = $ stdClass ;
420+ }
421+
422+ public function __invoke (ServerRequestInterface $ request )
423+ {
424+ return new Response (200 , [], json_encode ($ this ->data ));
425+ }
426+ };
427+
428+ $ container = new Container ([
429+ get_class ($ controller ) => function (string $ stdClass ) use ($ controller ) {
430+ $ class = get_class ($ controller );
431+ return new $ class ($ stdClass );
432+ },
433+ \stdClass::class => (object ) []
434+ ]);
435+
436+ $ callable = $ container ->callable (get_class ($ controller ));
437+
438+ $ this ->expectException (\BadMethodCallException::class);
439+ $ this ->expectExceptionMessage ('Container variable $stdClass expected type string, but got stdClass ' );
440+ $ callable ($ request );
441+ }
442+
443+ public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesVariableMappedFromFactoryWithUnexpectedReturnType ()
309444 {
310445 $ request = new ServerRequest ('GET ' , 'http://example.com/ ' );
311446
@@ -328,14 +463,14 @@ public function __invoke(ServerRequestInterface $request)
328463 return (object ) ['name ' => $ http ];
329464 },
330465 'http ' => function () {
331- return ' http/3 ' ;
466+ return 3 ;
332467 }
333468 ]);
334469
335470 $ callable = $ container ->callable (get_class ($ controller ));
336471
337472 $ this ->expectException (\BadMethodCallException::class);
338- $ this ->expectExceptionMessage ('Container variable $http expected type string, but got Closure ' );
473+ $ this ->expectExceptionMessage ('Container variable $http expected type string from factory , but got integer ' );
339474 $ callable ($ request );
340475 }
341476
0 commit comments