ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
DispatcherTest.php
Go to the documentation of this file.
1<?php
2
4
6use PHPUnit\Framework\TestCase;
7
8abstract class DispatcherTest extends TestCase
9{
13 abstract protected function getDispatcherClass();
14
18 abstract protected function getDataGeneratorClass();
19
23 private function generateDispatcherOptions()
24 {
25 return [
26 'dataGenerator' => $this->getDataGeneratorClass(),
27 'dispatcher' => $this->getDispatcherClass()
28 ];
29 }
30
34 public function testFoundDispatches($method, $uri, $callback, $handler, $argDict)
35 {
36 $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
37 $info = $dispatcher->dispatch($method, $uri);
38 $this->assertSame($dispatcher::FOUND, $info[0]);
39 $this->assertSame($handler, $info[1]);
40 $this->assertSame($argDict, $info[2]);
41 }
42
46 public function testNotFoundDispatches($method, $uri, $callback)
47 {
48 $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
49 $routeInfo = $dispatcher->dispatch($method, $uri);
50 $this->assertArrayNotHasKey(1, $routeInfo,
51 'NOT_FOUND result must only contain a single element in the returned info array'
52 );
53 $this->assertSame($dispatcher::NOT_FOUND, $routeInfo[0]);
54 }
55
59 public function testMethodNotAllowedDispatches($method, $uri, $callback, $availableMethods)
60 {
61 $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
62 $routeInfo = $dispatcher->dispatch($method, $uri);
63 $this->assertArrayHasKey(1, $routeInfo,
64 'METHOD_NOT_ALLOWED result must return an array of allowed methods at index 1'
65 );
66
67 list($routedStatus, $methodArray) = $dispatcher->dispatch($method, $uri);
68 $this->assertSame($dispatcher::METHOD_NOT_ALLOWED, $routedStatus);
69 $this->assertSame($availableMethods, $methodArray);
70 }
71
77 {
78 \FastRoute\simpleDispatcher(function (RouteCollector $r) {
79 $r->addRoute('GET', '/foo/{test}/{test:\d+}', 'handler0');
80 }, $this->generateDispatcherOptions());
81 }
82
88 {
89 \FastRoute\simpleDispatcher(function (RouteCollector $r) {
90 $r->addRoute('GET', '/user/{id}', 'handler0'); // oops, forgot \d+ restriction ;)
91 $r->addRoute('GET', '/user/{name}', 'handler1');
92 }, $this->generateDispatcherOptions());
93 }
94
99 public function testDuplicateStaticRoute()
100 {
101 \FastRoute\simpleDispatcher(function (RouteCollector $r) {
102 $r->addRoute('GET', '/user', 'handler0');
103 $r->addRoute('GET', '/user', 'handler1');
104 }, $this->generateDispatcherOptions());
105 }
106
111 public function testShadowedStaticRoute()
112 {
113 \FastRoute\simpleDispatcher(function (RouteCollector $r) {
114 $r->addRoute('GET', '/user/{name}', 'handler0');
115 $r->addRoute('GET', '/user/nikic', 'handler1');
116 }, $this->generateDispatcherOptions());
117 }
118
123 public function testCapturing()
124 {
125 \FastRoute\simpleDispatcher(function (RouteCollector $r) {
126 $r->addRoute('GET', '/{lang:(en|de)}', 'handler0');
127 }, $this->generateDispatcherOptions());
128 }
129
131 {
132 $cases = [];
133
134 // 0 -------------------------------------------------------------------------------------->
135
136 $callback = function (RouteCollector $r) {
137 $r->addRoute('GET', '/resource/123/456', 'handler0');
138 };
139
140 $method = 'GET';
141 $uri = '/resource/123/456';
142 $handler = 'handler0';
143 $argDict = [];
144
145 $cases[] = [$method, $uri, $callback, $handler, $argDict];
146
147 // 1 -------------------------------------------------------------------------------------->
148
149 $callback = function (RouteCollector $r) {
150 $r->addRoute('GET', '/handler0', 'handler0');
151 $r->addRoute('GET', '/handler1', 'handler1');
152 $r->addRoute('GET', '/handler2', 'handler2');
153 };
154
155 $method = 'GET';
156 $uri = '/handler2';
157 $handler = 'handler2';
158 $argDict = [];
159
160 $cases[] = [$method, $uri, $callback, $handler, $argDict];
161
162 // 2 -------------------------------------------------------------------------------------->
163
164 $callback = function (RouteCollector $r) {
165 $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
166 $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
167 $r->addRoute('GET', '/user/{name}', 'handler2');
168 };
169
170 $method = 'GET';
171 $uri = '/user/rdlowrey';
172 $handler = 'handler2';
173 $argDict = ['name' => 'rdlowrey'];
174
175 $cases[] = [$method, $uri, $callback, $handler, $argDict];
176
177 // 3 -------------------------------------------------------------------------------------->
178
179 // reuse $callback from #2
180
181 $method = 'GET';
182 $uri = '/user/12345';
183 $handler = 'handler1';
184 $argDict = ['id' => '12345'];
185
186 $cases[] = [$method, $uri, $callback, $handler, $argDict];
187
188 // 4 -------------------------------------------------------------------------------------->
189
190 // reuse $callback from #3
191
192 $method = 'GET';
193 $uri = '/user/NaN';
194 $handler = 'handler2';
195 $argDict = ['name' => 'NaN'];
196
197 $cases[] = [$method, $uri, $callback, $handler, $argDict];
198
199 // 5 -------------------------------------------------------------------------------------->
200
201 // reuse $callback from #4
202
203 $method = 'GET';
204 $uri = '/user/rdlowrey/12345';
205 $handler = 'handler0';
206 $argDict = ['name' => 'rdlowrey', 'id' => '12345'];
207
208 $cases[] = [$method, $uri, $callback, $handler, $argDict];
209
210 // 6 -------------------------------------------------------------------------------------->
211
212 $callback = function (RouteCollector $r) {
213 $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler0');
214 $r->addRoute('GET', '/user/12345/extension', 'handler1');
215 $r->addRoute('GET', '/user/{id:[0-9]+}.{extension}', 'handler2');
216 };
217
218 $method = 'GET';
219 $uri = '/user/12345.svg';
220 $handler = 'handler2';
221 $argDict = ['id' => '12345', 'extension' => 'svg'];
222
223 $cases[] = [$method, $uri, $callback, $handler, $argDict];
224
225 // 7 ----- Test GET method fallback on HEAD route miss ------------------------------------>
226
227 $callback = function (RouteCollector $r) {
228 $r->addRoute('GET', '/user/{name}', 'handler0');
229 $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler1');
230 $r->addRoute('GET', '/static0', 'handler2');
231 $r->addRoute('GET', '/static1', 'handler3');
232 $r->addRoute('HEAD', '/static1', 'handler4');
233 };
234
235 $method = 'HEAD';
236 $uri = '/user/rdlowrey';
237 $handler = 'handler0';
238 $argDict = ['name' => 'rdlowrey'];
239
240 $cases[] = [$method, $uri, $callback, $handler, $argDict];
241
242 // 8 ----- Test GET method fallback on HEAD route miss ------------------------------------>
243
244 // reuse $callback from #7
245
246 $method = 'HEAD';
247 $uri = '/user/rdlowrey/1234';
248 $handler = 'handler1';
249 $argDict = ['name' => 'rdlowrey', 'id' => '1234'];
250
251 $cases[] = [$method, $uri, $callback, $handler, $argDict];
252
253 // 9 ----- Test GET method fallback on HEAD route miss ------------------------------------>
254
255 // reuse $callback from #8
256
257 $method = 'HEAD';
258 $uri = '/static0';
259 $handler = 'handler2';
260 $argDict = [];
261
262 $cases[] = [$method, $uri, $callback, $handler, $argDict];
263
264 // 10 ---- Test existing HEAD route used if available (no fallback) ----------------------->
265
266 // reuse $callback from #9
267
268 $method = 'HEAD';
269 $uri = '/static1';
270 $handler = 'handler4';
271 $argDict = [];
272
273 $cases[] = [$method, $uri, $callback, $handler, $argDict];
274
275 // 11 ---- More specified routes are not shadowed by less specific of another method ------>
276
277 $callback = function (RouteCollector $r) {
278 $r->addRoute('GET', '/user/{name}', 'handler0');
279 $r->addRoute('POST', '/user/{name:[a-z]+}', 'handler1');
280 };
281
282 $method = 'POST';
283 $uri = '/user/rdlowrey';
284 $handler = 'handler1';
285 $argDict = ['name' => 'rdlowrey'];
286
287 $cases[] = [$method, $uri, $callback, $handler, $argDict];
288
289 // 12 ---- Handler of more specific routes is used, if it occurs first -------------------->
290
291 $callback = function (RouteCollector $r) {
292 $r->addRoute('GET', '/user/{name}', 'handler0');
293 $r->addRoute('POST', '/user/{name:[a-z]+}', 'handler1');
294 $r->addRoute('POST', '/user/{name}', 'handler2');
295 };
296
297 $method = 'POST';
298 $uri = '/user/rdlowrey';
299 $handler = 'handler1';
300 $argDict = ['name' => 'rdlowrey'];
301
302 $cases[] = [$method, $uri, $callback, $handler, $argDict];
303
304 // 13 ---- Route with constant suffix ----------------------------------------------------->
305
306 $callback = function (RouteCollector $r) {
307 $r->addRoute('GET', '/user/{name}', 'handler0');
308 $r->addRoute('GET', '/user/{name}/edit', 'handler1');
309 };
310
311 $method = 'GET';
312 $uri = '/user/rdlowrey/edit';
313 $handler = 'handler1';
314 $argDict = ['name' => 'rdlowrey'];
315
316 $cases[] = [$method, $uri, $callback, $handler, $argDict];
317
318 // 14 ---- Handle multiple methods with the same handler ---------------------------------->
319
320 $callback = function (RouteCollector $r) {
321 $r->addRoute(['GET', 'POST'], '/user', 'handlerGetPost');
322 $r->addRoute(['DELETE'], '/user', 'handlerDelete');
323 $r->addRoute([], '/user', 'handlerNone');
324 };
325
326 $argDict = [];
327 $cases[] = ['GET', '/user', $callback, 'handlerGetPost', $argDict];
328 $cases[] = ['POST', '/user', $callback, 'handlerGetPost', $argDict];
329 $cases[] = ['DELETE', '/user', $callback, 'handlerDelete', $argDict];
330
331 // 17 ----
332
333 $callback = function (RouteCollector $r) {
334 $r->addRoute('POST', '/user.json', 'handler0');
335 $r->addRoute('GET', '/{entity}.json', 'handler1');
336 };
337
338 $cases[] = ['GET', '/user.json', $callback, 'handler1', ['entity' => 'user']];
339
340 // 18 ----
341
342 $callback = function (RouteCollector $r) {
343 $r->addRoute('GET', '', 'handler0');
344 };
345
346 $cases[] = ['GET', '', $callback, 'handler0', []];
347
348 // 19 ----
349
350 $callback = function (RouteCollector $r) {
351 $r->addRoute('HEAD', '/a/{foo}', 'handler0');
352 $r->addRoute('GET', '/b/{foo}', 'handler1');
353 };
354
355 $cases[] = ['HEAD', '/b/bar', $callback, 'handler1', ['foo' => 'bar']];
356
357 // 20 ----
358
359 $callback = function (RouteCollector $r) {
360 $r->addRoute('HEAD', '/a', 'handler0');
361 $r->addRoute('GET', '/b', 'handler1');
362 };
363
364 $cases[] = ['HEAD', '/b', $callback, 'handler1', []];
365
366 // 21 ----
367
368 $callback = function (RouteCollector $r) {
369 $r->addRoute('GET', '/foo', 'handler0');
370 $r->addRoute('HEAD', '/{bar}', 'handler1');
371 };
372
373 $cases[] = ['HEAD', '/foo', $callback, 'handler1', ['bar' => 'foo']];
374
375 // 22 ----
376
377 $callback = function (RouteCollector $r) {
378 $r->addRoute('*', '/user', 'handler0');
379 $r->addRoute('*', '/{user}', 'handler1');
380 $r->addRoute('GET', '/user', 'handler2');
381 };
382
383 $cases[] = ['GET', '/user', $callback, 'handler2', []];
384
385 // 23 ----
386
387 $callback = function (RouteCollector $r) {
388 $r->addRoute('*', '/user', 'handler0');
389 $r->addRoute('GET', '/user', 'handler1');
390 };
391
392 $cases[] = ['POST', '/user', $callback, 'handler0', []];
393
394 // 24 ----
395
396 $cases[] = ['HEAD', '/user', $callback, 'handler1', []];
397
398 // 25 ----
399
400 $callback = function (RouteCollector $r) {
401 $r->addRoute('GET', '/{bar}', 'handler0');
402 $r->addRoute('*', '/foo', 'handler1');
403 };
404
405 $cases[] = ['GET', '/foo', $callback, 'handler0', ['bar' => 'foo']];
406
407 // 26 ----
408
409 $callback = function(RouteCollector $r) {
410 $r->addRoute('GET', '/user', 'handler0');
411 $r->addRoute('*', '/{foo:.*}', 'handler1');
412 };
413
414 $cases[] = ['POST', '/bar', $callback, 'handler1', ['foo' => 'bar']];
415
416 // x -------------------------------------------------------------------------------------->
417
418 return $cases;
419 }
420
422 {
423 $cases = [];
424
425 // 0 -------------------------------------------------------------------------------------->
426
427 $callback = function (RouteCollector $r) {
428 $r->addRoute('GET', '/resource/123/456', 'handler0');
429 };
430
431 $method = 'GET';
432 $uri = '/not-found';
433
434 $cases[] = [$method, $uri, $callback];
435
436 // 1 -------------------------------------------------------------------------------------->
437
438 // reuse callback from #0
439 $method = 'POST';
440 $uri = '/not-found';
441
442 $cases[] = [$method, $uri, $callback];
443
444 // 2 -------------------------------------------------------------------------------------->
445
446 // reuse callback from #1
447 $method = 'PUT';
448 $uri = '/not-found';
449
450 $cases[] = [$method, $uri, $callback];
451
452 // 3 -------------------------------------------------------------------------------------->
453
454 $callback = function (RouteCollector $r) {
455 $r->addRoute('GET', '/handler0', 'handler0');
456 $r->addRoute('GET', '/handler1', 'handler1');
457 $r->addRoute('GET', '/handler2', 'handler2');
458 };
459
460 $method = 'GET';
461 $uri = '/not-found';
462
463 $cases[] = [$method, $uri, $callback];
464
465 // 4 -------------------------------------------------------------------------------------->
466
467 $callback = function (RouteCollector $r) {
468 $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
469 $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
470 $r->addRoute('GET', '/user/{name}', 'handler2');
471 };
472
473 $method = 'GET';
474 $uri = '/not-found';
475
476 $cases[] = [$method, $uri, $callback];
477
478 // 5 -------------------------------------------------------------------------------------->
479
480 // reuse callback from #4
481 $method = 'GET';
482 $uri = '/user/rdlowrey/12345/not-found';
483
484 $cases[] = [$method, $uri, $callback];
485
486 // 6 -------------------------------------------------------------------------------------->
487
488 // reuse callback from #5
489 $method = 'HEAD';
490
491 $cases[] = [$method, $uri, $callback];
492
493 // x -------------------------------------------------------------------------------------->
494
495 return $cases;
496 }
497
499 {
500 $cases = [];
501
502 // 0 -------------------------------------------------------------------------------------->
503
504 $callback = function (RouteCollector $r) {
505 $r->addRoute('GET', '/resource/123/456', 'handler0');
506 };
507
508 $method = 'POST';
509 $uri = '/resource/123/456';
510 $allowedMethods = ['GET'];
511
512 $cases[] = [$method, $uri, $callback, $allowedMethods];
513
514 // 1 -------------------------------------------------------------------------------------->
515
516 $callback = function (RouteCollector $r) {
517 $r->addRoute('GET', '/resource/123/456', 'handler0');
518 $r->addRoute('POST', '/resource/123/456', 'handler1');
519 $r->addRoute('PUT', '/resource/123/456', 'handler2');
520 $r->addRoute('*', '/', 'handler3');
521 };
522
523 $method = 'DELETE';
524 $uri = '/resource/123/456';
525 $allowedMethods = ['GET', 'POST', 'PUT'];
526
527 $cases[] = [$method, $uri, $callback, $allowedMethods];
528
529 // 2 -------------------------------------------------------------------------------------->
530
531 $callback = function (RouteCollector $r) {
532 $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
533 $r->addRoute('POST', '/user/{name}/{id:[0-9]+}', 'handler1');
534 $r->addRoute('PUT', '/user/{name}/{id:[0-9]+}', 'handler2');
535 $r->addRoute('PATCH', '/user/{name}/{id:[0-9]+}', 'handler3');
536 };
537
538 $method = 'DELETE';
539 $uri = '/user/rdlowrey/42';
540 $allowedMethods = ['GET', 'POST', 'PUT', 'PATCH'];
541
542 $cases[] = [$method, $uri, $callback, $allowedMethods];
543
544 // 3 -------------------------------------------------------------------------------------->
545
546 $callback = function (RouteCollector $r) {
547 $r->addRoute('POST', '/user/{name}', 'handler1');
548 $r->addRoute('PUT', '/user/{name:[a-z]+}', 'handler2');
549 $r->addRoute('PATCH', '/user/{name:[a-z]+}', 'handler3');
550 };
551
552 $method = 'GET';
553 $uri = '/user/rdlowrey';
554 $allowedMethods = ['POST', 'PUT', 'PATCH'];
555
556 $cases[] = [$method, $uri, $callback, $allowedMethods];
557
558 // 4 -------------------------------------------------------------------------------------->
559
560 $callback = function (RouteCollector $r) {
561 $r->addRoute(['GET', 'POST'], '/user', 'handlerGetPost');
562 $r->addRoute(['DELETE'], '/user', 'handlerDelete');
563 $r->addRoute([], '/user', 'handlerNone');
564 };
565
566 $cases[] = ['PUT', '/user', $callback, ['GET', 'POST', 'DELETE']];
567
568 // 5
569
570 $callback = function (RouteCollector $r) {
571 $r->addRoute('POST', '/user.json', 'handler0');
572 $r->addRoute('GET', '/{entity}.json', 'handler1');
573 };
574
575 $cases[] = ['PUT', '/user.json', $callback, ['POST', 'GET']];
576
577 // x -------------------------------------------------------------------------------------->
578
579 return $cases;
580 }
581}
An exception for terminatinating execution or to throw for unit testing.
testNotFoundDispatches($method, $uri, $callback)
@dataProvider provideNotFoundDispatchCases
getDispatcherClass()
Delegate dispatcher selection to child test classes.
testMethodNotAllowedDispatches($method, $uri, $callback, $availableMethods)
@dataProvider provideMethodNotAllowedDispatchCases
testShadowedStaticRoute()
@expectedException \FastRoute\BadRouteException @expectedExceptionMessage Static route "/user/nikic" ...
testFoundDispatches($method, $uri, $callback, $handler, $argDict)
@dataProvider provideFoundDispatchCases
generateDispatcherOptions()
Set appropriate options for the specific Dispatcher class we're testing.
testDuplicateStaticRoute()
@expectedException \FastRoute\BadRouteException @expectedExceptionMessage Cannot register two routes ...
testDuplicateVariableNameError()
@expectedException \FastRoute\BadRouteException @expectedExceptionMessage Cannot use the same placeho...
testDuplicateVariableRoute()
@expectedException \FastRoute\BadRouteException @expectedExceptionMessage Cannot register two routes ...
getDataGeneratorClass()
Delegate dataGenerator selection to child test classes.
testCapturing()
@expectedException \FastRoute\BadRouteException @expectedExceptionMessage Regex "(en|de)" for paramet...
$r
Definition: example_031.php:79
$info
Definition: index.php:5
$handler