Skip to content

Commit 990eead

Browse files
cdosofteiSimonFrings
authored andcommitted
Adjustments for 7.1, support for union types, test suite updates
1 parent a9752a8 commit 990eead

2 files changed

Lines changed: 99 additions & 5 deletions

File tree

src/functions.php

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -341,11 +341,43 @@ function _checkTypehint(callable $callback, $object)
341341
return true;
342342
}
343343

344-
$expectedException = $parameters[0];
344+
if (\PHP_VERSION_ID < 70100 || \defined('HHVM_VERSION')) {
345+
$expectedException = $parameters[0];
345346

346-
if (!$expectedException->getClass()) {
347-
return true;
348-
}
347+
if (!$expectedException->getClass()) {
348+
return true;
349+
}
350+
351+
return $expectedException->getClass()->isInstance($object);
352+
} else {
353+
$type = $parameters[0]->getType();
349354

350-
return $expectedException->getClass()->isInstance($object);
355+
if (!$type) {
356+
return true;
357+
}
358+
359+
$types = [$type];
360+
361+
if ($type instanceof \ReflectionUnionType) {
362+
$types = $type->getTypes();
363+
}
364+
365+
$mismatched = false;
366+
367+
foreach ($types as $type) {
368+
if (!$type || $type->isBuiltin()) {
369+
continue;
370+
}
371+
372+
$expectedClass = $type->getName();
373+
374+
if ($object instanceof $expectedClass) {
375+
return true;
376+
}
377+
378+
$mismatched = true;
379+
}
380+
381+
return !$mismatched;
382+
}
351383
}

tests/FunctionCheckTypehintTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,49 @@ public function shouldAcceptStaticClassCallbackWithTypehint()
4141
$this->assertfalse(_checkTypehint(['React\Promise\TestCallbackWithTypehintClass', 'testCallbackStatic'], new \Exception()));
4242
}
4343

44+
/**
45+
* @test
46+
* @requires PHP 8
47+
*/
48+
public function shouldAcceptClosureCallbackWithUnionTypehint()
49+
{
50+
eval(
51+
'namespace React\Promise;' .
52+
'self::assertTrue(_checkTypehint(function (\RuntimeException|\InvalidArgumentException $e) {}, new \InvalidArgumentException()));' .
53+
'self::assertFalse(_checkTypehint(function (\RuntimeException|\InvalidArgumentException $e) {}, new \Exception()));'
54+
);
55+
}
56+
57+
/**
58+
* @test
59+
* @requires PHP 8
60+
*/
61+
public function shouldAcceptInvokableObjectCallbackWithUnionTypehint()
62+
{
63+
self::assertTrue(_checkTypehint(new TestCallbackWithUnionTypehintClass(), new InvalidArgumentException()));
64+
self::assertFalse(_checkTypehint(new TestCallbackWithUnionTypehintClass(), new Exception()));
65+
}
66+
67+
/**
68+
* @test
69+
* @requires PHP 8
70+
*/
71+
public function shouldAcceptObjectMethodCallbackWithUnionTypehint()
72+
{
73+
self::assertTrue(_checkTypehint([new TestCallbackWithUnionTypehintClass(), 'testCallback'], new InvalidArgumentException()));
74+
self::assertFalse(_checkTypehint([new TestCallbackWithUnionTypehintClass(), 'testCallback'], new Exception()));
75+
}
76+
77+
/**
78+
* @test
79+
* @requires PHP 8
80+
*/
81+
public function shouldAcceptStaticClassCallbackWithUnionTypehint()
82+
{
83+
self::assertTrue(_checkTypehint([TestCallbackWithUnionTypehintClass::class, 'testCallbackStatic'], new InvalidArgumentException()));
84+
self::assertFalse(_checkTypehint([TestCallbackWithUnionTypehintClass::class, 'testCallbackStatic'], new Exception()));
85+
}
86+
4487
/** @test */
4588
public function shouldAcceptClosureCallbackWithoutTypehint()
4689
{
@@ -99,6 +142,25 @@ public static function testCallbackStatic(\InvalidArgumentException $e)
99142
}
100143
}
101144

145+
if (defined('PHP_MAJOR_VERSION') && (PHP_MAJOR_VERSION >= 8)) {
146+
eval(<<<EOT
147+
namespace React\Promise;
148+
class TestCallbackWithUnionTypehintClass
149+
{
150+
public function __invoke(\RuntimeException|\InvalidArgumentException \$e)
151+
{
152+
}
153+
public function testCallback(\RuntimeException|\InvalidArgumentException \$e)
154+
{
155+
}
156+
public static function testCallbackStatic(\RuntimeException|\InvalidArgumentException \$e)
157+
{
158+
}
159+
}
160+
EOT
161+
);
162+
}
163+
102164
class TestCallbackWithoutTypehintClass
103165
{
104166
public function __invoke()

0 commit comments

Comments
 (0)