66e858a82fd68783bf3b08923022a7e28e1dc4ea
[yaffs-website] / vendor / symfony / routing / Tests / Matcher / Dumper / PhpMatcherDumperTest.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Routing\Tests\Matcher\Dumper;
13
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
16 use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
17 use Symfony\Component\Routing\Matcher\UrlMatcher;
18 use Symfony\Component\Routing\RequestContext;
19 use Symfony\Component\Routing\Route;
20 use Symfony\Component\Routing\RouteCollection;
21
22 class PhpMatcherDumperTest extends TestCase
23 {
24     /**
25      * @var string
26      */
27     private $matcherClass;
28
29     /**
30      * @var string
31      */
32     private $dumpPath;
33
34     protected function setUp()
35     {
36         parent::setUp();
37
38         $this->matcherClass = uniqid('ProjectUrlMatcher');
39         $this->dumpPath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_matcher.'.$this->matcherClass.'.php';
40     }
41
42     protected function tearDown()
43     {
44         parent::tearDown();
45
46         @unlink($this->dumpPath);
47     }
48
49     /**
50      * @expectedException \LogicException
51      */
52     public function testDumpWhenSchemeIsUsedWithoutAProperDumper()
53     {
54         $collection = new RouteCollection();
55         $collection->add('secure', new Route(
56             '/secure',
57             array(),
58             array(),
59             array(),
60             '',
61             array('https')
62         ));
63         $dumper = new PhpMatcherDumper($collection);
64         $dumper->dump();
65     }
66
67     public function testRedirectPreservesUrlEncoding()
68     {
69         $collection = new RouteCollection();
70         $collection->add('foo', new Route('/foo:bar/'));
71
72         $class = $this->generateDumpedMatcher($collection, true);
73
74         $matcher = $this->getMockBuilder($class)
75                         ->setMethods(array('redirect'))
76                         ->setConstructorArgs(array(new RequestContext()))
77                         ->getMock();
78
79         $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/', 'foo')->willReturn(array());
80
81         $matcher->match('/foo%3Abar');
82     }
83
84     /**
85      * @dataProvider getRouteCollections
86      */
87     public function testDump(RouteCollection $collection, $fixture, $options = array())
88     {
89         $basePath = __DIR__.'/../../Fixtures/dumper/';
90
91         $dumper = new PhpMatcherDumper($collection);
92         $this->assertStringEqualsFile($basePath.$fixture, $dumper->dump($options), '->dump() correctly dumps routes as optimized PHP code.');
93     }
94
95     public function getRouteCollections()
96     {
97         /* test case 1 */
98
99         $collection = new RouteCollection();
100
101         $collection->add('overridden', new Route('/overridden'));
102
103         // defaults and requirements
104         $collection->add('foo', new Route(
105             '/foo/{bar}',
106             array('def' => 'test'),
107             array('bar' => 'baz|symfony')
108         ));
109         // method requirement
110         $collection->add('bar', new Route(
111             '/bar/{foo}',
112             array(),
113             array(),
114             array(),
115             '',
116             array(),
117             array('GET', 'head')
118         ));
119         // GET method requirement automatically adds HEAD as valid
120         $collection->add('barhead', new Route(
121             '/barhead/{foo}',
122             array(),
123             array(),
124             array(),
125             '',
126             array(),
127             array('GET')
128         ));
129         // simple
130         $collection->add('baz', new Route(
131             '/test/baz'
132         ));
133         // simple with extension
134         $collection->add('baz2', new Route(
135             '/test/baz.html'
136         ));
137         // trailing slash
138         $collection->add('baz3', new Route(
139             '/test/baz3/'
140         ));
141         // trailing slash with variable
142         $collection->add('baz4', new Route(
143             '/test/{foo}/'
144         ));
145         // trailing slash and method
146         $collection->add('baz5', new Route(
147             '/test/{foo}/',
148             array(),
149             array(),
150             array(),
151             '',
152             array(),
153             array('post')
154         ));
155         // complex name
156         $collection->add('baz.baz6', new Route(
157             '/test/{foo}/',
158             array(),
159             array(),
160             array(),
161             '',
162             array(),
163             array('put')
164         ));
165         // defaults without variable
166         $collection->add('foofoo', new Route(
167             '/foofoo',
168             array('def' => 'test')
169         ));
170         // pattern with quotes
171         $collection->add('quoter', new Route(
172             '/{quoter}',
173             array(),
174             array('quoter' => '[\']+')
175         ));
176         // space in pattern
177         $collection->add('space', new Route(
178             '/spa ce'
179         ));
180
181         // prefixes
182         $collection1 = new RouteCollection();
183         $collection1->add('overridden', new Route('/overridden1'));
184         $collection1->add('foo1', new Route('/{foo}'));
185         $collection1->add('bar1', new Route('/{bar}'));
186         $collection1->addPrefix('/b\'b');
187         $collection2 = new RouteCollection();
188         $collection2->addCollection($collection1);
189         $collection2->add('overridden', new Route('/{var}', array(), array('var' => '.*')));
190         $collection1 = new RouteCollection();
191         $collection1->add('foo2', new Route('/{foo1}'));
192         $collection1->add('bar2', new Route('/{bar1}'));
193         $collection1->addPrefix('/b\'b');
194         $collection2->addCollection($collection1);
195         $collection2->addPrefix('/a');
196         $collection->addCollection($collection2);
197
198         // overridden through addCollection() and multiple sub-collections with no own prefix
199         $collection1 = new RouteCollection();
200         $collection1->add('overridden2', new Route('/old'));
201         $collection1->add('helloWorld', new Route('/hello/{who}', array('who' => 'World!')));
202         $collection2 = new RouteCollection();
203         $collection3 = new RouteCollection();
204         $collection3->add('overridden2', new Route('/new'));
205         $collection3->add('hey', new Route('/hey/'));
206         $collection2->addCollection($collection3);
207         $collection1->addCollection($collection2);
208         $collection1->addPrefix('/multi');
209         $collection->addCollection($collection1);
210
211         // "dynamic" prefix
212         $collection1 = new RouteCollection();
213         $collection1->add('foo3', new Route('/{foo}'));
214         $collection1->add('bar3', new Route('/{bar}'));
215         $collection1->addPrefix('/b');
216         $collection1->addPrefix('{_locale}');
217         $collection->addCollection($collection1);
218
219         // route between collections
220         $collection->add('ababa', new Route('/ababa'));
221
222         // collection with static prefix but only one route
223         $collection1 = new RouteCollection();
224         $collection1->add('foo4', new Route('/{foo}'));
225         $collection1->addPrefix('/aba');
226         $collection->addCollection($collection1);
227
228         // prefix and host
229
230         $collection1 = new RouteCollection();
231
232         $route1 = new Route('/route1', array(), array(), array(), 'a.example.com');
233         $collection1->add('route1', $route1);
234
235         $route2 = new Route('/c2/route2', array(), array(), array(), 'a.example.com');
236         $collection1->add('route2', $route2);
237
238         $route3 = new Route('/c2/route3', array(), array(), array(), 'b.example.com');
239         $collection1->add('route3', $route3);
240
241         $route4 = new Route('/route4', array(), array(), array(), 'a.example.com');
242         $collection1->add('route4', $route4);
243
244         $route5 = new Route('/route5', array(), array(), array(), 'c.example.com');
245         $collection1->add('route5', $route5);
246
247         $route6 = new Route('/route6', array(), array(), array(), null);
248         $collection1->add('route6', $route6);
249
250         $collection->addCollection($collection1);
251
252         // host and variables
253
254         $collection1 = new RouteCollection();
255
256         $route11 = new Route('/route11', array(), array(), array(), '{var1}.example.com');
257         $collection1->add('route11', $route11);
258
259         $route12 = new Route('/route12', array('var1' => 'val'), array(), array(), '{var1}.example.com');
260         $collection1->add('route12', $route12);
261
262         $route13 = new Route('/route13/{name}', array(), array(), array(), '{var1}.example.com');
263         $collection1->add('route13', $route13);
264
265         $route14 = new Route('/route14/{name}', array('var1' => 'val'), array(), array(), '{var1}.example.com');
266         $collection1->add('route14', $route14);
267
268         $route15 = new Route('/route15/{name}', array(), array(), array(), 'c.example.com');
269         $collection1->add('route15', $route15);
270
271         $route16 = new Route('/route16/{name}', array('var1' => 'val'), array(), array(), null);
272         $collection1->add('route16', $route16);
273
274         $route17 = new Route('/route17', array(), array(), array(), null);
275         $collection1->add('route17', $route17);
276
277         $collection->addCollection($collection1);
278
279         // multiple sub-collections with a single route and a prefix each
280         $collection1 = new RouteCollection();
281         $collection1->add('a', new Route('/a...'));
282         $collection2 = new RouteCollection();
283         $collection2->add('b', new Route('/{var}'));
284         $collection3 = new RouteCollection();
285         $collection3->add('c', new Route('/{var}'));
286         $collection3->addPrefix('/c');
287         $collection2->addCollection($collection3);
288         $collection2->addPrefix('/b');
289         $collection1->addCollection($collection2);
290         $collection1->addPrefix('/a');
291         $collection->addCollection($collection1);
292
293         /* test case 2 */
294
295         $redirectCollection = clone $collection;
296
297         // force HTTPS redirection
298         $redirectCollection->add('secure', new Route(
299             '/secure',
300             array(),
301             array(),
302             array(),
303             '',
304             array('https')
305         ));
306
307         // force HTTP redirection
308         $redirectCollection->add('nonsecure', new Route(
309             '/nonsecure',
310             array(),
311             array(),
312             array(),
313             '',
314             array('http')
315         ));
316
317         /* test case 3 */
318
319         $rootprefixCollection = new RouteCollection();
320         $rootprefixCollection->add('static', new Route('/test'));
321         $rootprefixCollection->add('dynamic', new Route('/{var}'));
322         $rootprefixCollection->addPrefix('rootprefix');
323         $route = new Route('/with-condition');
324         $route->setCondition('context.getMethod() == "GET"');
325         $rootprefixCollection->add('with-condition', $route);
326
327         /* test case 4 */
328         $headMatchCasesCollection = new RouteCollection();
329         $headMatchCasesCollection->add('just_head', new Route(
330             '/just_head',
331             array(),
332             array(),
333             array(),
334             '',
335             array(),
336             array('HEAD')
337         ));
338         $headMatchCasesCollection->add('head_and_get', new Route(
339             '/head_and_get',
340             array(),
341             array(),
342             array(),
343             '',
344             array(),
345             array('HEAD', 'GET')
346         ));
347         $headMatchCasesCollection->add('get_and_head', new Route(
348             '/get_and_head',
349             array(),
350             array(),
351             array(),
352             '',
353             array(),
354             array('GET', 'HEAD')
355         ));
356         $headMatchCasesCollection->add('post_and_head', new Route(
357             '/post_and_head',
358             array(),
359             array(),
360             array(),
361             '',
362             array(),
363             array('POST', 'HEAD')
364         ));
365         $headMatchCasesCollection->add('put_and_post', new Route(
366             '/put_and_post',
367             array(),
368             array(),
369             array(),
370             '',
371             array(),
372             array('PUT', 'POST')
373         ));
374         $headMatchCasesCollection->add('put_and_get_and_head', new Route(
375             '/put_and_post',
376             array(),
377             array(),
378             array(),
379             '',
380             array(),
381             array('PUT', 'GET', 'HEAD')
382         ));
383
384         /* test case 5 */
385         $groupOptimisedCollection = new RouteCollection();
386         $groupOptimisedCollection->add('a_first', new Route('/a/11'));
387         $groupOptimisedCollection->add('a_second', new Route('/a/22'));
388         $groupOptimisedCollection->add('a_third', new Route('/a/333'));
389         $groupOptimisedCollection->add('a_wildcard', new Route('/{param}'));
390         $groupOptimisedCollection->add('a_fourth', new Route('/a/44/'));
391         $groupOptimisedCollection->add('a_fifth', new Route('/a/55/'));
392         $groupOptimisedCollection->add('a_sixth', new Route('/a/66/'));
393         $groupOptimisedCollection->add('nested_wildcard', new Route('/nested/{param}'));
394         $groupOptimisedCollection->add('nested_a', new Route('/nested/group/a/'));
395         $groupOptimisedCollection->add('nested_b', new Route('/nested/group/b/'));
396         $groupOptimisedCollection->add('nested_c', new Route('/nested/group/c/'));
397
398         $groupOptimisedCollection->add('slashed_a', new Route('/slashed/group/'));
399         $groupOptimisedCollection->add('slashed_b', new Route('/slashed/group/b/'));
400         $groupOptimisedCollection->add('slashed_c', new Route('/slashed/group/c/'));
401
402         $trailingSlashCollection = new RouteCollection();
403         $trailingSlashCollection->add('simple_trailing_slash_no_methods', new Route('/trailing/simple/no-methods/', array(), array(), array(), '', array(), array()));
404         $trailingSlashCollection->add('simple_trailing_slash_GET_method', new Route('/trailing/simple/get-method/', array(), array(), array(), '', array(), array('GET')));
405         $trailingSlashCollection->add('simple_trailing_slash_HEAD_method', new Route('/trailing/simple/head-method/', array(), array(), array(), '', array(), array('HEAD')));
406         $trailingSlashCollection->add('simple_trailing_slash_POST_method', new Route('/trailing/simple/post-method/', array(), array(), array(), '', array(), array('POST')));
407         $trailingSlashCollection->add('regex_trailing_slash_no_methods', new Route('/trailing/regex/no-methods/{param}/', array(), array(), array(), '', array(), array()));
408         $trailingSlashCollection->add('regex_trailing_slash_GET_method', new Route('/trailing/regex/get-method/{param}/', array(), array(), array(), '', array(), array('GET')));
409         $trailingSlashCollection->add('regex_trailing_slash_HEAD_method', new Route('/trailing/regex/head-method/{param}/', array(), array(), array(), '', array(), array('HEAD')));
410         $trailingSlashCollection->add('regex_trailing_slash_POST_method', new Route('/trailing/regex/post-method/{param}/', array(), array(), array(), '', array(), array('POST')));
411
412         $trailingSlashCollection->add('simple_not_trailing_slash_no_methods', new Route('/not-trailing/simple/no-methods', array(), array(), array(), '', array(), array()));
413         $trailingSlashCollection->add('simple_not_trailing_slash_GET_method', new Route('/not-trailing/simple/get-method', array(), array(), array(), '', array(), array('GET')));
414         $trailingSlashCollection->add('simple_not_trailing_slash_HEAD_method', new Route('/not-trailing/simple/head-method', array(), array(), array(), '', array(), array('HEAD')));
415         $trailingSlashCollection->add('simple_not_trailing_slash_POST_method', new Route('/not-trailing/simple/post-method', array(), array(), array(), '', array(), array('POST')));
416         $trailingSlashCollection->add('regex_not_trailing_slash_no_methods', new Route('/not-trailing/regex/no-methods/{param}', array(), array(), array(), '', array(), array()));
417         $trailingSlashCollection->add('regex_not_trailing_slash_GET_method', new Route('/not-trailing/regex/get-method/{param}', array(), array(), array(), '', array(), array('GET')));
418         $trailingSlashCollection->add('regex_not_trailing_slash_HEAD_method', new Route('/not-trailing/regex/head-method/{param}', array(), array(), array(), '', array(), array('HEAD')));
419         $trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', array(), array(), array(), '', array(), array('POST')));
420
421         return array(
422            array(new RouteCollection(), 'url_matcher0.php', array()),
423            array($collection, 'url_matcher1.php', array()),
424            array($redirectCollection, 'url_matcher2.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
425            array($rootprefixCollection, 'url_matcher3.php', array()),
426            array($headMatchCasesCollection, 'url_matcher4.php', array()),
427            array($groupOptimisedCollection, 'url_matcher5.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
428            array($trailingSlashCollection, 'url_matcher6.php', array()),
429            array($trailingSlashCollection, 'url_matcher7.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
430         );
431     }
432
433     /**
434      * @param $dumper
435      */
436     private function generateDumpedMatcher(RouteCollection $collection, $redirectableStub = false)
437     {
438         $options = array('class' => $this->matcherClass);
439
440         if ($redirectableStub) {
441             $options['base_class'] = '\Symfony\Component\Routing\Tests\Matcher\Dumper\RedirectableUrlMatcherStub';
442         }
443
444         $dumper = new PhpMatcherDumper($collection);
445         $code = $dumper->dump($options);
446
447         file_put_contents($this->dumpPath, $code);
448         include $this->dumpPath;
449
450         return $this->matcherClass;
451     }
452 }
453
454 abstract class RedirectableUrlMatcherStub extends UrlMatcher implements RedirectableUrlMatcherInterface
455 {
456     public function redirect($path, $route, $scheme = null)
457     {
458     }
459 }