Skip to content

Commit ac75701

Browse files
authored
test: add tests that close #52 after #70's implementation (#72)
1 parent 0bdb4d7 commit ac75701

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

test/phpunit/PromiseTest.php

+64
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use RuntimeException;
1818
use stdClass;
1919
use Throwable;
20+
use TypeError;
2021
use ValueError;
2122

2223
class PromiseTest extends TestCase {
@@ -902,4 +903,67 @@ protected function mockCallableThrowsException(
902903
->will(self::throwException($exception));
903904
return $mock;
904905
}
906+
907+
/*
908+
* The functionality tested here is an important distinction in the PHP
909+
* implemnetation, because of the type safety PHP can enforce compared
910+
* to the JavaScript implementation. If there's a catch function, but
911+
* the type of exception does not match the actual rejection, the
912+
* rejection should be thrown to the main thread instead.
913+
*/
914+
public function testCatchRejectionHandlerIsNotCalledByTypeHintedOnRejectedCallback() {
915+
$exception = new RangeException();
916+
$promiseContainer = $this->getTestPromiseContainer();
917+
$sut = $promiseContainer->getPromise();
918+
919+
$shouldNeverBeCalled = self::mockCallable(0);
920+
self::expectException(RangeException::class);
921+
922+
$sut->catch(function(PromiseException $reason) use($shouldNeverBeCalled) {
923+
call_user_func($shouldNeverBeCalled, $reason);
924+
});
925+
926+
$promiseContainer->reject($exception);
927+
}
928+
929+
public function testMatchingTypedCatchRejectionHandlerCanHandleInternalTypeErrors() {
930+
$exception = new RangeException("No, Michael, no!");
931+
$promiseContainer = $this->getTestPromiseContainer();
932+
$sut = $promiseContainer->getPromise();
933+
934+
$onRejected1 = self::mockCallable(0);
935+
$onRejected2 = self::mockCallable(0);
936+
937+
// There is a type error in the matching catch callback. This
938+
// should bubble out of the chain rather than being seen as
939+
// missing the RangeException type hint.
940+
self::expectException(TypeError::class);
941+
self::expectExceptionMessage("DateTime::__construct(): Argument #1 (\$datetime) must be of type string, Closure given");
942+
943+
$sut->catch(function(PromiseException $reason1) use($onRejected1) {
944+
call_user_func($onRejected1, $reason1);
945+
})
946+
->catch(function(RangeException $reason2) use($onRejected2) {
947+
new DateTime(fn() => "That was so not right!");
948+
call_user_func($onRejected2, $reason2);
949+
});
950+
$promiseContainer->reject($exception);
951+
}
952+
953+
public function testCatchRejectionHandlerIsCalledByAnotherMatchingTypeHintedOnRejectedCallback() {
954+
$exception = new RangeException();
955+
$promiseContainer = $this->getTestPromiseContainer();
956+
$sut = $promiseContainer->getPromise();
957+
958+
$onRejected1 = self::mockCallable(0);
959+
$onRejected2 = self::mockCallable(1);
960+
961+
$sut->catch(function(PromiseException $reason) use($onRejected1) {
962+
call_user_func($onRejected1, $reason);
963+
})->catch(function(RangeException $reason) use($onRejected2) {
964+
call_user_func($onRejected2, $reason);
965+
});
966+
967+
$promiseContainer->reject($exception);
968+
}
905969
}

0 commit comments

Comments
 (0)