getReactor(); $increment = 0; $watcherId = $reactor->immediately(function() use (&$increment) { $increment++; }); $reactor->disable($watcherId); $reactor->once([$reactor, 'stop'], $msDelay = 50); $reactor->run(); $this->assertEquals(0, $increment); $reactor->enable($watcherId); $reactor->once([$reactor, 'stop'], $msDelay = 50); $reactor->run(); $this->assertEquals(1, $increment); } public function testTimerWatcherParameterOrder() { $reactor = $this->getReactor(); $counter = 0; $reactor->immediately(function($reactorArg, $watcherId) use ($reactor, &$counter) { $this->assertSame($reactor, $reactorArg); if (++$counter === 3) { $reactor->stop(); } }); $reactor->once(function($reactorArg, $watcherId) use ($reactor, &$counter) { $this->assertSame($reactor, $reactorArg); if (++$counter === 3) { $reactor->stop(); } }, $msDelay = 1); $reactor->repeat(function($reactorArg, $watcherId) use ($reactor, &$counter) { $this->assertSame($reactor, $reactorArg); $reactor->cancel($watcherId); if (++$counter === 3) { $reactor->stop(); } }, $msDelay = 1); $reactor->run(); } public function testStreamWatcherParameterOrder() { $reactor = $this->getReactor(); $reactor->onWritable(STDOUT, function($reactorArg, $watcherId) use ($reactor) { $this->assertSame($reactor, $reactorArg); $this->assertTrue(is_string($watcherId)); $reactor->stop(); }); } public function testDisablingWatcherPreventsSubsequentInvocation() { $reactor = $this->getReactor(); $increment = 0; $watcherId = $reactor->immediately(function() use (&$increment) { $increment++; }); $reactor->disable($watcherId); $reactor->once([$reactor, 'stop'], $msDelay = 50); $reactor->run(); $this->assertEquals(0, $increment); } public function testUnresolvedEventsAreReenabledOnRunFollowingPreviousStop() { $reactor = $this->getReactor(); $increment = 0; $reactor->once(function($reactor) use (&$increment) { $increment++; $reactor->stop(); }, $msDelay = 200); $reactor->run(function($reactor) { $reactor->stop(); }); $this->assertEquals(0, $increment); usleep(150000); $reactor->run(); $this->assertEquals(1, $increment); } public function testImmediateExecution() { $reactor = $this->getReactor(); $increment = 0; $reactor->immediately(function() use (&$increment) { $increment++; }); $reactor->tick(); $this->assertEquals(1, $increment); } public function testImmediatelyCallbacksDontRecurseInSameTick() { $reactor = $this->getReactor(); $increment = 0; $reactor->immediately(function() use (&$increment, $reactor) { $increment++; $reactor->immediately(function() use (&$increment) { $increment++; }); }); $reactor->tick(); $this->assertEquals(1, $increment); } public function testTickExecutesReadyEvents() { $reactor = $this->getReactor(); $increment = 0; $reactor->immediately(function() use (&$increment) { $increment++; }); $reactor->tick(); $this->assertEquals(1, $increment); } public function testRunExecutesEventsUntilExplicitlyStopped() { $reactor = $this->getReactor(); $increment = 0; $reactor->repeat(function() use (&$increment, $reactor) { if ($increment < 10) { $increment++; } else { $reactor->stop(); } }, $msInterval = 1); $reactor->run(); $this->assertEquals(10, $increment); } public function testOnceReturnsEventWatcher() { $reactor = $this->getReactor(); $firstWatcherId = '1'; $watcherId = $reactor->once(function(){}, $delay = 0); $this->assertSame($firstWatcherId, $watcherId); $watcherId = $reactor->immediately(function(){}); $this->assertSame((string)($firstWatcherId + 1), $watcherId); } /** * @expectedException RuntimeException * @expectedExceptionMessage test */ public function testReactorAllowsExceptionToBubbleUpDuringTick() { $reactor = $this->getReactor(); $reactor->immediately(function(){ throw new \RuntimeException('test'); }); $reactor->tick(); } /** * @expectedException RuntimeException * @expectedExceptionMessage test */ public function testReactorAllowsExceptionToBubbleUpDuringRun() { $reactor = $this->getReactor(); $reactor->immediately(function(){ throw new \RuntimeException('test'); }); $reactor->run(); } /** * @expectedException RuntimeException * @expectedExceptionMessage test */ public function testReactorAllowsExceptionToBubbleUpFromRepeatingAlarmDuringRun() { $reactor = $this->getReactor(); $reactor->repeat(function(){ throw new \RuntimeException('test'); }, $msInterval = 0); $reactor->run(); } public function testRepeatReturnsEventWatcher() { $reactor = $this->getReactor(); $firstWatcherId = '1'; $watcherId = $reactor->repeat(function(){}, $msInterval = 1000); $this->assertSame($firstWatcherId, $watcherId); $watcherId = $reactor->repeat(function(){}, $msInterval = 1000); $this->assertSame((string)($firstWatcherId + 1), $watcherId); } public function testCancelRemovesWatcher() { $reactor = $this->getReactor(); $watcherId = $reactor->once(function(){ $this->fail('Watcher was not cancelled as expected'); }, $msDelay = 20); $reactor->immediately(function() use ($reactor, $watcherId) { $reactor->cancel($watcherId); }); $reactor->once(function() use ($reactor) { $reactor->stop(); }, $msDelay = 5); $reactor->run(); } public function testOnWritableWatcher() { $reactor = $this->getReactor(); $flag = FALSE; $reactor->onWritable(STDOUT, function() use ($reactor, &$flag) { $flag = TRUE; $reactor->stop(); }); $reactor->once([$reactor, 'stop'], $msDelay = 50); $reactor->run(); $this->assertTrue($flag); } public function testInitiallyDisabledWriteWatcher() { $reactor = $this->getReactor(); $increment = 0; $reactor->onWritable(STDOUT, function() use (&$increment) { $increment++; }, $isEnabled = FALSE); $reactor->once([$reactor, 'stop'], $msDelay = 50); $reactor->run(); $this->assertSame(0, $increment); } public function testInitiallyDisabledWriteWatcherIsTriggeredOnceEnabled() { $reactor = $this->getReactor(); $increment = 0; $watcherId = $reactor->onWritable(STDOUT, function() use (&$increment) { $increment++; }, $isEnabled = FALSE); $reactor->immediately(function() use ($reactor, $watcherId) { $reactor->enable($watcherId); }); $reactor->once([$reactor, 'stop'], $msDelay = 250); $reactor->run(); $this->assertTrue($increment > 0); } /** * @expectedException RuntimeException */ public function testStreamWatcherDoesntSwallowExceptions() { $reactor = $this->getReactor(); $reactor->onWritable(STDOUT, function() { throw new \RuntimeException; }); $reactor->once([$reactor, 'stop'], $msDelay = 50); $reactor->run(); } public function testGarbageCollection() { $reactor = $this->getReactor(); $reactor->once([$reactor, 'stop'], $msDelay = 100); $reactor->run(); } public function testOnStartGeneratorResolvesAutomatically() { $reactor = $this->getReactor(); $test = ''; $gen = function($reactor) use (&$test) { yield; $test = "Thus Spake Zarathustra"; $reactor->once(function() use ($reactor) { $reactor->stop(); }, 50); }; $reactor->run($gen); $this->assertSame("Thus Spake Zarathustra", $test); } public function testImmediatelyGeneratorResolvesAutomatically() { $reactor = $this->getReactor(); $test = ''; $gen = function($reactor) use (&$test) { yield; $test = "The abyss will gaze back into you"; $reactor->once(function() use ($reactor) { $reactor->stop(); }, 50); }; $reactor->immediately($gen); $reactor->run(); $this->assertSame("The abyss will gaze back into you", $test); } public function testOnceGeneratorResolvesAutomatically() { $reactor = $this->getReactor(); $test = ''; $gen = function($reactor) use (&$test) { yield; $test = "There are no facts, only interpretations."; $reactor->once(function() use ($reactor) { $reactor->stop(); }, 50); }; $reactor->once($gen, 1); $reactor->run(); $this->assertSame("There are no facts, only interpretations.", $test); } public function testRepeatGeneratorResolvesAutomatically() { $reactor = $this->getReactor(); $test = ''; $gen = function($reactor, $watcherId) use (&$test) { $reactor->cancel($watcherId); yield; $test = "Art is the supreme task"; $reactor->stop(); }; $reactor->repeat($gen, 50); $reactor->run(); $this->assertSame("Art is the supreme task", $test); } public function testOnErrorCallbackInterceptsUncaughtException() { $var = null; $reactor = $this->getReactor(); $reactor->onError(function($e) use (&$var) { $var = $e->getMessage(); }); $reactor->run(function() { throw new \Exception('test'); }); $this->assertSame('test', $var); } }