Skip to content

Commit

Permalink
Adjustments for 7.1, support for union types, test suite updates
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonFrings committed Oct 15, 2021
1 parent a9752a8 commit 6fe0751
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 5 deletions.
42 changes: 37 additions & 5 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,43 @@ function _checkTypehint(callable $callback, $object)
return true;
}

$expectedException = $parameters[0];
if (PHP_VERSION < 7.1) {
$expectedException = $parameters[0];

if (!$expectedException->getClass()) {
return true;
}
if (!$expectedException->getClass()) {
return true;
}

return $expectedException->getClass()->isInstance($object);
} else {
$type = $parameters[0]->getType();

return $expectedException->getClass()->isInstance($object);
if (!$type) {
return true;
}

$types = [$type];

if ($type instanceof \ReflectionUnionType) {
$types = $type->getTypes();
}

$mismatched = false;

foreach ($types as $type) {
if (!$type || $type->isBuiltin()) {
continue;
}

$expectedClass = $type->getName();

if ($object instanceof $expectedClass) {
return true;
}

$mismatched = true;
}

return !$mismatched;
}
}
62 changes: 62 additions & 0 deletions tests/FunctionCheckTypehintTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,49 @@ public function shouldAcceptStaticClassCallbackWithTypehint()
$this->assertfalse(_checkTypehint(['React\Promise\TestCallbackWithTypehintClass', 'testCallbackStatic'], new \Exception()));
}

/**
* @test
* @requires PHP 8
*/
public function shouldAcceptClosureCallbackWithUnionTypehint()
{
eval(
'namespace React\Promise;' .
'self::assertTrue(_checkTypehint(function (\RuntimeException|\InvalidArgumentException $e) {}, new \InvalidArgumentException()));' .
'self::assertFalse(_checkTypehint(function (\RuntimeException|\InvalidArgumentException $e) {}, new \Exception()));'
);
}

/**
* @test
* @requires PHP 8
*/
public function shouldAcceptInvokableObjectCallbackWithUnionTypehint()
{
self::assertTrue(_checkTypehint(new TestCallbackWithUnionTypehintClass(), new InvalidArgumentException()));
self::assertFalse(_checkTypehint(new TestCallbackWithUnionTypehintClass(), new Exception()));
}

/**
* @test
* @requires PHP 8
*/
public function shouldAcceptObjectMethodCallbackWithUnionTypehint()
{
self::assertTrue(_checkTypehint([new TestCallbackWithUnionTypehintClass(), 'testCallback'], new InvalidArgumentException()));
self::assertFalse(_checkTypehint([new TestCallbackWithUnionTypehintClass(), 'testCallback'], new Exception()));
}

/**
* @test
* @requires PHP 8
*/
public function shouldAcceptStaticClassCallbackWithUnionTypehint()
{
self::assertTrue(_checkTypehint([TestCallbackWithUnionTypehintClass::class, 'testCallbackStatic'], new InvalidArgumentException()));
self::assertFalse(_checkTypehint([TestCallbackWithUnionTypehintClass::class, 'testCallbackStatic'], new Exception()));
}

/** @test */
public function shouldAcceptClosureCallbackWithoutTypehint()
{
Expand Down Expand Up @@ -99,6 +142,25 @@ public static function testCallbackStatic(\InvalidArgumentException $e)
}
}

if (defined('PHP_MAJOR_VERSION') && (PHP_MAJOR_VERSION >= 8)) {
eval(<<<EOT
namespace React\Promise;
class TestCallbackWithUnionTypehintClass
{
public function __invoke(\RuntimeException|\InvalidArgumentException \$e)
{
}
public function testCallback(\RuntimeException|\InvalidArgumentException \$e)
{
}
public static function testCallbackStatic(\RuntimeException|\InvalidArgumentException \$e)
{
}
}
EOT
);
}

class TestCallbackWithoutTypehintClass
{
public function __invoke()
Expand Down

0 comments on commit 6fe0751

Please sign in to comment.