diff --git a/src/Events/SwooleEvent.php b/src/Events/SwooleEvent.php index 74f644c..146576b 100644 --- a/src/Events/SwooleEvent.php +++ b/src/Events/SwooleEvent.php @@ -32,11 +32,12 @@ class SwooleEvent implements EventInterface protected int $_timerId = 0; /** + * @param bool $debug 测试用 * @throws EventLoopException 如果没有启用拓展 */ - public function __construct() + public function __construct(bool $debug = false) { - if (!extension_loaded('swoole')) { + if (!$debug and !extension_loaded('swoole')) { throw new EventLoopException('Not support ext-swoole. '); } } diff --git a/src/Events/SwowEvent.php b/src/Events/SwowEvent.php index ca571ea..c42f2b4 100644 --- a/src/Events/SwowEvent.php +++ b/src/Events/SwowEvent.php @@ -35,11 +35,12 @@ class SwowEvent implements EventInterface protected null|WaitGroup $_waitGroup = null; /** + * @param bool $debug 测试用 * @throws EventLoopException 如果没有启用拓展 */ - public function __construct() + public function __construct(bool $debug = false) { - if (!extension_loaded('swow')) { + if (!$debug and !extension_loaded('swow')) { throw new EventLoopException('Not support ext-swow. '); } } diff --git a/tests/EventsCase/SwooleEventTest.php b/tests/EventsCase/SwooleEventTest.php new file mode 100644 index 0000000..b2e2502 --- /dev/null +++ b/tests/EventsCase/SwooleEventTest.php @@ -0,0 +1,170 @@ +markTestSkipped('Swoole extension is loaded.'); + } + // normal + $this->expectException(EventLoopException::class); + $this->expectExceptionMessage('Not support ext-swoole.'); + new SwooleEvent(); + + // debug + $swooleEvent = new SwooleEvent(true); + $this->assertInstanceOf(SwooleEvent::class, $swooleEvent); + } + + public function testAddSignal() + { + $swooleEvent = new SwooleEvent(true); + + $processMock = m::mock('alias:Swoole\Process'); + $processMock->shouldReceive('signal')->andReturn(true); + + $result = $swooleEvent->add(SIGTERM, EventInterface::EV_SIGNAL, function () { + echo 'Signal received'; + }); + + $this->assertTrue($result); + } + + public function testAddTimer() + { + $swooleEvent = new SwooleEvent(true); + + $timerMock = m::mock('alias:Swoole\Timer'); + $timerMock->shouldReceive('after')->andReturn(1); + + $result = $swooleEvent->add(1, EventInterface::EV_TIMER, function () { + echo 'Timer triggered'; + }); + + $this->assertEquals(0, $result); + } + + public function testAddRead() + { + $swooleEvent = new SwooleEvent(true); + + $eventMock = m::mock('alias:Swoole\Event'); + $eventMock->shouldReceive('add')->andReturn(true); + + $stream = fopen('php://memory', 'r+'); + $result = $swooleEvent->add($stream, EventInterface::EV_READ, function () { + echo 'Read event'; + }); + + $this->assertTrue($result); + fclose($stream); + } + + public function testDelSignal() + { + $swooleEvent = new SwooleEvent(true); + + $processMock = m::mock('alias:Swoole\Process'); + $processMock->shouldReceive('signal')->andReturn(true); + + $swooleEvent->add(SIGTERM, EventInterface::EV_SIGNAL, function () { + echo 'Signal received'; + }); + + $result = $swooleEvent->del(SIGTERM, EventInterface::EV_SIGNAL); + + $this->assertTrue($result); + } + + public function testDelTimer() + { + $swooleEvent = new SwooleEvent(true); + + $timerMock = m::mock('alias:Swoole\Timer'); + $timerMock->shouldReceive('after')->andReturn(1); + $timerMock->shouldReceive('clear')->andReturn(true); + + $timerId = $swooleEvent->add(1, EventInterface::EV_TIMER, function () { + echo 'Timer triggered'; + }); + + $result = $swooleEvent->del($timerId, EventInterface::EV_TIMER); + + $this->assertTrue($result); + } + + public function testLoop() + { + $this->markTestSkipped('loop will exit()'); + + $this->expectException(\RuntimeException::class); + + $swooleEvent = new SwooleEvent(true); + $eventMock = m::mock('alias:Swoole\Event'); + $eventMock->shouldReceive('wait')->andReturn(true); + + $this->expectOutputString(''); + $swooleEvent->loop(); + } + + public function testDestroy() + { + $swooleEvent = new SwooleEvent(true); + + $eventMock = m::mock('alias:Swoole\Event'); + $eventMock->shouldReceive('exit')->andReturn(true); + + $swooleEvent->destroy(); + + $this->assertEmpty($swooleEvent->getTimerCount()); + } + + public function testClearAllTimer() + { + $swooleEvent = new SwooleEvent(true); + + $timerMock = m::mock('alias:Swoole\Timer'); + $timerMock->shouldReceive('clear')->andReturn(true); + $timerMock->shouldReceive('after')->andReturnSelf(); + + $swooleEvent->add(1, EventInterface::EV_TIMER, function () { + echo 'Timer triggered'; + }); + + $swooleEvent->clearAllTimer(); + + $this->assertEquals(0, $swooleEvent->getTimerCount()); + } +} \ No newline at end of file diff --git a/tests/EventsCase/SwowEventTest.php b/tests/EventsCase/SwowEventTest.php new file mode 100644 index 0000000..4febeec --- /dev/null +++ b/tests/EventsCase/SwowEventTest.php @@ -0,0 +1,187 @@ +markTestSkipped('The swow extension is loaded.'); + } + // normal + $this->expectException(EventLoopException::class); + $this->expectExceptionMessage('Not support ext-swow.'); + new SwowEvent(); + + // debug + $swowEvent = new SwowEvent(true); + $this->assertInstanceOf(SwowEvent::class, $swowEvent); + } + + public function testAddSignal() + { + $swowEvent = new SwowEvent(true); + + $coroutineMock = m::mock('alias:Swow\Coroutine'); + $coroutineMock->shouldReceive('run')->andReturnSelf(); + + $signalMock = m::mock('alias:Swow\Signal'); + $signalMock->shouldReceive('wait')->andReturn(true); + + $result = $swowEvent->add(SIGTERM, EventInterface::EV_SIGNAL, function () { + echo 'Signal received'; + }); + + $this->assertTrue($result); + } + + public function testAddTimer() + { + $swowEvent = new SwowEvent(true); + + $coroutineMock = m::mock('alias:Swow\Coroutine'); + $coroutineMock->shouldReceive('run')->andReturnSelf(); + $coroutineMock->shouldReceive('sleep')->andReturn(true); + + $result = $swowEvent->add(1, EventInterface::EV_TIMER, function () { + echo 'Timer triggered'; + }); + + $this->assertEquals(0, $result); + } + + public function testAddRead() + { + $swowEvent = new SwowEvent(true); + + $coroutineMock = m::mock('alias:Swow\Coroutine'); + $coroutineMock->shouldReceive('run')->andReturnSelf(); + + $stream = fopen('php://memory', 'r+'); + $result = $swowEvent->add($stream, EventInterface::EV_READ, function () { + echo 'Read event'; + }); + + $this->assertTrue($result); + fclose($stream); + } + + public function testDelSignal() + { + $swowEvent = new SwowEvent(true); + + $coroutineMock = m::mock('alias:Swow\Coroutine'); + $coroutineMock->shouldReceive('run')->andReturnSelf(); + $coroutineMock->shouldReceive('kill')->andReturn(true); + $coroutineMock->shouldReceive('isExecuting')->andReturn(true); + + $swowEvent->add(SIGTERM, EventInterface::EV_SIGNAL, function () { + echo 'Signal received'; + }); + + $result = $swowEvent->del(SIGTERM, EventInterface::EV_SIGNAL); + + $this->assertTrue($result); + } + + public function testDelTimer() + { + $swowEvent = new SwowEvent(true); + + $coroutineMock = m::mock('alias:Swow\Coroutine'); + $coroutineMock->shouldReceive('run')->andReturnSelf(); + $coroutineMock->shouldReceive('kill')->andReturn(true); + $coroutineMock->shouldReceive('isExecuting')->andReturn(true); + + $timerId = $swowEvent->add(1, EventInterface::EV_TIMER, function () { + echo 'Timer triggered'; + }); + + $result = $swowEvent->del($timerId, EventInterface::EV_TIMER); + + $this->assertTrue($result); + } + + public function testLoop() + { + $this->markTestSkipped('skip'); + + $swowEvent = new SwowEvent(true); + + $waitGroupMock = m::mock('alias:Swow\Sync\WaitGroup'); + $waitGroupMock->shouldReceive('add')->andReturn('add'); + $waitGroupMock->shouldReceive('wait')->andReturn(true); + + $this->expectOutputString(''); + $swowEvent->loop(); + } + + public function testDestroy() + { + $swowEvent = new SwowEvent(true); + + $coroutineMock = m::mock('alias:Swow\Coroutine'); + $coroutineMock->shouldReceive('killAll')->andReturn(true); + + $waitGroupMock = m::mock('alias:Swow\Sync\WaitGroup'); + $waitGroupMock->shouldReceive('done')->andReturn(true); + + $swowEvent->destroy(); + + $this->assertEmpty($swowEvent->getTimerCount()); + } + + public function testClearAllTimer() + { + $swowEvent = new SwowEvent(true); + + $coroutineMock = m::mock('alias:Swow\Coroutine'); + $coroutineMock->shouldReceive('kill')->andReturn(true); + $coroutineMock->shouldReceive('isExecuting')->andReturn(true); + $coroutineMock->shouldReceive('run')->andReturnSelf(); + + $swowEvent->add(1, EventInterface::EV_TIMER, function () { + echo 'Timer triggered'; + }); + + $swowEvent->clearAllTimer(); + + $this->assertEquals(0, $swowEvent->getTimerCount()); + } + +} \ No newline at end of file