Skip to content

Commit 3591c4c

Browse files
authored
Add InvalidMiddlewareDefinitionException, improve tests, update dev dependencies
1 parent 39b0bd9 commit 3591c4c

6 files changed

+123
-14
lines changed

composer.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
},
2828
"require-dev": {
2929
"nyholm/psr7": "^1.3",
30-
"phpunit/phpunit": "^9.4",
31-
"roave/infection-static-analysis-plugin": "^1.5",
30+
"phpunit/phpunit": "^9.5",
31+
"roave/infection-static-analysis-plugin": "^1.6",
3232
"spatie/phpunit-watcher": "^1.23",
33-
"vimeo/psalm": "^4.2"
33+
"vimeo/psalm": "^4.3"
3434
},
3535
"autoload": {
3636
"psr-4": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Middleware\Dispatcher;
6+
7+
use InvalidArgumentException;
8+
use function get_class;
9+
use function is_array;
10+
use function is_object;
11+
use function is_string;
12+
13+
final class InvalidMiddlewareDefinitionException extends InvalidArgumentException
14+
{
15+
/**
16+
* @param array|callable|string $middlewareDefinition
17+
*/
18+
public function __construct($middlewareDefinition)
19+
{
20+
$message = 'Parameter should be either PSR middleware class name or a callable.';
21+
22+
$definitionString = $this->convertDefinitionToString($middlewareDefinition);
23+
if ($definitionString !== null) {
24+
$message .= ' Got ' . $definitionString . '.';
25+
}
26+
27+
parent::__construct($message);
28+
}
29+
30+
private function convertDefinitionToString($middlewareDefinition): ?string
31+
{
32+
if (is_object($middlewareDefinition)) {
33+
return 'an instance of "' . get_class($middlewareDefinition) . '"';
34+
}
35+
36+
if (is_string($middlewareDefinition)) {
37+
return '"' . $middlewareDefinition . '"';
38+
}
39+
40+
if (is_array($middlewareDefinition)) {
41+
$items = $middlewareDefinition;
42+
foreach ($middlewareDefinition as $key => $item) {
43+
if (!is_string($item)) {
44+
return null;
45+
}
46+
}
47+
array_walk($items, static function (&$item, $key) {
48+
$item = '"' . $item . '"';
49+
if (is_string($key)) {
50+
$item = '"' . $key . '" => ' . $item;
51+
}
52+
});
53+
return '[' . implode(', ', $items) . ']';
54+
}
55+
56+
return null;
57+
}
58+
}

src/MiddlewareFactory.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Yiisoft\Middleware\Dispatcher;
66

7-
use InvalidArgumentException;
87
use Psr\Container\ContainerInterface;
98
use Psr\Http\Message\ResponseInterface;
109
use Psr\Http\Message\ServerRequestInterface;
@@ -96,6 +95,8 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
9695
* are automatically injected using dependency injection container passed to the route.
9796
* Current request and handler could be obtained by type-hinting for {@see ServerRequestInterface}
9897
* and {@see RequestHandlerInterface}.
98+
*
99+
* @throws InvalidMiddlewareDefinitionException
99100
*/
100101
private function validateMiddleware($middlewareDefinition): void
101102
{
@@ -107,7 +108,7 @@ private function validateMiddleware($middlewareDefinition): void
107108
return;
108109
}
109110

110-
throw new InvalidArgumentException('Parameter should be either PSR middleware class name or a callable.');
111+
throw new InvalidMiddlewareDefinitionException($middlewareDefinition);
111112
}
112113

113114
private function isCallable($definition): bool
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Middleware\Dispatcher\Tests;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Yiisoft\Middleware\Dispatcher\InvalidMiddlewareDefinitionException;
9+
use Yiisoft\Middleware\Dispatcher\Tests\Support\TestController;
10+
11+
final class InvalidMiddlewareDefinitionExceptionTest extends TestCase
12+
{
13+
public function dataBase(): array
14+
{
15+
return [
16+
[
17+
'test',
18+
'"test"',
19+
],
20+
[
21+
new TestController(),
22+
'an instance of "Yiisoft\Middleware\Dispatcher\Tests\Support\TestController"',
23+
],
24+
[
25+
[TestController::class, 'notExistsAction'],
26+
'["Yiisoft\Middleware\Dispatcher\Tests\Support\TestController", "notExistsAction"]',
27+
],
28+
[
29+
['class' => TestController::class, 'index'],
30+
'["class" => "Yiisoft\Middleware\Dispatcher\Tests\Support\TestController", "index"]',
31+
],
32+
];
33+
}
34+
35+
/**
36+
* @dataProvider dataBase
37+
*
38+
* @param mixed $definition
39+
* @param string $expected
40+
*/
41+
public function testBase($definition, string $expected): void
42+
{
43+
$exception = new InvalidMiddlewareDefinitionException($definition);
44+
$this->assertStringEndsWith('. Got ' . $expected . '.', $exception->getMessage());
45+
}
46+
}

tests/MiddlewareDispatcherTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace Yiisoft\Router\Tests;
5+
namespace Yiisoft\Middleware\Dispatcher\Tests;
66

77
use Nyholm\Psr7\Response;
88
use Nyholm\Psr7\ServerRequest;

tests/MiddlewareFactoryTest.php

+12-8
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
declare(strict_types=1);
44

5+
namespace Yiisoft\Middleware\Dispatcher\Tests;
6+
57
use PHPUnit\Framework\TestCase;
68
use Psr\Container\ContainerInterface;
79
use Psr\Http\Server\MiddlewareInterface;
10+
use stdClass;
11+
use Yiisoft\Middleware\Dispatcher\InvalidMiddlewareDefinitionException;
812
use Yiisoft\Middleware\Dispatcher\MiddlewareFactory;
913
use Yiisoft\Middleware\Dispatcher\MiddlewareFactoryInterface;
1014
use Yiisoft\Middleware\Dispatcher\Tests\Support\Container;
@@ -29,39 +33,39 @@ public function testCreateFromArray(): void
2933

3034
public function testInvalidMiddleware(): void
3135
{
32-
$this->expectException(\InvalidArgumentException::class);
33-
$this->getMiddlewareFactory()->create(new \stdClass());
36+
$this->expectException(InvalidMiddlewareDefinitionException::class);
37+
$this->getMiddlewareFactory()->create(new stdClass());
3438
}
3539

3640
public function testInvalidMiddlewareAddWrongString(): void
3741
{
38-
$this->expectException(\InvalidArgumentException::class);
42+
$this->expectException(InvalidMiddlewareDefinitionException::class);
3943
$this->getMiddlewareFactory()->create('test');
4044
}
4145

4246
public function testInvalidMiddlewareAddWrongStringClass(): void
4347
{
44-
$this->expectException(\InvalidArgumentException::class);
48+
$this->expectException(InvalidMiddlewareDefinitionException::class);
4549
$this->expectExceptionMessage('Parameter should be either PSR middleware class name or a callable.');
4650
$this->getMiddlewareFactory()->create(TestController::class);
4751
}
4852

4953
public function testInvalidMiddlewareAddWrongArraySize(): void
5054
{
51-
$this->expectException(\InvalidArgumentException::class);
55+
$this->expectException(InvalidMiddlewareDefinitionException::class);
5256
$this->getMiddlewareFactory()->create(['test']);
5357
}
5458

5559
public function testInvalidMiddlewareAddWrongArrayClass(): void
5660
{
57-
$this->expectException(\InvalidArgumentException::class);
61+
$this->expectException(InvalidMiddlewareDefinitionException::class);
5862
$this->getMiddlewareFactory()->create(['class', 'test']);
5963
}
6064

6165
public function testInvalidMiddlewareAddWrongArrayType(): void
6266
{
63-
$this->expectException(\InvalidArgumentException::class);
64-
$this->getMiddlewareFactory()->create(['class' => \Yiisoft\Router\Tests\Support\TestController::class, 'index']);
67+
$this->expectException(InvalidMiddlewareDefinitionException::class);
68+
$this->getMiddlewareFactory()->create(['class' => TestController::class, 'index']);
6569
}
6670

6771
private function getMiddlewareFactory(ContainerInterface $container = null): MiddlewareFactoryInterface

0 commit comments

Comments
 (0)