Skip to content

Commit 4e42238

Browse files
committed
Support more built-in types for Container
1 parent 136319f commit 4e42238

2 files changed

Lines changed: 147 additions & 2 deletions

File tree

src/Container.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,11 +461,15 @@ private function validateType($value, \ReflectionType $type): bool
461461
\assert($type !== 'null' && $type !== 'mixed');
462462

463463
return (
464-
(\is_object($value) && $value instanceof $type) ||
464+
(\is_object($value) && ($value instanceof $type || $type === 'object')) || // instanceof or object for PHP 7.2+
465465
(\is_string($value) && $type === 'string') ||
466466
(\is_int($value) && $type === 'int') ||
467467
(\is_float($value) && $type === 'float') ||
468-
(\is_bool($value) && $type === 'bool')
468+
(\is_bool($value) && $type === 'bool') ||
469+
(\is_iterable($value) && $type === 'iterable') ||
470+
(\is_callable($value) && $type === 'callable') ||
471+
($value === true && $type === 'true') || // PHP 8.2+ standalone type
472+
($value === false && $type === 'false') // PHP 8.0+ union or PHP 8.2+ standalone
469473
);
470474
}
471475

tests/ContainerTest.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,6 +1924,69 @@ public function testGetEnvReturnsStringFromMapFactory(): void
19241924
$this->assertEquals('bar', $container->getEnv('X_FOO'));
19251925
}
19261926

1927+
/**
1928+
* @requires PHP 7.2
1929+
*/
1930+
public function testGetEnvReturnsStringFromFactoryFunctionWithObjectType(): void
1931+
{
1932+
$container = new Container([
1933+
'X_FOO' => function (object $data) { return get_class($data); },
1934+
'data' => new \ArrayObject()
1935+
]);
1936+
1937+
$this->assertEquals('ArrayObject', $container->getEnv('X_FOO'));
1938+
}
1939+
1940+
public function testGetEnvReturnsStringFromFactoryFunctionWithIterableType(): void
1941+
{
1942+
$container = new Container([
1943+
'X_FOO' => function (iterable $items) { $s = ''; foreach ($items as $v) { $s .= $v; } return $s; },
1944+
'items' => new \ArrayIterator([1, 2, 3])
1945+
]);
1946+
1947+
$this->assertEquals('123', $container->getEnv('X_FOO'));
1948+
}
1949+
1950+
public function testGetEnvReturnsStringFromFactoryFunctionWithCallableType(): void
1951+
{
1952+
$container = new Container([
1953+
'X_FOO' => function (callable $fn) { return $fn('alice'); },
1954+
'fn' => 'strtoupper'
1955+
]);
1956+
1957+
$this->assertEquals('ALICE', $container->getEnv('X_FOO'));
1958+
}
1959+
1960+
/**
1961+
* @requires PHP 8.2
1962+
*/
1963+
public function testGetEnvReturnsStringFromFactoryFunctionWithTrueType(): void
1964+
{
1965+
// eval to avoid syntax error on PHP < 8.2
1966+
$fn = eval('return function (true $admin) { return var_export($admin, true); };');
1967+
$container = new Container([
1968+
'X_FOO' => $fn,
1969+
'admin' => true
1970+
]);
1971+
1972+
$this->assertEquals('true', $container->getEnv('X_FOO'));
1973+
}
1974+
1975+
/**
1976+
* @requires PHP 8.2
1977+
*/
1978+
public function testGetEnvReturnsStringFromFactoryFunctionWithFalseType(): void
1979+
{
1980+
// eval to avoid syntax error on PHP < 8.2
1981+
$fn = eval('return function (false $disabled) { return var_export($disabled, true); };');
1982+
$container = new Container([
1983+
'X_FOO' => $fn,
1984+
'disabled' => false
1985+
]);
1986+
1987+
$this->assertEquals('false', $container->getEnv('X_FOO'));
1988+
}
1989+
19271990
/**
19281991
* @requires PHP 8
19291992
*/
@@ -2485,6 +2548,84 @@ public function testGetEnvThrowsWhenFactoryFunctionExpectsNullableIntArgumentBut
24852548
$container->getEnv('X_FOO');
24862549
}
24872550

2551+
/**
2552+
* @requires PHP 7.2
2553+
*/
2554+
public function testGetEnvThrowsWhenFactoryFunctionExpectsObjectTypeButWrongTypeGiven(): void
2555+
{
2556+
$line = __LINE__ + 2;
2557+
$container = new Container([
2558+
'X_FOO' => function (object $data) { return get_class($data); },
2559+
'data' => 'Alice'
2560+
]);
2561+
2562+
$this->expectException(\TypeError::class);
2563+
$this->expectExceptionMessage('Argument #1 ($data) of {closure:' . __FILE__ . ':' . $line . '}() for $X_FOO must be of type object, string given');
2564+
$container->getEnv('X_FOO');
2565+
}
2566+
2567+
public function testGetEnvThrowsWhenFactoryFunctionExpectsIterableTypeButWrongTypeGiven(): void
2568+
{
2569+
$line = __LINE__ + 2;
2570+
$container = new Container([
2571+
'X_FOO' => function (iterable $items) { $s = ''; foreach ($items as $v) { $s .= $v; } return $s; },
2572+
'items' => 'not-iterable'
2573+
]);
2574+
2575+
$this->expectException(\TypeError::class);
2576+
$this->expectExceptionMessage('Argument #1 ($items) of {closure:' . __FILE__ . ':' . $line . '}() for $X_FOO must be of type iterable, string given');
2577+
$container->getEnv('X_FOO');
2578+
}
2579+
2580+
public function testGetEnvThrowsWhenFactoryFunctionExpectsCallableTypeButWrongTypeGiven(): void
2581+
{
2582+
$line = __LINE__ + 2;
2583+
$container = new Container([
2584+
'X_FOO' => function (callable $fn) { return $fn(); },
2585+
'fn' => 42
2586+
]);
2587+
2588+
$this->expectException(\TypeError::class);
2589+
$this->expectExceptionMessage('Argument #1 ($fn) of {closure:' . __FILE__ . ':' . $line . '}() for $X_FOO must be of type callable, int given');
2590+
$container->getEnv('X_FOO');
2591+
}
2592+
2593+
/**
2594+
* @requires PHP 8.2
2595+
*/
2596+
public function testGetEnvThrowsWhenFactoryFunctionExpectsTrueTypeButWrongTypeGiven(): void
2597+
{
2598+
$line = __LINE__ + 2;
2599+
// eval to avoid syntax error on PHP < 8.2
2600+
$fn = eval('return function (true $admin) { return var_export($admin, true); };');
2601+
$container = new Container([
2602+
'X_FOO' => $fn,
2603+
'admin' => false
2604+
]);
2605+
2606+
$this->expectException(\TypeError::class);
2607+
$this->expectExceptionMessage('Argument #1 ($admin) of {closure:' . __FILE__ . '(' . $line . ') : eval()\'d code:1}() for $X_FOO must be of type true, false given');
2608+
$container->getEnv('X_FOO');
2609+
}
2610+
2611+
/**
2612+
* @requires PHP 8.2
2613+
*/
2614+
public function testGetEnvThrowsWhenFactoryFunctionExpectsFalseTypeButWrongTypeGiven(): void
2615+
{
2616+
$line = __LINE__ + 2;
2617+
// eval to avoid syntax error on PHP < 8.2
2618+
$fn = eval('return function (false $disabled) { return var_export($disabled, true); };');
2619+
$container = new Container([
2620+
'X_FOO' => $fn,
2621+
'disabled' => true
2622+
]);
2623+
2624+
$this->expectException(\TypeError::class);
2625+
$this->expectExceptionMessage('Argument #1 ($disabled) of {closure:' . __FILE__ . '(' . $line . ') : eval()\'d code:1}() for $X_FOO must be of type false, true given');
2626+
$container->getEnv('X_FOO');
2627+
}
2628+
24882629
/**
24892630
* @requires PHP 8
24902631
*/

0 commit comments

Comments
 (0)