createLoop(); $timer = $loop->addTimer(0.001, $this->expectCallableNever()); $this->assertInstanceOf('React\EventLoop\TimerInterface', $timer); $this->assertFalse($timer->isPeriodic()); } public function testAddTimerWillBeInvokedOnceAndBlocksLoopWhenRunning() { $loop = $this->createLoop(); $loop->addTimer(0.005, $this->expectCallableOnce()); $start = microtime(true); $loop->run(); $end = microtime(true); // 1 invocation should take 5ms (± a few milliseconds due to timer inaccuracies) // make no strict assumptions about time interval, must at least take 1ms // and should not take longer than 0.1s for slower loops. $this->assertGreaterThanOrEqual(0.001, $end - $start); $this->assertLessThan(0.1, $end - $start); } public function testAddPeriodicTimerReturnsPeriodicTimerInstance() { $loop = $this->createLoop(); $periodic = $loop->addPeriodicTimer(0.1, $this->expectCallableNever()); $this->assertInstanceOf('React\EventLoop\TimerInterface', $periodic); $this->assertTrue($periodic->isPeriodic()); } public function testAddPeriodicTimerWillBeInvokedUntilItIsCancelled() { $loop = $this->createLoop(); $periodic = $loop->addPeriodicTimer(0.1, $this->expectCallableExactly(3)); // make no strict assumptions about actual time interval. // leave some room to ensure this ticks exactly 3 times. $loop->addTimer(0.350, function () use ($loop, $periodic) { $loop->cancelTimer($periodic); }); $loop->run(); } public function testAddPeriodicTimerWillBeInvokedWithMaximumAccuracyUntilItIsCancelled() { $loop = $this->createLoop(); $i = 0; $periodic = $loop->addPeriodicTimer(0.001, function () use (&$i) { ++$i; }); $loop->addTimer(0.1, function () use ($loop, $periodic) { $loop->cancelTimer($periodic); }); $loop->run(); // make no strict assumptions about number of invocations. // we know it must be no more than 100 times and should at least be // invoked 4 times for really slow loops $this->assertLessThanOrEqual(100, $i); $this->assertGreaterThanOrEqual(4, $i); } public function testAddPeriodicTimerCancelsItself() { $loop = $this->createLoop(); $i = 0; $loop->addPeriodicTimer(0.001, function ($timer) use (&$i, $loop) { $i++; if ($i === 5) { $loop->cancelTimer($timer); } }); $start = microtime(true); $loop->run(); $end = microtime(true); $this->assertEquals(5, $i); // 5 invocations should take 5ms (± 1ms due to timer inaccuracies) // make no strict assumptions about time interval, must at least take 4ms // and should not take longer than 0.2s for slower loops. $this->assertGreaterThanOrEqual(0.004, $end - $start); $this->assertLessThan(0.2, $end - $start); } public function testMinimumIntervalOneMicrosecond() { $loop = $this->createLoop(); $timer = $loop->addTimer(0, function () {}); $this->assertEquals(0.000001, $timer->getInterval()); } public function testAddPeriodicTimerWithZeroIntervalWillExecuteCallbackFunctionAtLeastTwice() { $loop = $this->createLoop(); $timeout = $loop->addTimer(2, $this->expectCallableNever()); //Timeout the test after two seconds if the periodic timer hasn't fired twice $i = 0; $loop->addPeriodicTimer(0, function ($timer) use (&$i, $loop, $timeout) { ++$i; if ($i === 2) { $loop->cancelTimer($timer); $loop->cancelTimer($timeout); } }); $loop->run(); $this->assertEquals(2, $i); } public function testTimerIntervalBelowZeroRunsImmediately() { $loop = $this->createLoop(); $start = 0; $loop->addTimer( -1, function () use (&$start) { $start = \microtime(true); } ); $loop->run(); $end = \microtime(true); // 1ms should be enough even on slow machines (± 1ms due to timer inaccuracies) $this->assertLessThan(0.002, $end - $start); } }