diff --git a/src/SimpleFiber.php b/src/SimpleFiber.php index acf3fad..255aa44 100644 --- a/src/SimpleFiber.php +++ b/src/SimpleFiber.php @@ -63,7 +63,14 @@ public function suspend(): mixed }); } - return (self::$scheduler->isStarted() ? self::$scheduler->resume() : self::$scheduler->start())(); + $ret = (self::$scheduler->isStarted() ? self::$scheduler->resume() : self::$scheduler->start()); + assert(is_callable($ret)); + + Loop::stop(); + self::$scheduler->resume(); + assert(self::$scheduler->isTerminated()); + + return $ret(); } return \Fiber::suspend(); diff --git a/tests/AwaitTest.php b/tests/AwaitTest.php index 3d2b886..2bfaa73 100644 --- a/tests/AwaitTest.php +++ b/tests/AwaitTest.php @@ -97,6 +97,33 @@ public function testAwaitAsyncThrowsExceptionImmediatelyWhenPromiseIsRejected(ca } } + /** + * @dataProvider provideAwaiters + */ + public function testAwaitThrowsExceptionAfterCompletingCurrentTickWhenPromiseIsRejected(callable $await) + { + $deferred = new Deferred(); + + $ticks = 0; + Loop::futureTick(function () use (&$ticks) { + ++$ticks; + }); + Loop::futureTick(function () use (&$ticks, $deferred) { + ++$ticks; + $deferred->reject(new \RuntimeException($ticks . ' ticks')); + }); + Loop::futureTick(function () use (&$ticks) { + ++$ticks; + }); + + try { + $await($deferred->promise()); + } catch (\RuntimeException $e) { + $this->assertEquals('2 ticks', $e->getMessage()); + $this->assertEquals(3, $ticks); + } + } + /** * @dataProvider provideAwaiters */ @@ -251,6 +278,29 @@ public function testAwaitAsyncReturnsValueImmediatelyWhenPromiseIsFulfilled(call $this->assertEquals(1, $ticks); } + /** + * @dataProvider provideAwaiters + */ + public function testAwaitAsyncReturnsValueAfterCompletingCurrentTickWhenPromiseIsFulfilled(callable $await) + { + $deferred = new Deferred(); + + $ticks = 0; + Loop::futureTick(function () use (&$ticks) { + ++$ticks; + }); + Loop::futureTick(function () use (&$ticks, $deferred) { + ++$ticks; + $deferred->resolve($ticks); + }); + Loop::futureTick(function () use (&$ticks) { + ++$ticks; + }); + + $this->assertEquals(2, $await($deferred->promise())); + $this->assertEquals(3, $ticks); + } + /** * @dataProvider provideAwaiters */