diff --git a/src/support/src/Timebox.php b/src/support/src/Timebox.php new file mode 100644 index 000000000..16d89ea37 --- /dev/null +++ b/src/support/src/Timebox.php @@ -0,0 +1,65 @@ +earlyReturn && $remainder > 0) { + $this->usleep($remainder); + } + + if ($exception) { + throw $exception; + } + + return $result; + } + + public function returnEarly(): static + { + $this->earlyReturn = true; + + return $this; + } + + public function dontReturnEarly(): static + { + $this->earlyReturn = false; + + return $this; + } + + protected function usleep(int $microseconds) + { + Sleep::usleep($microseconds); + } +} diff --git a/tests/Support/TimeboxTest.php b/tests/Support/TimeboxTest.php new file mode 100644 index 000000000..991d6c448 --- /dev/null +++ b/tests/Support/TimeboxTest.php @@ -0,0 +1,92 @@ +assertTrue(true); + }; + + (new Timebox())->call($callback, 0); + } + + public function testMakeWaitsForMicroseconds(): void + { + $mock = Mockery::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial(); + $mock->shouldReceive('usleep')->once(); + + $mock->call(function () { + }, 10000); + + $mock->shouldHaveReceived('usleep')->once(); + } + + public function testMakeShouldNotSleepWhenEarlyReturnHasBeenFlagged(): void + { + $mock = Mockery::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial(); + $mock->call(function ($timebox) { + $timebox->returnEarly(); + }, 10000); + + $mock->shouldNotHaveReceived('usleep'); + } + + public function testMakeShouldSleepWhenDontEarlyReturnHasBeenFlagged(): void + { + $mock = Mockery::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial(); + $mock->shouldReceive('usleep')->once(); + + $mock->call(function ($timebox) { + $timebox->returnEarly(); + $timebox->dontReturnEarly(); + }, 10000); + + $mock->shouldHaveReceived('usleep')->once(); + } + + public function testMakeWaitsForMicrosecondsWhenExceptionIsThrown(): void + { + $mock = Mockery::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial(); + $mock->shouldReceive('usleep')->once(); + + try { + $this->expectExceptionMessage('Exception within Timebox callback.'); + + $mock->call(function () { + throw new Exception('Exception within Timebox callback.'); + }, 10000); + } finally { + $mock->shouldHaveReceived('usleep')->once(); + } + } + + public function testMakeShouldNotSleepWhenEarlyReturnHasBeenFlaggedAndExceptionIsThrown(): void + { + $mock = Mockery::spy(Timebox::class)->shouldAllowMockingProtectedMethods()->makePartial(); + + try { + $this->expectExceptionMessage('Exception within Timebox callback.'); + + $mock->call(function ($timebox) { + $timebox->returnEarly(); + throw new Exception('Exception within Timebox callback.'); + }, 10000); + } finally { + $mock->shouldNotHaveReceived('usleep'); + } + } +}