RejectTestTrait.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace React\Promise\PromiseTest;
  3. use Exception;
  4. use React\Promise;
  5. use React\Promise\Deferred;
  6. use React\Promise\PromiseAdapter\PromiseAdapterInterface;
  7. use React\Promise\PromiseInterface;
  8. use function React\Promise\reject;
  9. use function React\Promise\resolve;
  10. trait RejectTestTrait
  11. {
  12. abstract public function getPromiseTestAdapter(callable $canceller = null): PromiseAdapterInterface;
  13. /** @test */
  14. public function rejectShouldRejectWithAnException(): void
  15. {
  16. $adapter = $this->getPromiseTestAdapter();
  17. $exception = new Exception();
  18. $mock = $this->createCallableMock();
  19. $mock
  20. ->expects($this->once())
  21. ->method('__invoke')
  22. ->with($this->identicalTo($exception));
  23. $adapter->promise()
  24. ->then($this->expectCallableNever(), $mock);
  25. $adapter->reject($exception);
  26. }
  27. /** @test */
  28. public function rejectShouldForwardReasonWhenCallbackIsNull(): void
  29. {
  30. $adapter = $this->getPromiseTestAdapter();
  31. $exception = new Exception();
  32. $mock = $this->createCallableMock();
  33. $mock
  34. ->expects($this->once())
  35. ->method('__invoke')
  36. ->with($this->identicalTo($exception));
  37. $adapter->promise()
  38. ->then(
  39. $this->expectCallableNever()
  40. )
  41. ->then(
  42. $this->expectCallableNever(),
  43. $mock
  44. );
  45. $adapter->reject($exception);
  46. }
  47. /** @test */
  48. public function rejectShouldMakePromiseImmutable(): void
  49. {
  50. $adapter = $this->getPromiseTestAdapter();
  51. $exception1 = new Exception();
  52. $exception2 = new Exception();
  53. $exception3 = new Exception();
  54. $mock = $this->createCallableMock();
  55. $mock
  56. ->expects($this->once())
  57. ->method('__invoke')
  58. ->with($this->identicalTo($exception1));
  59. $adapter->promise()
  60. ->then(null, function (\Throwable $value) use ($exception3, $adapter): PromiseInterface {
  61. $adapter->reject($exception3);
  62. return reject($value);
  63. })
  64. ->then(
  65. $this->expectCallableNever(),
  66. $mock
  67. );
  68. $adapter->reject($exception1);
  69. $adapter->reject($exception2);
  70. }
  71. /** @test */
  72. public function rejectShouldInvokeCatchHandler(): void
  73. {
  74. $adapter = $this->getPromiseTestAdapter();
  75. $exception = new Exception();
  76. $mock = $this->createCallableMock();
  77. $mock
  78. ->expects($this->once())
  79. ->method('__invoke')
  80. ->with($this->identicalTo($exception));
  81. $adapter->promise()
  82. ->catch($mock);
  83. $adapter->reject($exception);
  84. }
  85. /** @test */
  86. public function finallyShouldNotSuppressRejection(): void
  87. {
  88. $adapter = $this->getPromiseTestAdapter();
  89. $exception = new Exception();
  90. $mock = $this->createCallableMock();
  91. $mock
  92. ->expects($this->once())
  93. ->method('__invoke')
  94. ->with($this->identicalTo($exception));
  95. $adapter->promise()
  96. ->finally(function () {})
  97. ->then(null, $mock);
  98. $adapter->reject($exception);
  99. }
  100. /** @test */
  101. public function finallyShouldNotSuppressRejectionWhenHandlerReturnsANonPromise(): void
  102. {
  103. $adapter = $this->getPromiseTestAdapter();
  104. $exception = new Exception();
  105. $mock = $this->createCallableMock();
  106. $mock
  107. ->expects($this->once())
  108. ->method('__invoke')
  109. ->with($this->identicalTo($exception));
  110. $adapter->promise()
  111. ->finally(function (): int { // @phpstan-ignore-line
  112. return 1;
  113. })
  114. ->then(null, $mock);
  115. $adapter->reject($exception);
  116. }
  117. /** @test */
  118. public function finallyShouldNotSuppressRejectionWhenHandlerReturnsAPromise(): void
  119. {
  120. $adapter = $this->getPromiseTestAdapter();
  121. $exception = new Exception();
  122. $mock = $this->createCallableMock();
  123. $mock
  124. ->expects($this->once())
  125. ->method('__invoke')
  126. ->with($this->identicalTo($exception));
  127. $adapter->promise()
  128. ->finally(function (): PromiseInterface { // @phpstan-ignore-line
  129. return resolve(1);
  130. })
  131. ->then(null, $mock);
  132. $adapter->reject($exception);
  133. }
  134. /** @test */
  135. public function finallyShouldRejectWhenHandlerThrowsForRejection(): void
  136. {
  137. $adapter = $this->getPromiseTestAdapter();
  138. $exception = new Exception();
  139. $mock = $this->createCallableMock();
  140. $mock
  141. ->expects($this->once())
  142. ->method('__invoke')
  143. ->with($this->identicalTo($exception));
  144. $adapter->promise()
  145. ->finally(function () use ($exception) {
  146. throw $exception;
  147. })
  148. ->then(null, $mock);
  149. $adapter->reject($exception);
  150. }
  151. /** @test */
  152. public function finallyShouldRejectWhenHandlerRejectsForRejection(): void
  153. {
  154. $adapter = $this->getPromiseTestAdapter();
  155. $exception = new Exception();
  156. $mock = $this->createCallableMock();
  157. $mock
  158. ->expects($this->once())
  159. ->method('__invoke')
  160. ->with($this->identicalTo($exception));
  161. $adapter->promise()
  162. ->finally(function () use ($exception) {
  163. return reject($exception);
  164. })
  165. ->then(null, $mock);
  166. $adapter->reject($exception);
  167. }
  168. }