From 0892cbebfdfbe73ae9d2a64a133c96daf1552c7a Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 9 Nov 2023 14:02:58 +0300 Subject: [PATCH] Fix debug classes and add more tests (#224) --- src/Debug/DebugRoutesCommand.php | 11 +-- src/Debug/RouterCollector.php | 16 +--- src/Debug/UrlMatcherInterfaceProxy.php | 9 +-- tests/Debug/DebugRoutesCommandTest.php | 80 +++++++++++++++++--- tests/Debug/RouterCollectorTest.php | 39 ++++++++++ tests/Debug/UrlMatcherInterfaceProxyTest.php | 44 +++++++++++ tests/Support/UrlMatcherStub.php | 22 ++++++ 7 files changed, 186 insertions(+), 35 deletions(-) create mode 100644 tests/Debug/UrlMatcherInterfaceProxyTest.php create mode 100644 tests/Support/UrlMatcherStub.php diff --git a/src/Debug/DebugRoutesCommand.php b/src/Debug/DebugRoutesCommand.php index 4a6fe74..efbde07 100644 --- a/src/Debug/DebugRoutesCommand.php +++ b/src/Debug/DebugRoutesCommand.php @@ -14,9 +14,6 @@ use Yiisoft\VarDumper\VarDumper; use Yiisoft\Yii\Debug\Debugger; -/** - * @codeCoverageIgnore - */ final class DebugRoutesCommand extends Command { public const COMMAND_NAME = 'debug:routes'; @@ -55,8 +52,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $data = $route->__debugInfo(); $action = ''; $middlewares = []; - if (!empty($data['middlewareDefinitions'])) { - $middlewareDefinitions = $data['middlewareDefinitions']; + if (!empty($data['enabledMiddlewares'])) { + $middlewareDefinitions = $data['enabledMiddlewares']; $action = array_pop($middlewareDefinitions); $middlewares = $middlewareDefinitions; } @@ -94,8 +91,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($this->routeCollection->getRoutes() as $route) { $data = $route->__debugInfo(); $action = ''; - if (!empty($data['middlewareDefinitions'])) { - $middlewareDefinitions = $data['middlewareDefinitions']; + if (!empty($data['enabledMiddlewares'])) { + $middlewareDefinitions = $data['enabledMiddlewares']; $action = array_pop($middlewareDefinitions); } $rows[] = [ diff --git a/src/Debug/RouterCollector.php b/src/Debug/RouterCollector.php index e9dfc59..c1bf9ea 100644 --- a/src/Debug/RouterCollector.php +++ b/src/Debug/RouterCollector.php @@ -12,9 +12,6 @@ use Yiisoft\Yii\Debug\Collector\CollectorTrait; use Yiisoft\Yii\Debug\Collector\SummaryCollectorInterface; -/** - * @codeCoverageIgnore - */ final class RouterCollector implements SummaryCollectorInterface { use CollectorTrait; @@ -134,15 +131,10 @@ private function getMiddlewaresAndAction(?Route $route): array if ($route === null) { return [[], null]; } - $reflection = new ReflectionObject($route); - $reflectionProperty = $reflection->getProperty('middlewareDefinitions'); - $reflectionProperty->setAccessible(true); - /** - * @var array[]|callable[]|string[] $middlewareDefinitions - */ - $middlewareDefinitions = $reflectionProperty->getValue($route); - $action = array_pop($middlewareDefinitions); - return [$middlewareDefinitions, $action]; + $middlewares = $route->getData('enabledMiddlewares'); + $action = array_pop($middlewares); + + return [$middlewares, $action]; } } diff --git a/src/Debug/UrlMatcherInterfaceProxy.php b/src/Debug/UrlMatcherInterfaceProxy.php index bbe625c..53057b7 100644 --- a/src/Debug/UrlMatcherInterfaceProxy.php +++ b/src/Debug/UrlMatcherInterfaceProxy.php @@ -8,13 +8,12 @@ use Yiisoft\Router\MatchingResult; use Yiisoft\Router\UrlMatcherInterface; -/** - * @codeCoverageIgnore - */ final class UrlMatcherInterfaceProxy implements UrlMatcherInterface { - public function __construct(private UrlMatcherInterface $urlMatcher, private RouterCollector $routerCollector) - { + public function __construct( + private UrlMatcherInterface $urlMatcher, + private RouterCollector $routerCollector + ) { } public function match(ServerRequestInterface $request): MatchingResult diff --git a/tests/Debug/DebugRoutesCommandTest.php b/tests/Debug/DebugRoutesCommandTest.php index 30fb9e0..845d165 100644 --- a/tests/Debug/DebugRoutesCommandTest.php +++ b/tests/Debug/DebugRoutesCommandTest.php @@ -7,26 +7,84 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Yiisoft\Router\Debug\DebugRoutesCommand; -use Yiisoft\Router\RouteCollectionInterface; +use Yiisoft\Router\Route; +use Yiisoft\Router\RouteCollection; +use Yiisoft\Router\RouteCollector; +use Yiisoft\Router\Tests\Support\TestController; +use Yiisoft\Router\Tests\Support\TestMiddleware1; use Yiisoft\Yii\Debug\Debugger; use Yiisoft\Yii\Debug\DebuggerIdGenerator; -use Yiisoft\Yii\Debug\Storage\StorageInterface; +use Yiisoft\Yii\Debug\Storage\MemoryStorage; final class DebugRoutesCommandTest extends TestCase { - public function testCommand() + public function testBase(): void { - $routeCollection = $this->createMock(RouteCollectionInterface::class); - $routeCollection->method('getRoutes')->willReturn([]); - $idGenerator = new DebuggerIdGenerator(); - $storage = $this->createMock(StorageInterface::class); - $storage->expects($this->never())->method('clear'); - $debugger = new Debugger($idGenerator, $storage, []); + $debuggerIdGenerator = new DebuggerIdGenerator(); - $command = new DebugRoutesCommand($routeCollection, $debugger); + $command = new DebugRoutesCommand( + new RouteCollection( + (new RouteCollector())->addRoute( + Route::get('/') + ->host('example.com') + ->defaults(['SpecialArg' => 1]) + ->action(fn () => 'Hello, XXXXXX!') + ->name('site/index'), + Route::get('/about') + ->action([TestController::class, 'index']) + ->name('site/about'), + ), + ), + new Debugger( + $debuggerIdGenerator, + new MemoryStorage($debuggerIdGenerator), + [], + ), + ); $commandTester = new CommandTester($command); - $commandTester->execute([]); + $output = $commandTester->getDisplay(); + + $this->assertStringContainsString('site/index', $output); + $this->assertStringContainsString('SpecialArg', $output); + $this->assertStringContainsString('example.com', $output); + $this->assertStringContainsString('XXXXXX', $output); + $this->assertStringContainsString('site/about', $output); + $this->assertStringContainsString(TestController::class . '::index', $output); + } + + public function testSpecificRoute(): void + { + $debuggerIdGenerator = new DebuggerIdGenerator(); + + $command = new DebugRoutesCommand( + new RouteCollection( + (new RouteCollector())->addRoute( + Route::get('/') + ->host('example.com') + ->defaults(['SpecialArg' => 1]) + ->name('site/index') + ->middleware(TestMiddleware1::class) + ->action(fn () => 'Hello world!'), + Route::get('/about')->name('site/about'), + ), + ), + new Debugger( + $debuggerIdGenerator, + new MemoryStorage($debuggerIdGenerator), + [], + ), + ); + + $commandTester = new CommandTester($command); + $commandTester->execute(['route' => ['site/index']]); + $output = $commandTester->getDisplay(); + + $this->assertStringContainsString('site/index', $output); + $this->assertStringContainsString('TestMiddleware1', $output); + $this->assertStringContainsString('SpecialArg', $output); + $this->assertStringContainsString('example.com', $output); + $this->assertStringNotContainsString('site/about', $output); } } diff --git a/tests/Debug/RouterCollectorTest.php b/tests/Debug/RouterCollectorTest.php index e3e5731..651263d 100644 --- a/tests/Debug/RouterCollectorTest.php +++ b/tests/Debug/RouterCollectorTest.php @@ -7,14 +7,17 @@ use PHPUnit\Framework\MockObject\MockObject; use Yiisoft\Di\Container; use Yiisoft\Di\ContainerConfig; +use Yiisoft\Router\CurrentRoute; use Yiisoft\Router\Debug\RouterCollector; use Yiisoft\Router\Group; +use Yiisoft\Router\MatchingResult; use Yiisoft\Router\Route; use Yiisoft\Router\RouteCollection; use Yiisoft\Router\RouteCollectionInterface; use Yiisoft\Router\RouteCollector; use Yiisoft\Router\RouteCollectorInterface; use Yiisoft\Router\UrlMatcherInterface; +use Yiisoft\Test\Support\Container\SimpleContainer; use Yiisoft\Yii\Debug\Collector\CollectorInterface; use Yiisoft\Yii\Debug\Tests\Shared\AbstractCollectorTestCase; @@ -24,6 +27,42 @@ final class RouterCollectorTest extends AbstractCollectorTestCase private ?Container $container = null; + public function testWithoutCurrentRoute(): void + { + $collector = new RouterCollector( + new SimpleContainer() + ); + $collector->startup(); + + $summary = $collector->getSummary(); + + $this->assertNull($summary['router']); + } + + public function testWithoutRouteCollection(): void + { + $route = Route::get('/'); + $arguments = ['a' => 19]; + $result = MatchingResult::fromSuccess($route, $arguments); + + $currentRoute = new CurrentRoute(); + $currentRoute->setRouteWithArguments($result->route(), $result->arguments()); + $collector = new RouterCollector( + new SimpleContainer([ + CurrentRoute::class => $currentRoute, + ]) + ); + $collector->startup(); + + $collected = $collector->getCollected(); + + $this->assertSame(['currentRoute'], array_keys($collected)); + $this->assertSame( + ['matchTime', 'name', 'pattern', 'arguments', 'host', 'uri', 'action', 'middlewares'], + array_keys($collected['currentRoute']) + ); + } + /** * @param CollectorInterface|RouterCollector $collector */ diff --git a/tests/Debug/UrlMatcherInterfaceProxyTest.php b/tests/Debug/UrlMatcherInterfaceProxyTest.php new file mode 100644 index 0000000..c6756d2 --- /dev/null +++ b/tests/Debug/UrlMatcherInterfaceProxyTest.php @@ -0,0 +1,44 @@ + 19]; + $result = MatchingResult::fromSuccess($route, $arguments); + + $currentRoute = new CurrentRoute(); + $currentRoute->setRouteWithArguments($result->route(), $result->arguments()); + + $collector = new RouterCollector( + new SimpleContainer([ + CurrentRoute::class => $currentRoute, + ]) + ); + $collector->startup(); + + $proxy = new UrlMatcherInterfaceProxy(new UrlMatcherStub($result), $collector); + + $proxyResult = $proxy->match($request); + $summary = $collector->getSummary(); + + $this->assertSame($result, $proxyResult); + $this->assertGreaterThan(0, $summary['router']['matchTime']); + } +} diff --git a/tests/Support/UrlMatcherStub.php b/tests/Support/UrlMatcherStub.php new file mode 100644 index 0000000..44db87b --- /dev/null +++ b/tests/Support/UrlMatcherStub.php @@ -0,0 +1,22 @@ +result; + } +}