1
0
mirror of https://github.com/danog/amp.git synced 2024-12-12 09:29:45 +01:00
amp/test/ReactorTest.php

333 lines
10 KiB
PHP
Raw Normal View History

<?php
2014-09-23 04:38:32 +02:00
namespace Amp\Test;
abstract class ReactorTest extends \PHPUnit_Framework_TestCase {
abstract protected function getReactor();
public function testEnablingWatcherAllowsSubsequentInvocation() {
$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);
$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);
2014-08-21 19:54:02 +02:00
$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() use (&$increment, $reactor) {
$increment++;
$reactor->stop();
}, $msDelay = 100);
$reactor->once([$reactor, 'stop'], $msDelay = 0);
$reactor->run();
$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();
2014-08-21 19:54:02 +02:00
$firstWatcherId = '1';
$watcherId = $reactor->once(function(){}, $delay = 0);
$this->assertSame($firstWatcherId, $watcherId);
$watcherId = $reactor->immediately(function(){});
2014-08-21 19:54:02 +02:00
$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();
2014-08-21 19:54:02 +02:00
$firstWatcherId = '1';
$watcherId = $reactor->repeat(function(){}, $msInterval = 1000);
$this->assertSame($firstWatcherId, $watcherId);
2014-06-11 18:21:46 +02:00
$watcherId = $reactor->repeat(function(){}, $msInterval = 1000);
2014-08-21 19:54:02 +02:00
$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();
}
2014-09-22 22:47:48 +02:00
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);
}
}