ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
DispatcherTest.php
Go to the documentation of this file.
1 <?php
2 
3 namespace FastRoute\Dispatcher;
4 
7 
8 abstract 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 
87  public function testDuplicateVariableRoute()
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 
130  public function provideFoundDispatchCases()
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 }
testShadowedStaticRoute()
Static route "/user/nikic" is shadowed by previously defined variable route "/user/([^/]+)" for metho...
testCapturing()
Regex "(en|de)" for parameter "lang" contains a capturing group
testFoundDispatches($method, $uri, $callback, $handler, $argDict)
provideFoundDispatchCases
getDispatcherClass()
Delegate dispatcher selection to child test classes.
testDuplicateStaticRoute()
Cannot register two routes matching "/user" for method "GET"
testDuplicateVariableNameError()
Cannot use the same placeholder "test" twice
addRoute($httpMethod, $route, $handler)
Adds a route to the collection.
testDuplicateVariableRoute()
Cannot register two routes matching "/user/([^/]+)" for method "GET"
testMethodNotAllowedDispatches($method, $uri, $callback, $availableMethods)
provideMethodNotAllowedDispatchCases
generateDispatcherOptions()
Set appropriate options for the specific Dispatcher class we&#39;re testing.
testNotFoundDispatches($method, $uri, $callback)
provideNotFoundDispatchCases
$r
Definition: example_031.php:79
getDataGeneratorClass()
Delegate dataGenerator selection to child test classes.
$info
Definition: index.php:5
$handler