Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix debug classes and add more tests #224

Merged
merged 3 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/Debug/DebugRoutesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -41,7 +38,7 @@
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->debugger->stop();

Check warning on line 41 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ */ protected function execute(InputInterface $input, OutputInterface $output) : int { - $this->debugger->stop(); + $io = new SymfonyStyle($input, $output); if ($input->hasArgument('route') && !empty($input->getArgument('route'))) { /**

Check warning on line 41 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ */ protected function execute(InputInterface $input, OutputInterface $output) : int { - $this->debugger->stop(); + $io = new SymfonyStyle($input, $output); if ($input->hasArgument('route') && !empty($input->getArgument('route'))) { /**

$io = new SymfonyStyle($input, $output);

Expand All @@ -49,26 +46,26 @@
/**
* @var string[] $routes
*/
$routes = (array) $input->getArgument('route');

Check warning on line 49 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "CastArray": --- Original +++ New @@ @@ /** * @var string[] $routes */ - $routes = (array) $input->getArgument('route'); + $routes = $input->getArgument('route'); foreach ($routes as $route) { $route = $this->routeCollection->getRoute($route); $data = $route->__debugInfo();

Check warning on line 49 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "CastArray": --- Original +++ New @@ @@ /** * @var string[] $routes */ - $routes = (array) $input->getArgument('route'); + $routes = $input->getArgument('route'); foreach ($routes as $route) { $route = $this->routeCollection->getRoute($route); $data = $route->__debugInfo();
foreach ($routes as $route) {
$route = $this->routeCollection->getRoute($route);
$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;
}

$io->title($data['name']);

Check warning on line 61 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ $action = array_pop($middlewareDefinitions); $middlewares = $middlewareDefinitions; } - $io->title($data['name']); + $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)];

Check warning on line 61 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ $action = array_pop($middlewareDefinitions); $middlewares = $middlewareDefinitions; } - $io->title($data['name']); + $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)];
$definitionList = [

Check warning on line 62 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }

Check warning on line 62 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }
['Methods' => $this->export($data['methods'])],

Check warning on line 63 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItem": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [['Methods' > $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }

Check warning on line 63 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [[], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }

Check warning on line 63 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItem": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [['Methods' > $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }

Check warning on line 63 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [[], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }
['Name' => $data['name']],

Check warning on line 64 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [['Methods' => $this->export($data['methods'])], [], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }

Check warning on line 64 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [['Methods' => $this->export($data['methods'])], [], ['Pattern' => $data['pattern']]]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }
['Pattern' => $data['pattern']],

Check warning on line 65 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], []]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }

Check warning on line 65 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItemRemoval": --- Original +++ New @@ @@ $middlewares = $middlewareDefinitions; } $io->title($data['name']); - $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; + $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], []]; if (!empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; }
];
if (!empty($action)) {

Check warning on line 67 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "LogicalNot": --- Original +++ New @@ @@ } $io->title($data['name']); $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; - if (!empty($action)) { + if (empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; } if (!empty($data['defaults'])) {

Check warning on line 67 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "LogicalNot": --- Original +++ New @@ @@ } $io->title($data['name']); $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; - if (!empty($action)) { + if (empty($action)) { $definitionList[] = ['Action' => $this->export($action)]; } if (!empty($data['defaults'])) {
$definitionList[] = ['Action' => $this->export($action)];

Check warning on line 68 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItem": --- Original +++ New @@ @@ $io->title($data['name']); $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { - $definitionList[] = ['Action' => $this->export($action)]; + $definitionList[] = ['Action' > $this->export($action)]; } if (!empty($data['defaults'])) { $definitionList[] = ['Defaults' => $this->export($data['defaults'])];

Check warning on line 68 in src/Debug/DebugRoutesCommand.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "ArrayItem": --- Original +++ New @@ @@ $io->title($data['name']); $definitionList = [['Methods' => $this->export($data['methods'])], ['Name' => $data['name']], ['Pattern' => $data['pattern']]]; if (!empty($action)) { - $definitionList[] = ['Action' => $this->export($action)]; + $definitionList[] = ['Action' > $this->export($action)]; } if (!empty($data['defaults'])) { $definitionList[] = ['Defaults' => $this->export($data['defaults'])];
}
if (!empty($data['defaults'])) {
$definitionList[] = ['Defaults' => $this->export($data['defaults'])];
Expand All @@ -94,8 +91,8 @@
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[] = [
Expand Down
16 changes: 4 additions & 12 deletions src/Debug/RouterCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
use Yiisoft\Yii\Debug\Collector\CollectorTrait;
use Yiisoft\Yii\Debug\Collector\SummaryCollectorInterface;

/**
* @codeCoverageIgnore
*/
final class RouterCollector implements SummaryCollectorInterface
{
use CollectorTrait;
Expand Down Expand Up @@ -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];
}
}
9 changes: 4 additions & 5 deletions src/Debug/UrlMatcherInterfaceProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
80 changes: 69 additions & 11 deletions tests/Debug/DebugRoutesCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
39 changes: 39 additions & 0 deletions tests/Debug/RouterCollectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
*/
Expand Down
44 changes: 44 additions & 0 deletions tests/Debug/UrlMatcherInterfaceProxyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Router\Tests\Debug;

use Nyholm\Psr7\ServerRequest;
use PHPUnit\Framework\TestCase;
use Yiisoft\Router\CurrentRoute;
use Yiisoft\Router\Debug\RouterCollector;
use Yiisoft\Router\Debug\UrlMatcherInterfaceProxy;
use Yiisoft\Router\MatchingResult;
use Yiisoft\Router\Route;
use Yiisoft\Router\Tests\Support\UrlMatcherStub;
use Yiisoft\Test\Support\Container\SimpleContainer;

final class UrlMatcherInterfaceProxyTest extends TestCase
{
public function testBase(): void
{
$request = new ServerRequest('GET', '/');
$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();

$proxy = new UrlMatcherInterfaceProxy(new UrlMatcherStub($result), $collector);

$proxyResult = $proxy->match($request);
$summary = $collector->getSummary();

$this->assertSame($result, $proxyResult);
$this->assertGreaterThan(0, $summary['router']['matchTime']);
}
}
22 changes: 22 additions & 0 deletions tests/Support/UrlMatcherStub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Router\Tests\Support;

use Psr\Http\Message\ServerRequestInterface;
use Yiisoft\Router\MatchingResult;
use Yiisoft\Router\UrlMatcherInterface;

final class UrlMatcherStub implements UrlMatcherInterface
{
public function __construct(
private MatchingResult $result
) {
}

public function match(ServerRequestInterface $request): MatchingResult
{
return $this->result;
}
}
Loading