@@ -743,7 +743,7 @@ public function __invoke(): ResponseInterface
743743 }
744744 };
745745
746- $ fn = $ data = null ;
746+ $ fn = null ;
747747 $ fn = #[PHP8 ] fn (mixed $ data = 42 ) => new Response (200 , [], (string ) json_encode ($ data )); // @phpstan-ignore-line
748748 $ container = new Container ([
749749 ResponseInterface::class => $ fn ,
@@ -1906,31 +1906,52 @@ public function testGetEnvReturnsStringFromMapFactory(): void
19061906 /**
19071907 * @requires PHP 8
19081908 */
1909- public function testGetEnvReturnsNullFromFactoryForUnsupportedUnionVariableWithNullDefaultEvenForKnownVariable (): void
1909+ public function testGetEnvReturnsStringFromFactoryFunctionWithUnionType (): void
19101910 {
19111911 $ fn = null ;
1912- $ fn = #[PHP8 ] function (string |int | null $ bar = null ) { return $ bar ; };
1912+ $ fn = #[PHP8 ] function (string |int $ X_UNION ) { return ( string ) $ X_UNION ; };
19131913 $ container = new Container ([
19141914 'X_FOO ' => $ fn ,
1915- 'bar ' => ' ignored '
1915+ 'X_UNION ' => 42
19161916 ]);
19171917
1918- $ this ->assertNull ( $ container ->getEnv ('X_FOO ' ));
1918+ $ this ->assertEquals ( ' 42 ' , $ container ->getEnv ('X_FOO ' ));
19191919 }
19201920
19211921 /**
1922- * @requires PHP 8
1922+ * @requires PHP 8.1
19231923 */
1924- public function testGetEnvReturnsStringFromFactoryForUnsupportedUnionVariableWithStringDefaultEvenForKnownVariable (): void
1924+ public function testGetEnvReturnsStringFromFactoryFunctionWithIntersectionType (): void
19251925 {
1926- $ fn = null ;
1927- $ fn = #[ PHP8 ] function (string | int | null $ bar = ' default ' ) { return $ bar ; };
1926+ // eval to avoid syntax error on PHP < 8.1
1927+ $ fn = eval ( ' return function (\Traversable&\Stringable $X_UNION ) { return (string) $X_UNION ; }; ' ) ;
19281928 $ container = new Container ([
19291929 'X_FOO ' => $ fn ,
1930- 'bar ' => 'ignored '
1930+ 'X_UNION ' => new class implements \IteratorAggregate, \Stringable {
1931+ public function __toString (): string { return '42 ' ; }
1932+ public function getIterator (): \Traversable { yield from []; }
1933+ }
19311934 ]);
19321935
1933- $ this ->assertEquals ('default ' , $ container ->getEnv ('X_FOO ' ));
1936+ $ this ->assertEquals ('42 ' , $ container ->getEnv ('X_FOO ' ));
1937+ }
1938+
1939+ /**
1940+ * @requires PHP 8.2
1941+ */
1942+ public function testGetEnvReturnsStringFromFactoryFunctionWithDnfType (): void
1943+ {
1944+ // eval to avoid syntax error on PHP < 8.2
1945+ $ fn = eval ('return function (float|(\Traversable&\Stringable)|string $X_UNION) { return (string) $X_UNION; }; ' );
1946+ $ container = new Container ([
1947+ 'X_FOO ' => $ fn ,
1948+ 'X_UNION ' => new class implements \IteratorAggregate, \Stringable {
1949+ public function __toString (): string { return '42 ' ; }
1950+ public function getIterator (): \Traversable { yield from []; }
1951+ }
1952+ ]);
1953+
1954+ $ this ->assertEquals ('42 ' , $ container ->getEnv ('X_FOO ' ));
19341955 }
19351956
19361957 public function testGetEnvReturnsNullFromFactoryForUnknownNullableVariableWithNullDefault (): void
@@ -1954,7 +1975,7 @@ public function testGetEnvReturnsStringFromFactoryForUnknownVariableWithStringDe
19541975 /**
19551976 * @requires PHP 8
19561977 */
1957- public function testGetEnvReturnsNullFromFactoryForUnknownAndUnsupportedUnionVariableWithNullDefault (): void
1978+ public function testGetEnvReturnsNullFromFactoryForUnknownUnionVariableWithNullDefault (): void
19581979 {
19591980 $ fn = null ;
19601981 $ fn = #[PHP8 ] function (string |int |null $ X_UNDEFINED = null ) { return $ X_UNDEFINED ; };
@@ -1968,7 +1989,7 @@ public function testGetEnvReturnsNullFromFactoryForUnknownAndUnsupportedUnionVar
19681989 /**
19691990 * @requires PHP 8
19701991 */
1971- public function testGetEnvReturnsStringFromFactoryForUnknownAndUnsupportedUnionVariableWithStringDefault (): void
1992+ public function testGetEnvReturnsStringFromFactoryForUnknownUnionVariableWithStringDefault (): void
19721993 {
19731994 $ fn = null ;
19741995 $ fn = #[PHP8 ] function (string |int |null $ X_UNDEFINED = 'default ' ) { return $ X_UNDEFINED ; };
@@ -2266,6 +2287,57 @@ public function testGetEnvThrowsWhenFactoryFunctionExpectsRequiredMixedEnvVariab
22662287 $ container ->getEnv ('X_FOO ' );
22672288 }
22682289
2290+ /**
2291+ * @requires PHP 8
2292+ */
2293+ public function testGetEnvThrowsWhenFactoryFunctionExpectsUnionTypeButNoneGiven (): void
2294+ {
2295+ $ line = __LINE__ + 2 ;
2296+ $ fn = null ;
2297+ $ fn = #[PHP8 ] function (string |int |null $ X_UNDEFINED ) { return $ X_UNDEFINED ; };
2298+ $ container = new Container ([
2299+ 'X_FOO ' => $ fn
2300+ ]);
2301+
2302+ $ this ->expectException (\Error::class);
2303+ $ this ->expectExceptionMessage ('Argument #1 ($X_UNDEFINED) of {closure: ' . __FILE__ . ': ' . $ line . '}() for $X_FOO requires container config with type string|int|null, none given ' );
2304+ $ container ->getEnv ('X_FOO ' );
2305+ }
2306+
2307+ /**
2308+ * @requires PHP 8.1
2309+ */
2310+ public function testGetEnvThrowsWhenFactoryFunctionExpectsIntersectionTypeButNoneGiven (): void
2311+ {
2312+ $ line = __LINE__ + 2 ;
2313+ // eval to avoid syntax error on PHP < 8.1
2314+ $ fn = eval ('return function (\Traversable&\Stringable $X_UNDEFINED) { return (string) $X_UNDEFINED; }; ' );
2315+ $ container = new Container ([
2316+ 'X_FOO ' => $ fn
2317+ ]);
2318+
2319+ $ this ->expectException (\Error::class);
2320+ $ this ->expectExceptionMessage ('Argument #1 ($X_UNDEFINED) of {closure: ' . __FILE__ . '( ' . $ line . ') : eval() \'d code:1}() for $X_FOO requires container config with type Traversable&Stringable, none given ' );
2321+ $ container ->getEnv ('X_FOO ' );
2322+ }
2323+
2324+ /**
2325+ * @requires PHP 8.2
2326+ */
2327+ public function testGetEnvThrowsWhenFactoryFunctionExpectsDnfTypeButNoneGiven (): void
2328+ {
2329+ $ line = __LINE__ + 2 ;
2330+ // eval to avoid syntax error on PHP < 8.2
2331+ $ fn = eval ('return function (float|(\Traversable&\Stringable)|string $X_UNDEFINED) { return (string) $X_UNDEFINED; }; ' );
2332+ $ container = new Container ([
2333+ 'X_FOO ' => $ fn
2334+ ]);
2335+
2336+ $ this ->expectException (\Error::class);
2337+ $ this ->expectExceptionMessage ('Argument #1 ($X_UNDEFINED) of {closure: ' . __FILE__ . '( ' . $ line . ') : eval() \'d code:1}() for $X_FOO requires container config with type (Traversable&Stringable)|string|float, none given ' );
2338+ $ container ->getEnv ('X_FOO ' );
2339+ }
2340+
22692341 public function testGetEnvThrowsWhenFactoryFunctionExpectsNullableIntArgumentButGivenString (): void
22702342 {
22712343 $ line = __LINE__ + 2 ;
@@ -2282,35 +2354,54 @@ public function testGetEnvThrowsWhenFactoryFunctionExpectsNullableIntArgumentBut
22822354 /**
22832355 * @requires PHP 8
22842356 */
2285- public function testGetEnvThrowsWhenFactoryFunctionExpectsUnsupportedUnionType (): void
2357+ public function testGetEnvThrowsWhenFactoryFunctionExpectsUnionTypeButWrongTypeGiven (): void
22862358 {
22872359 $ line = __LINE__ + 2 ;
22882360 $ fn = null ;
22892361 $ fn = #[PHP8 ] function (string |int $ X_UNION ) { return (string ) $ X_UNION ; };
22902362 $ container = new Container ([
22912363 'X_FOO ' => $ fn ,
2292- 'X_UNION ' => 42
2364+ 'X_UNION ' => false
22932365 ]);
22942366
2295- $ this ->expectException (\Error ::class);
2296- $ this ->expectExceptionMessage ('Argument #1 ($X_UNION) of {closure: ' . __FILE__ . ': ' . $ line . '}() for $X_FOO expects unsupported type string|int ' );
2367+ $ this ->expectException (\TypeError ::class);
2368+ $ this ->expectExceptionMessage ('Argument #1 ($X_UNION) of {closure: ' . __FILE__ . ': ' . $ line . '}() for $X_FOO must be of type string|int, false given ' );
22972369 $ container ->getEnv ('X_FOO ' );
22982370 }
22992371
23002372 /**
2301- * @requires PHP 8
2373+ * @requires PHP 8.1
23022374 */
2303- public function testGetEnvThrowsWhenFactoryFunctionExpectsNullableUnionType (): void
2375+ public function testGetEnvThrowsWhenFactoryFunctionExpectsIntersectionTypeButWrongTypeGiven (): void
23042376 {
23052377 $ line = __LINE__ + 2 ;
2306- $ fn = null ;
2307- $ fn = #[ PHP8 ] function (string | int | null $ X_UNDEFINED ) { return $ X_UNDEFINED ; };
2378+ // eval to avoid syntax error on PHP < 8.1
2379+ $ fn = eval ( ' return function (\Traversable&\ArrayAccess $X_INTERSECTION ) { return var_export($X_INTERSECTION) ; }; ' ) ;
23082380 $ container = new Container ([
2309- 'X_FOO ' => $ fn
2381+ 'X_FOO ' => $ fn ,
2382+ 'X_INTERSECTION ' => false
23102383 ]);
23112384
2312- $ this ->expectException (\Error::class);
2313- $ this ->expectExceptionMessage ('Argument #1 ($X_UNDEFINED) of {closure: ' . __FILE__ . ': ' . $ line . '}() for $X_FOO expects unsupported type string|int|null ' );
2385+ $ this ->expectException (\TypeError::class);
2386+ $ this ->expectExceptionMessage ('Argument #1 ($X_INTERSECTION) of {closure: ' . __FILE__ . '( ' . $ line . ') : eval() \'d code:1}() for $X_FOO must be of type Traversable&ArrayAccess, false given ' );
2387+ $ container ->getEnv ('X_FOO ' );
2388+ }
2389+
2390+ /**
2391+ * @requires PHP 8.2
2392+ */
2393+ public function testGetEnvThrowsWhenFactoryFunctionExpectsDnfTypeButWrongTypeGiven (): void
2394+ {
2395+ $ line = __LINE__ + 2 ;
2396+ // eval to avoid syntax error on PHP < 8.2
2397+ $ fn = eval ('return function (float|(\Traversable&\Stringable)|string $X_UNION) { return (string) $X_UNION; }; ' );
2398+ $ container = new Container ([
2399+ 'X_FOO ' => $ fn ,
2400+ 'X_UNION ' => null
2401+ ]);
2402+
2403+ $ this ->expectException (\TypeError::class);
2404+ $ this ->expectExceptionMessage ('Argument #1 ($X_UNION) of {closure: ' . __FILE__ . '( ' . $ line . ') : eval() \'d code:1}() for $X_FOO must be of type (Traversable&Stringable)|string|float, null given ' );
23142405 $ container ->getEnv ('X_FOO ' );
23152406 }
23162407
0 commit comments