mirror of
https://github.com/danog/amp.git
synced 2024-11-27 04:24:42 +01:00
328 lines
10 KiB
PHP
328 lines
10 KiB
PHP
|
<?php
|
||
|
|
||
|
use Alert\NativeReactor;
|
||
|
|
||
|
class NativeReactorTest extends PHPUnit_Framework_TestCase {
|
||
|
|
||
|
function testImmediateExecution() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$testIncrement = 0;
|
||
|
|
||
|
$reactor->immediately(function() use (&$testIncrement) {
|
||
|
$testIncrement++;
|
||
|
});
|
||
|
$reactor->tick();
|
||
|
|
||
|
$this->assertEquals(1, $testIncrement);
|
||
|
}
|
||
|
|
||
|
function testWatcherIsNeverNotifiedIfStreamIsNeverReadable() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$stream = STDIN;
|
||
|
$increment = 0;
|
||
|
|
||
|
$reactor->onReadable($stream, function($stream) use (&$increment) {
|
||
|
$increment++;
|
||
|
});
|
||
|
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.1);
|
||
|
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertEquals(0, $increment);
|
||
|
}
|
||
|
|
||
|
function testTickExecutesReadyEvents() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$testIncrement = 0;
|
||
|
|
||
|
$reactor->immediately(function() use (&$testIncrement) {
|
||
|
$testIncrement++;
|
||
|
});
|
||
|
$reactor->tick();
|
||
|
|
||
|
$this->assertEquals(1, $testIncrement);
|
||
|
}
|
||
|
|
||
|
function testRunExecutesEventsUntilExplicitlyStopped() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$testIncrement = 0;
|
||
|
|
||
|
$reactor->repeat(function() use (&$testIncrement, $reactor) {
|
||
|
if ($testIncrement < 10) {
|
||
|
$testIncrement++;
|
||
|
} else {
|
||
|
$reactor->stop();
|
||
|
}
|
||
|
}, $delay = 0.001);
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertEquals(10, $testIncrement);
|
||
|
}
|
||
|
|
||
|
function testImmediatelyReturnsWatcherId() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$watcherId = $reactor->immediately(function(){});
|
||
|
$this->assertSame(1, $watcherId);
|
||
|
|
||
|
$watcherId = $reactor->immediately(function(){});
|
||
|
$this->assertSame(2, $watcherId);
|
||
|
|
||
|
$watcherId = $reactor->immediately(function(){});
|
||
|
$this->assertSame(3, $watcherId);
|
||
|
}
|
||
|
|
||
|
function testOnceReturnsWatcherId() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$watcherId = $reactor->once(function(){}, $delay = 0);
|
||
|
|
||
|
$this->assertSame(1, $watcherId);
|
||
|
}
|
||
|
|
||
|
function testReactorDoesntSwallowOnceCallbackException() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$reactor->repeat(function(){}, $delay = 1);
|
||
|
$reactor->once(function(){ throw new Exception('test'); }, $delay = 0);
|
||
|
|
||
|
try {
|
||
|
$reactor->tick();
|
||
|
$this->fail('Expected exception not thrown');
|
||
|
} catch (Exception $e) {
|
||
|
// woot! this is what we wanted
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function testScheduleReturnsWatcherId() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$watcherId = $reactor->repeat(function(){}, $interval = 1);
|
||
|
$this->assertSame(1, $watcherId);
|
||
|
}
|
||
|
|
||
|
function testImmediatelyAlarmAssignmentWhileAlreadyRunning() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$counter = 0;
|
||
|
$nestedCounter = 0;
|
||
|
$watcherId = $reactor->repeat(function() use ($reactor, &$counter, &$nestedCounter) {
|
||
|
$counter++;
|
||
|
if ($counter === 1) {
|
||
|
$reactor->immediately(function() use (&$nestedCounter) { $nestedCounter++; });
|
||
|
} elseif ($counter === 3) {
|
||
|
$reactor->stop();
|
||
|
}
|
||
|
}, $interval = 0.001);
|
||
|
$reactor->run();
|
||
|
$this->assertSame(3, $counter);
|
||
|
$this->assertSame(1, $nestedCounter);
|
||
|
}
|
||
|
|
||
|
function testOnReadableReturnsWatcherId() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$watcherId = $reactor->onReadable(STDIN, function(){});
|
||
|
$this->assertSame(1, $watcherId);
|
||
|
|
||
|
$watcherId = $reactor->onReadable(STDIN, function(){});
|
||
|
$this->assertSame(2, $watcherId);
|
||
|
}
|
||
|
|
||
|
function testOnWritableReturnsWatcherId() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$watcherId = $reactor->onWritable(STDOUT, function(){});
|
||
|
$this->assertSame(1, $watcherId);
|
||
|
|
||
|
$watcherId = $reactor->onWritable(STDOUT, function(){});
|
||
|
$this->assertSame(2, $watcherId);
|
||
|
}
|
||
|
|
||
|
function testOnReadableCancellation() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$watcherId = $reactor->onReadable(STDIN, function(){});
|
||
|
$reactor->immediately(function() use ($reactor, $watcherId) { $reactor->cancel($watcherId); });
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.1);
|
||
|
$reactor->run();
|
||
|
}
|
||
|
|
||
|
function testOnWritableCancellation() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$watcherId = $reactor->onWritable(STDOUT, function(){});
|
||
|
$reactor->immediately(function() use ($reactor, $watcherId) { $reactor->cancel($watcherId); });
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.1);
|
||
|
$reactor->run();
|
||
|
}
|
||
|
|
||
|
function testReactorDoesntSwallowExceptionOnRecurringScheduledAlarm() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$reactor->repeat(function(){ throw new Exception('test'); }, $interval = 0);
|
||
|
|
||
|
try {
|
||
|
$reactor->run();
|
||
|
$this->fail('Expected exception not thrown');
|
||
|
} catch (Exception $e) {
|
||
|
// woot! this is what we wanted
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function testEnableDoesNothingIfWatcherIdDoesntExistOrIsAlreadyEnabled() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$watcherId = $reactor->immediately(function() use ($reactor) { $reactor->stop(); });
|
||
|
$reactor->enable($watcherId);
|
||
|
$reactor->run();
|
||
|
}
|
||
|
|
||
|
function testAlarmWatcherDisable() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$watcherId = $reactor->immediately(function() use ($reactor) { $reactor->stop(); });
|
||
|
$reactor->disable($watcherId);
|
||
|
$reactor->once(function() use ($reactor, $watcherId) { $reactor->enable($watcherId); }, $delay = 0.01);
|
||
|
$reactor->run();
|
||
|
}
|
||
|
|
||
|
function testEnableReadableStreamWatcher() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$increment = 0;
|
||
|
$watcherId = $reactor->onReadable(STDIN, function() use (&$increment) { $increment++; });
|
||
|
$reactor->disable($watcherId);
|
||
|
$reactor->enable($watcherId);
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.01);
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertSame(0, $increment);
|
||
|
}
|
||
|
|
||
|
function testEnableWritableStreamWatcher() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$increment = 0;
|
||
|
$watcherId = $reactor->onWritable(STDOUT, function() use (&$increment) { $increment++; });
|
||
|
$reactor->disable($watcherId);
|
||
|
$reactor->enable($watcherId);
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.01);
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertTrue($increment > 0);
|
||
|
}
|
||
|
|
||
|
function testAlarmResortIfModifiedDuringStreamWatcherInvocation() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$reactor->onWritable(STDOUT, function() use ($reactor) {
|
||
|
$reactor->immediately(function() use ($reactor) { $reactor->stop(); });
|
||
|
});
|
||
|
$reactor->run();
|
||
|
}
|
||
|
|
||
|
function testCancelRemovesDisabledWatcher() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$increment = 0;
|
||
|
$watcherId = $reactor->immediately(function() use ($increment) { $increment++; });
|
||
|
$reactor->disable($watcherId);
|
||
|
$reactor->cancel($watcherId);
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.01);
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertSame(0, $increment);
|
||
|
}
|
||
|
|
||
|
function testOnWritableDisable() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$increment = 0;
|
||
|
$watcherId = $reactor->onWritable(STDOUT, function() use (&$increment) { $increment++; });
|
||
|
$reactor->disable($watcherId);
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.1);
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertSame(0, $increment);
|
||
|
}
|
||
|
|
||
|
function testOnReadableDisable() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$increment = 0;
|
||
|
$watcherId = $reactor->onReadable(STDIN, function() use (&$increment) { $increment++; });
|
||
|
$reactor->disable($watcherId);
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.1);
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertSame(0, $increment);
|
||
|
}
|
||
|
|
||
|
function testCancellation() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$watcherId = $reactor->once(function(){
|
||
|
$this->fail('Watcher was not cancelled as expected');
|
||
|
}, $delay = 0.005);
|
||
|
|
||
|
$reactor->immediately(function() use ($reactor, $watcherId) { $reactor->cancel($watcherId); });
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, $delay = 0.01);
|
||
|
$reactor->run();
|
||
|
}
|
||
|
|
||
|
function testOnWritableWatcher() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$flag = FALSE;
|
||
|
|
||
|
$reactor->onWritable(STDOUT, function() use ($reactor, &$flag) {
|
||
|
$flag = TRUE;
|
||
|
$reactor->stop();
|
||
|
});
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, 0.05);
|
||
|
|
||
|
$reactor->run();
|
||
|
$this->assertTrue($flag);
|
||
|
}
|
||
|
|
||
|
function testOnReadableWatcher() {
|
||
|
$reactor = new NativeReactor;
|
||
|
$reactor->onWritable(STDIN, function() {});
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, 0.05);
|
||
|
$reactor->run();
|
||
|
}
|
||
|
|
||
|
function testInitiallyDisabledWriteWatcher() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$increment = 0;
|
||
|
$reactor->onWritable(STDOUT, function() use (&$increment) { $increment++; }, $isEnabled = FALSE);
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, 0.05);
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertSame(0, $increment);
|
||
|
}
|
||
|
|
||
|
function testInitiallyDisabledWriteWatcherIsTriggeredOnceEnabled() {
|
||
|
$reactor = new NativeReactor;
|
||
|
|
||
|
$increment = 0;
|
||
|
$watcherId = $reactor->onWritable(STDOUT, function() use (&$increment) {
|
||
|
$increment++;
|
||
|
}, $isEnabled = FALSE);
|
||
|
|
||
|
$reactor->once(function() use ($reactor, $watcherId) {
|
||
|
$reactor->enable($watcherId);
|
||
|
}, 0.01);
|
||
|
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, 0.1);
|
||
|
$reactor->run();
|
||
|
|
||
|
$this->assertTrue($increment > 0);
|
||
|
}
|
||
|
|
||
|
function testGarbageCollection() {
|
||
|
$reactor = new NativeReactor();
|
||
|
$reactor->once(function() use ($reactor) { $reactor->stop(); }, 0.1);
|
||
|
$reactor->run();
|
||
|
}
|
||
|
|
||
|
}
|