divineniiquaye /
flight-routing
| 1 | <?php declare(strict_types=1); |
||||
| 2 | |||||
| 3 | /* |
||||
| 4 | * This file is part of Flight Routing. |
||||
| 5 | * |
||||
| 6 | * PHP version 8.0 and above required |
||||
| 7 | * |
||||
| 8 | * @author Divine Niiquaye Ibok <[email protected]> |
||||
| 9 | * @copyright 2019 Divine Niiquaye Ibok (https://divinenii.com/) |
||||
| 10 | * @license https://opensource.org/licenses/BSD-3-Clause License |
||||
| 11 | * |
||||
| 12 | * For the full copyright and license information, please view the LICENSE |
||||
| 13 | * file that was distributed with this source code. |
||||
| 14 | */ |
||||
| 15 | |||||
| 16 | namespace Flight\Routing\Tests\Benchmarks; |
||||
| 17 | |||||
| 18 | use Flight\Routing\Exceptions\MethodNotAllowedException; |
||||
| 19 | use Flight\Routing\Interfaces\RouteMatcherInterface; |
||||
| 20 | use Nyholm\Psr7\Uri; |
||||
| 21 | |||||
| 22 | /** |
||||
| 23 | * @Warmup(2) |
||||
| 24 | * @Revs(100) |
||||
| 25 | * @Iterations(5) |
||||
| 26 | * @BeforeClassMethods({"before"}) |
||||
| 27 | */ |
||||
| 28 | abstract class RouteBench |
||||
| 29 | { |
||||
| 30 | protected const MAX_ROUTES = 400; |
||||
| 31 | protected const CACHE_FILE = __DIR__.'/../Fixtures/compiled_test.php'; |
||||
| 32 | |||||
| 33 | /** @var array<string,RouteMatcherInterface> */ |
||||
| 34 | private array $dispatchers = []; |
||||
| 35 | |||||
| 36 | public static function before(): void |
||||
| 37 | { |
||||
| 38 | if (\file_exists(self::CACHE_FILE)) { |
||||
| 39 | @\unlink(self::CACHE_FILE); |
||||
|
0 ignored issues
–
show
|
|||||
| 40 | } |
||||
| 41 | } |
||||
| 42 | |||||
| 43 | /** @return \Generator<string,array<string,mixed>> */ |
||||
| 44 | abstract public function provideStaticRoutes(): iterable; |
||||
| 45 | |||||
| 46 | /** @return \Generator<string,array<string,mixed>> */ |
||||
| 47 | abstract public function provideDynamicRoutes(): iterable; |
||||
| 48 | |||||
| 49 | /** @return \Generator<string,array<string,mixed>> */ |
||||
| 50 | abstract public function provideOtherScenarios(): iterable; |
||||
| 51 | |||||
| 52 | /** @return \Generator<string,array<int,mixed>> */ |
||||
| 53 | public function provideAllScenarios(): iterable |
||||
| 54 | { |
||||
| 55 | yield 'static(first,middle,last,invalid-method)' => \array_values(\iterator_to_array($this->provideStaticRoutes())); |
||||
| 56 | yield 'dynamic(first,middle,last,invalid-method)' => \array_values(\iterator_to_array($this->provideDynamicRoutes())); |
||||
| 57 | yield 'others(non-existent,...)' => \array_values(\iterator_to_array($this->provideOtherScenarios())); |
||||
| 58 | } |
||||
| 59 | |||||
| 60 | /** @return \Generator<string,array<string,string>> */ |
||||
| 61 | public function provideDispatcher(): iterable |
||||
| 62 | { |
||||
| 63 | yield 'not_cached' => ['dispatcher' => 'not_cached']; |
||||
| 64 | yield 'cached' => ['dispatcher' => 'cached']; |
||||
| 65 | } |
||||
| 66 | |||||
| 67 | public function initDispatchers(): void |
||||
| 68 | { |
||||
| 69 | $this->dispatchers['not_cached'] = $this->createDispatcher(); |
||||
| 70 | $this->dispatchers['cached'] = $this->createDispatcher(self::CACHE_FILE); |
||||
| 71 | } |
||||
| 72 | |||||
| 73 | /** |
||||
| 74 | * @BeforeMethods({"initDispatchers"}) |
||||
| 75 | * @ParamProviders({"provideDispatcher", "provideStaticRoutes"}) |
||||
| 76 | */ |
||||
| 77 | public function benchStaticRoutes(array $params): void |
||||
| 78 | { |
||||
| 79 | $this->runScenario($params); |
||||
| 80 | } |
||||
| 81 | |||||
| 82 | /** |
||||
| 83 | * @BeforeMethods({"initDispatchers"}) |
||||
| 84 | * @ParamProviders({"provideDispatcher", "provideDynamicRoutes"}) |
||||
| 85 | */ |
||||
| 86 | public function benchDynamicRoutes(array $params): void |
||||
| 87 | { |
||||
| 88 | $this->runScenario($params); |
||||
| 89 | } |
||||
| 90 | |||||
| 91 | /** |
||||
| 92 | * @BeforeMethods({"initDispatchers"}) |
||||
| 93 | * @ParamProviders({"provideDispatcher", "provideOtherScenarios"}) |
||||
| 94 | */ |
||||
| 95 | public function benchOtherRoutes(array $params): void |
||||
| 96 | { |
||||
| 97 | $this->runScenario($params); |
||||
| 98 | } |
||||
| 99 | |||||
| 100 | /** |
||||
| 101 | * @BeforeMethods({"initDispatchers"}) |
||||
| 102 | * @ParamProviders({"provideDispatcher", "provideAllScenarios"}) |
||||
| 103 | */ |
||||
| 104 | public function benchAll(array $params): void |
||||
| 105 | { |
||||
| 106 | $dispatcher = \array_shift($params); |
||||
| 107 | |||||
| 108 | foreach ($params as $param) { |
||||
| 109 | $this->runScenario($param + \compact('dispatcher')); |
||||
| 110 | } |
||||
| 111 | } |
||||
| 112 | |||||
| 113 | /** |
||||
| 114 | * @ParamProviders({"provideAllScenarios"}) |
||||
| 115 | * @Revs(4) |
||||
| 116 | */ |
||||
| 117 | public function benchWithRouter(array $params): void |
||||
| 118 | { |
||||
| 119 | $this->dispatchers['router'] = $this->createDispatcher(); |
||||
| 120 | |||||
| 121 | foreach ($params as $param) { |
||||
| 122 | $this->runScenario($param + ['dispatcher' => 'router']); |
||||
| 123 | } |
||||
| 124 | } |
||||
| 125 | |||||
| 126 | /** |
||||
| 127 | * @ParamProviders({"provideAllScenarios"}) |
||||
| 128 | * @Revs(4) |
||||
| 129 | */ |
||||
| 130 | public function benchWithCache(array $params): void |
||||
| 131 | { |
||||
| 132 | $this->dispatchers['cached'] = $this->createDispatcher(self::CACHE_FILE); |
||||
| 133 | |||||
| 134 | foreach ($params as $param) { |
||||
| 135 | $this->runScenario($param + ['dispatcher' => 'cached']); |
||||
| 136 | } |
||||
| 137 | } |
||||
| 138 | |||||
| 139 | abstract protected function createDispatcher(string $cache = null): RouteMatcherInterface; |
||||
| 140 | |||||
| 141 | /** |
||||
| 142 | * @param array<string,array<int,mixed>|string> $params |
||||
| 143 | */ |
||||
| 144 | private function runScenario(array $params): void |
||||
| 145 | { |
||||
| 146 | try { |
||||
| 147 | $dispatcher = $this->dispatchers[$params['dispatcher']]; |
||||
| 148 | $result = $params['result'] === $dispatcher->match($params['method'], new Uri($params['route'])); |
||||
|
0 ignored issues
–
show
It seems like
$params['route'] can also be of type array<integer,mixed>; however, parameter $uri of Nyholm\Psr7\Uri::__construct() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 149 | } catch (MethodNotAllowedException $e) { |
||||
| 150 | $result = $params['result'] === $e::class; |
||||
| 151 | } |
||||
| 152 | |||||
| 153 | \assert($result, new \RuntimeException( |
||||
| 154 | \sprintf( |
||||
| 155 | 'Benchmark "%s: %s" failed with method "%s"', |
||||
| 156 | $params['dispatcher'], |
||||
|
0 ignored issues
–
show
It seems like
$params['dispatcher'] can also be of type array<integer,mixed>; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 157 | $params['route'], |
||||
| 158 | $params['method'] |
||||
| 159 | ) |
||||
| 160 | )); |
||||
| 161 | } |
||||
| 162 | } |
||||
| 163 |
If you suppress an error, we recommend checking for the error condition explicitly: