mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-03-17 20:54:52 +08:00
add HttpEventListener test (#200)
This commit is contained in:
parent
ca430123c9
commit
ed5a9c6c12
@ -35,7 +35,7 @@
|
||||
"jangregor/phpstan-prophecy": "^1.0",
|
||||
"jetbrains/phpstorm-attributes": "^1.0",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"phpspec/prophecy": "1.x-dev",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"phpstan/phpstan": "^1.1",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
|
||||
@ -10,6 +10,9 @@ parameters:
|
||||
- '#Unsafe usage of new static#'
|
||||
- '#Call to method initTableList\(\) of deprecated class ZM\\DB\\DB#'
|
||||
- '#class Fiber#'
|
||||
- # Ignore Prophesize deprecation bug: https://github.com/phpstan/phpstan-deprecation-rules/issues/76
|
||||
message: '#^Call to deprecated method prophesize\(\) of class Tests\\TestCase#'
|
||||
path: tests
|
||||
dynamicConstantNames:
|
||||
- SWOOLE_VERSION
|
||||
- ZM_TEST_LOG_DEBUG
|
||||
|
||||
@ -4,24 +4,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Prophecy\Prophet;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class TestCase extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected Prophet $prophet;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->prophet = new Prophet();
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
$this->prophet->checkPredictions();
|
||||
}
|
||||
use ProphecyTrait;
|
||||
}
|
||||
|
||||
@ -5,13 +5,11 @@ declare(strict_types=1);
|
||||
namespace Tests\Trait;
|
||||
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\Prophet;
|
||||
use Psr\Log\AbstractLogger;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* 模拟 Logger 行为
|
||||
* @property Prophet $prophet
|
||||
*/
|
||||
trait HasLogger
|
||||
{
|
||||
@ -37,7 +35,7 @@ trait HasLogger
|
||||
|
||||
private function startMockLogger(): void
|
||||
{
|
||||
$logger = $this->prophet->prophesize(AbstractLogger::class);
|
||||
$logger = $this->prophesize(AbstractLogger::class);
|
||||
$levels = [
|
||||
LogLevel::EMERGENCY,
|
||||
LogLevel::ALERT,
|
||||
@ -50,9 +48,11 @@ trait HasLogger
|
||||
];
|
||||
$log_it = fn (...$args) => $this->mockLog(...$args);
|
||||
foreach ($levels as $level) {
|
||||
$logger->{$level}(Argument::type('string'), Argument::any())->will(fn ($args) => $log_it($level, ...$args));
|
||||
$logger->{$level}(Argument::type('string'), Argument::any())
|
||||
->will(fn ($args) => $log_it($level, ...$args));
|
||||
}
|
||||
$logger->log(Argument::in($levels), Argument::type('string'), Argument::any())->will(fn ($args) => $log_it(...$args));
|
||||
$logger->log(Argument::in($levels), Argument::type('string'), Argument::any())
|
||||
->will(fn ($args) => $log_it(...$args));
|
||||
ob_logger_register($logger->reveal());
|
||||
}
|
||||
}
|
||||
|
||||
112
tests/ZM/Event/Listener/HttpEventListenerTest.php
Normal file
112
tests/ZM/Event/Listener/HttpEventListenerTest.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\ZM\Event\Listener;
|
||||
|
||||
use Choir\Http\ServerRequest;
|
||||
use Prophecy\Argument;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Tests\TestCase;
|
||||
use Tests\Trait\HasVirtualFileSystem;
|
||||
use ZM\Event\Listener\HttpEventListener;
|
||||
use ZM\Utils\HttpUtil;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class HttpEventListenerTest extends TestCase
|
||||
{
|
||||
use HasVirtualFileSystem;
|
||||
|
||||
public function fakeHandler(): ?string
|
||||
{
|
||||
return 'I am here to greet';
|
||||
}
|
||||
|
||||
public function testHandleNotAllowedRoute(): void
|
||||
{
|
||||
$this->addRoute($this->mockHandler(false), 'fakeHandler');
|
||||
|
||||
$event = $this->mockRequestEvent(new ServerRequest('DELETE', '/test/get'), true);
|
||||
HttpEventListener::getInstance()->onRequest999($event);
|
||||
}
|
||||
|
||||
public function testHandleNotFoundRoute(): void
|
||||
{
|
||||
$this->addRoute($this->mockHandler(false), 'fakeHandler');
|
||||
|
||||
$event = $this->mockRequestEvent(new ServerRequest('GET', '/test/not-found'), false);
|
||||
HttpEventListener::getInstance()->onRequest999($event);
|
||||
}
|
||||
|
||||
public function testHandleFoundRoute(): void
|
||||
{
|
||||
$this->addRoute('', [$this->mockHandler(true), 'fakeHandler']);
|
||||
|
||||
$event = $this->mockRequestEvent(new ServerRequest('GET', '/test/get'), true);
|
||||
HttpEventListener::getInstance()->onRequest999($event);
|
||||
}
|
||||
|
||||
public function testHandleFoundRouteWithException(): void
|
||||
{
|
||||
$this->addRoute('', [$this->mockHandler(true, fn () => null), 'fakeHandler']);
|
||||
|
||||
$event = $this->mockRequestEvent(new ServerRequest('GET', '/test/get'), true);
|
||||
HttpEventListener::getInstance()->onRequest999($event);
|
||||
}
|
||||
|
||||
public function testHandleStaticFile(): void
|
||||
{
|
||||
$this->setUpVfs('static', [
|
||||
'test.txt' => 'Hello, world!',
|
||||
]);
|
||||
$event = $this->mockRequestEvent(new ServerRequest('GET', '/test.txt'), true);
|
||||
|
||||
$old_conf = config('global.file_server.document_root');
|
||||
config(['global.file_server.document_root' => $this->vfs->url()]);
|
||||
HttpEventListener::getInstance()->onRequest1($event);
|
||||
config(['global.file_server.document_root' => $old_conf]);
|
||||
}
|
||||
|
||||
private function addRoute($class, $method): void
|
||||
{
|
||||
HttpUtil::getRouteCollection()->remove('test.get');
|
||||
$route = new Route('/test/get', ['_class' => $class, '_method' => $method], methods: ['GET']);
|
||||
HttpUtil::getRouteCollection()->add('test.get', $route);
|
||||
}
|
||||
|
||||
private function mockRequestEvent(ServerRequest $request, bool $should_have_response): \HttpRequestEvent
|
||||
{
|
||||
$event = $this->prophesize(\HttpRequestEvent::class);
|
||||
$event->getRequest()->willReturn($request);
|
||||
$event->getResponse()->willReturn(null);
|
||||
if ($should_have_response) {
|
||||
$event->withResponse(Argument::type(ResponseInterface::class))
|
||||
->will(function ($args) use ($event) {
|
||||
$event->getResponse()->willReturn($args[0]);
|
||||
return $event->reveal();
|
||||
})
|
||||
->shouldBeCalledOnce();
|
||||
} else {
|
||||
$event->withResponse(Argument::type(ResponseInterface::class))->shouldNotBeCalled();
|
||||
}
|
||||
return $event->reveal();
|
||||
}
|
||||
|
||||
private function mockHandler(bool $should_be_called, callable $callback = null): self
|
||||
{
|
||||
$handler = $this->prophesize(self::class);
|
||||
if ($should_be_called) {
|
||||
$handler->fakeHandler(
|
||||
Argument::type('array'),
|
||||
Argument::type(ServerRequest::class),
|
||||
Argument::type(\HttpRequestEvent::class)
|
||||
)->will(fn () => $callback ? $callback() : 'OK!')->shouldBeCalledOnce();
|
||||
} else {
|
||||
$handler->fakeHandler(Argument::cetera())->shouldNotBeCalled();
|
||||
}
|
||||
return $handler->reveal();
|
||||
}
|
||||
}
|
||||
37
tests/ZM/Event/Listener/SignalListenerTest.php
Normal file
37
tests/ZM/Event/Listener/SignalListenerTest.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\ZM\Event\Listener;
|
||||
|
||||
use Tests\TestCase;
|
||||
use Tests\Trait\HasLogger;
|
||||
use ZM\Event\Listener\SignalListener;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class SignalListenerTest extends TestCase
|
||||
{
|
||||
use HasLogger;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->startMockLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires extension pcntl
|
||||
*/
|
||||
public function testListenWorkerSignal(): void
|
||||
{
|
||||
$l = new SignalListener();
|
||||
$l->signalWorker();
|
||||
// 检查信号处理器是否被设置
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
$h = pcntl_signal_get_handler(SIGINT);
|
||||
$this->assertIsCallable($h);
|
||||
$this->assertEquals([$l, 'onWorkerInt'], $h);
|
||||
}
|
||||
}
|
||||
@ -190,7 +190,7 @@ class ZMResultPrinter extends CliTestDoxPrinter
|
||||
$out = '';
|
||||
|
||||
if ($message) {
|
||||
$out .= $this->prefixLines($prefix['message'], strtolower($message) . PHP_EOL) . PHP_EOL;
|
||||
$out .= $this->prefixLines($prefix['message'], $message . PHP_EOL) . PHP_EOL;
|
||||
}
|
||||
|
||||
if ($diff) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user