Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 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\Generator;
13
 
14
use Symfony\Component\Routing\RouteCollection;
15
use Symfony\Component\Routing\Route;
16
use Symfony\Component\Routing\Generator\UrlGenerator;
17
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
18
use Symfony\Component\Routing\RequestContext;
19
 
20
class UrlGeneratorTest extends \PHPUnit_Framework_TestCase
21
{
22
    public function testAbsoluteUrlWithPort80()
23
    {
24
        $routes = $this->getRoutes('test', new Route('/testing'));
25
        $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
26
 
27
        $this->assertEquals('http://localhost/app.php/testing', $url);
28
    }
29
 
30
    public function testAbsoluteSecureUrlWithPort443()
31
    {
32
        $routes = $this->getRoutes('test', new Route('/testing'));
33
        $url = $this->getGenerator($routes, array('scheme' => 'https'))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
34
 
35
        $this->assertEquals('https://localhost/app.php/testing', $url);
36
    }
37
 
38
    public function testAbsoluteUrlWithNonStandardPort()
39
    {
40
        $routes = $this->getRoutes('test', new Route('/testing'));
41
        $url = $this->getGenerator($routes, array('httpPort' => 8080))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
42
 
43
        $this->assertEquals('http://localhost:8080/app.php/testing', $url);
44
    }
45
 
46
    public function testAbsoluteSecureUrlWithNonStandardPort()
47
    {
48
        $routes = $this->getRoutes('test', new Route('/testing'));
49
        $url = $this->getGenerator($routes, array('httpsPort' => 8080, 'scheme' => 'https'))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
50
 
51
        $this->assertEquals('https://localhost:8080/app.php/testing', $url);
52
    }
53
 
54
    public function testRelativeUrlWithoutParameters()
55
    {
56
        $routes = $this->getRoutes('test', new Route('/testing'));
57
        $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
58
 
59
        $this->assertEquals('/app.php/testing', $url);
60
    }
61
 
62
    public function testRelativeUrlWithParameter()
63
    {
64
        $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
65
        $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
66
 
67
        $this->assertEquals('/app.php/testing/bar', $url);
68
    }
69
 
70
    public function testRelativeUrlWithNullParameter()
71
    {
72
        $routes = $this->getRoutes('test', new Route('/testing.{format}', array('format' => null)));
73
        $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
74
 
75
        $this->assertEquals('/app.php/testing', $url);
76
    }
77
 
78
    /**
79
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
80
     */
81
    public function testRelativeUrlWithNullParameterButNotOptional()
82
    {
83
        $routes = $this->getRoutes('test', new Route('/testing/{foo}/bar', array('foo' => null)));
84
        // This must raise an exception because the default requirement for "foo" is "[^/]+" which is not met with these params.
85
        // Generating path "/testing//bar" would be wrong as matching this route would fail.
86
        $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
87
    }
88
 
89
    public function testRelativeUrlWithOptionalZeroParameter()
90
    {
91
        $routes = $this->getRoutes('test', new Route('/testing/{page}'));
92
        $url = $this->getGenerator($routes)->generate('test', array('page' => 0), UrlGeneratorInterface::ABSOLUTE_PATH);
93
 
94
        $this->assertEquals('/app.php/testing/0', $url);
95
    }
96
 
97
    public function testNotPassedOptionalParameterInBetween()
98
    {
99
        $routes = $this->getRoutes('test', new Route('/{slug}/{page}', array('slug' => 'index', 'page' => 0)));
100
        $this->assertSame('/app.php/index/1', $this->getGenerator($routes)->generate('test', array('page' => 1)));
101
        $this->assertSame('/app.php/', $this->getGenerator($routes)->generate('test'));
102
    }
103
 
104
    public function testRelativeUrlWithExtraParameters()
105
    {
106
        $routes = $this->getRoutes('test', new Route('/testing'));
107
        $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
108
 
109
        $this->assertEquals('/app.php/testing?foo=bar', $url);
110
    }
111
 
112
    public function testAbsoluteUrlWithExtraParameters()
113
    {
114
        $routes = $this->getRoutes('test', new Route('/testing'));
115
        $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
116
 
117
        $this->assertEquals('http://localhost/app.php/testing?foo=bar', $url);
118
    }
119
 
120
    public function testUrlWithNullExtraParameters()
121
    {
122
        $routes = $this->getRoutes('test', new Route('/testing'));
123
        $url = $this->getGenerator($routes)->generate('test', array('foo' => null), UrlGeneratorInterface::ABSOLUTE_URL);
124
 
125
        $this->assertEquals('http://localhost/app.php/testing', $url);
126
    }
127
 
128
    public function testUrlWithExtraParametersFromGlobals()
129
    {
130
        $routes = $this->getRoutes('test', new Route('/testing'));
131
        $generator = $this->getGenerator($routes);
132
        $context = new RequestContext('/app.php');
133
        $context->setParameter('bar', 'bar');
134
        $generator->setContext($context);
135
        $url = $generator->generate('test', array('foo' => 'bar'));
136
 
137
        $this->assertEquals('/app.php/testing?foo=bar', $url);
138
    }
139
 
140
    public function testUrlWithGlobalParameter()
141
    {
142
        $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
143
        $generator = $this->getGenerator($routes);
144
        $context = new RequestContext('/app.php');
145
        $context->setParameter('foo', 'bar');
146
        $generator->setContext($context);
147
        $url = $generator->generate('test', array());
148
 
149
        $this->assertEquals('/app.php/testing/bar', $url);
150
    }
151
 
152
    public function testGlobalParameterHasHigherPriorityThanDefault()
153
    {
154
        $routes = $this->getRoutes('test', new Route('/{_locale}', array('_locale' => 'en')));
155
        $generator = $this->getGenerator($routes);
156
        $context = new RequestContext('/app.php');
157
        $context->setParameter('_locale', 'de');
158
        $generator->setContext($context);
159
        $url = $generator->generate('test', array());
160
 
161
        $this->assertSame('/app.php/de', $url);
162
    }
163
 
164
    /**
165
     * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
166
     */
167
    public function testGenerateWithoutRoutes()
168
    {
169
        $routes = $this->getRoutes('foo', new Route('/testing/{foo}'));
170
        $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
171
    }
172
 
173
    /**
174
     * @expectedException \Symfony\Component\Routing\Exception\MissingMandatoryParametersException
175
     */
176
    public function testGenerateForRouteWithoutMandatoryParameter()
177
    {
178
        $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
179
        $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
180
    }
181
 
182
    /**
183
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
184
     */
185
    public function testGenerateForRouteWithInvalidOptionalParameter()
186
    {
187
        $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
188
        $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
189
    }
190
 
191
    /**
192
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
193
     */
194
    public function testGenerateForRouteWithInvalidParameter()
195
    {
196
        $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => '1|2')));
197
        $this->getGenerator($routes)->generate('test', array('foo' => '0'), UrlGeneratorInterface::ABSOLUTE_URL);
198
    }
199
 
200
    public function testGenerateForRouteWithInvalidOptionalParameterNonStrict()
201
    {
202
        $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
203
        $generator = $this->getGenerator($routes);
204
        $generator->setStrictRequirements(false);
205
        $this->assertNull($generator->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL));
206
    }
207
 
208
    public function testGenerateForRouteWithInvalidOptionalParameterNonStrictWithLogger()
209
    {
210
        $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
211
        $logger = $this->getMock('Psr\Log\LoggerInterface');
212
        $logger->expects($this->once())
213
            ->method('error');
214
        $generator = $this->getGenerator($routes, array(), $logger);
215
        $generator->setStrictRequirements(false);
216
        $this->assertNull($generator->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL));
217
    }
218
 
219
    public function testGenerateForRouteWithInvalidParameterButDisabledRequirementsCheck()
220
    {
221
        $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
222
        $generator = $this->getGenerator($routes);
223
        $generator->setStrictRequirements(null);
224
        $this->assertSame('/app.php/testing/bar', $generator->generate('test', array('foo' => 'bar')));
225
    }
226
 
227
    /**
228
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
229
     */
230
    public function testGenerateForRouteWithInvalidMandatoryParameter()
231
    {
232
        $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => 'd+')));
233
        $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
234
    }
235
 
236
    /**
237
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
238
     */
239
    public function testRequiredParamAndEmptyPassed()
240
    {
241
        $routes = $this->getRoutes('test', new Route('/{slug}', array(), array('slug' => '.+')));
242
        $this->getGenerator($routes)->generate('test', array('slug' => ''));
243
    }
244
 
245
    public function testSchemeRequirementDoesNothingIfSameCurrentScheme()
246
    {
247
        $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
248
        $this->assertEquals('/app.php/', $this->getGenerator($routes)->generate('test'));
249
 
250
        $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
251
        $this->assertEquals('/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
252
    }
253
 
254
    public function testSchemeRequirementForcesAbsoluteUrl()
255
    {
256
        $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
257
        $this->assertEquals('https://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
258
 
259
        $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
260
        $this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
261
    }
262
 
263
    public function testSchemeRequirementCreatesUrlForFirstRequiredScheme()
264
    {
265
        $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('Ftp', 'https')));
266
        $this->assertEquals('ftp://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
267
    }
268
 
269
    public function testPathWithTwoStartingSlashes()
270
    {
271
        $routes = $this->getRoutes('test', new Route('//path-and-not-domain'));
272
 
273
        // this must not generate '//path-and-not-domain' because that would be a network path
274
        $this->assertSame('/path-and-not-domain', $this->getGenerator($routes, array('BaseUrl' => ''))->generate('test'));
275
    }
276
 
277
    public function testNoTrailingSlashForMultipleOptionalParameters()
278
    {
279
        $routes = $this->getRoutes('test', new Route('/category/{slug1}/{slug2}/{slug3}', array('slug2' => null, 'slug3' => null)));
280
 
281
        $this->assertEquals('/app.php/category/foo', $this->getGenerator($routes)->generate('test', array('slug1' => 'foo')));
282
    }
283
 
284
    public function testWithAnIntegerAsADefaultValue()
285
    {
286
        $routes = $this->getRoutes('test', new Route('/{default}', array('default' => 0)));
287
 
288
        $this->assertEquals('/app.php/foo', $this->getGenerator($routes)->generate('test', array('default' => 'foo')));
289
    }
290
 
291
    public function testNullForOptionalParameterIsIgnored()
292
    {
293
        $routes = $this->getRoutes('test', new Route('/test/{default}', array('default' => 0)));
294
 
295
        $this->assertEquals('/app.php/test', $this->getGenerator($routes)->generate('test', array('default' => null)));
296
    }
297
 
298
    public function testQueryParamSameAsDefault()
299
    {
300
        $routes = $this->getRoutes('test', new Route('/test', array('page' => 1)));
301
 
302
        $this->assertSame('/app.php/test?page=2', $this->getGenerator($routes)->generate('test', array('page' => 2)));
303
        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('page' => 1)));
304
        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('page' => '1')));
305
        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));
306
    }
307
 
308
    public function testArrayQueryParamSameAsDefault()
309
    {
310
        $routes = $this->getRoutes('test', new Route('/test', array('array' => array('foo', 'bar'))));
311
 
312
        $this->assertSame('/app.php/test?array%5B0%5D=bar&array%5B1%5D=foo', $this->getGenerator($routes)->generate('test', array('array' => array('bar', 'foo'))));
313
        $this->assertSame('/app.php/test?array%5Ba%5D=foo&array%5Bb%5D=bar', $this->getGenerator($routes)->generate('test', array('array' => array('a' => 'foo', 'b' => 'bar'))));
314
        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('array' => array('foo', 'bar'))));
315
        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('array' => array(1 => 'bar', 0 => 'foo'))));
316
        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));
317
    }
318
 
319
    public function testGenerateWithSpecialRouteName()
320
    {
321
        $routes = $this->getRoutes('$péß^a|', new Route('/bar'));
322
 
323
        $this->assertSame('/app.php/bar', $this->getGenerator($routes)->generate('$péß^a|'));
324
    }
325
 
326
    public function testUrlEncoding()
327
    {
328
        // This tests the encoding of reserved characters that are used for delimiting of URI components (defined in RFC 3986)
329
        // and other special ASCII chars. These chars are tested as static text path, variable path and query param.
330
        $chars = '@:[]/()*\'" +,;-._~&$<>|{}%\\^`!?foo=bar#id';
331
        $routes = $this->getRoutes('test', new Route("/$chars/{varpath}", array(), array('varpath' => '.+')));
332
        $this->assertSame('/app.php/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
333
           .'/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
334
           .'?query=%40%3A%5B%5D/%28%29%2A%27%22+%2B%2C%3B-._%7E%26%24%3C%3E%7C%7B%7D%25%5C%5E%60%21%3Ffoo%3Dbar%23id',
335
            $this->getGenerator($routes)->generate('test', array(
336
                'varpath' => $chars,
337
                'query' => $chars,
338
            ))
339
        );
340
    }
341
 
342
    public function testEncodingOfRelativePathSegments()
343
    {
344
        $routes = $this->getRoutes('test', new Route('/dir/../dir/..'));
345
        $this->assertSame('/app.php/dir/%2E%2E/dir/%2E%2E', $this->getGenerator($routes)->generate('test'));
346
        $routes = $this->getRoutes('test', new Route('/dir/./dir/.'));
347
        $this->assertSame('/app.php/dir/%2E/dir/%2E', $this->getGenerator($routes)->generate('test'));
348
        $routes = $this->getRoutes('test', new Route('/a./.a/a../..a/...'));
349
        $this->assertSame('/app.php/a./.a/a../..a/...', $this->getGenerator($routes)->generate('test'));
350
    }
351
 
352
    public function testAdjacentVariables()
353
    {
354
        $routes = $this->getRoutes('test', new Route('/{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '\d+')));
355
        $generator = $this->getGenerator($routes);
356
        $this->assertSame('/app.php/foo123', $generator->generate('test', array('x' => 'foo', 'y' => '123')));
357
        $this->assertSame('/app.php/foo123bar.xml', $generator->generate('test', array('x' => 'foo', 'y' => '123', 'z' => 'bar', '_format' => 'xml')));
358
 
359
        // The default requirement for 'x' should not allow the separator '.' in this case because it would otherwise match everything
360
        // and following optional variables like _format could never match.
361
        $this->setExpectedException('Symfony\Component\Routing\Exception\InvalidParameterException');
362
        $generator->generate('test', array('x' => 'do.t', 'y' => '123', 'z' => 'bar', '_format' => 'xml'));
363
    }
364
 
365
    public function testOptionalVariableWithNoRealSeparator()
366
    {
367
        $routes = $this->getRoutes('test', new Route('/get{what}', array('what' => 'All')));
368
        $generator = $this->getGenerator($routes);
369
 
370
        $this->assertSame('/app.php/get', $generator->generate('test'));
371
        $this->assertSame('/app.php/getSites', $generator->generate('test', array('what' => 'Sites')));
372
    }
373
 
374
    public function testRequiredVariableWithNoRealSeparator()
375
    {
376
        $routes = $this->getRoutes('test', new Route('/get{what}Suffix'));
377
        $generator = $this->getGenerator($routes);
378
 
379
        $this->assertSame('/app.php/getSitesSuffix', $generator->generate('test', array('what' => 'Sites')));
380
    }
381
 
382
    public function testDefaultRequirementOfVariable()
383
    {
384
        $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
385
        $generator = $this->getGenerator($routes);
386
 
387
        $this->assertSame('/app.php/index.mobile.html', $generator->generate('test', array('page' => 'index', '_format' => 'mobile.html')));
388
    }
389
 
390
    /**
391
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
392
     */
393
    public function testDefaultRequirementOfVariableDisallowsSlash()
394
    {
395
        $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
396
        $this->getGenerator($routes)->generate('test', array('page' => 'index', '_format' => 'sl/ash'));
397
    }
398
 
399
    /**
400
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
401
     */
402
    public function testDefaultRequirementOfVariableDisallowsNextSeparator()
403
    {
404
        $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
405
        $this->getGenerator($routes)->generate('test', array('page' => 'do.t', '_format' => 'html'));
406
    }
407
 
408
    public function testWithHostDifferentFromContext()
409
    {
410
        $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
411
 
412
        $this->assertEquals('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', array('name' => 'Fabien', 'locale' => 'fr')));
413
    }
414
 
415
    public function testWithHostSameAsContext()
416
    {
417
        $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
418
 
419
        $this->assertEquals('/app.php/Fabien', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test', array('name' => 'Fabien', 'locale' => 'fr')));
420
    }
421
 
422
    public function testWithHostSameAsContextAndAbsolute()
423
    {
424
        $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
425
 
426
        $this->assertEquals('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test', array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL));
427
    }
428
 
429
    /**
430
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
431
     */
432
    public function testUrlWithInvalidParameterInHost()
433
    {
434
        $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com'));
435
        $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
436
    }
437
 
438
    /**
439
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
440
     */
441
    public function testUrlWithInvalidParameterInHostWhenParamHasADefaultValue()
442
    {
443
        $routes = $this->getRoutes('test', new Route('/', array('foo' => 'bar'), array('foo' => 'bar'), array(), '{foo}.example.com'));
444
        $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
445
    }
446
 
447
    /**
448
     * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
449
     */
450
    public function testUrlWithInvalidParameterEqualsDefaultValueInHost()
451
    {
452
        $routes = $this->getRoutes('test', new Route('/', array('foo' => 'baz'), array('foo' => 'bar'), array(), '{foo}.example.com'));
453
        $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
454
    }
455
 
456
    public function testUrlWithInvalidParameterInHostInNonStrictMode()
457
    {
458
        $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com'));
459
        $generator = $this->getGenerator($routes);
460
        $generator->setStrictRequirements(false);
461
        $this->assertNull($generator->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH));
462
    }
463
 
464
    public function testHostIsCaseInsensitive()
465
    {
466
        $routes = $this->getRoutes('test', new Route('/', array(), array('locale' => 'en|de|fr'), array(), '{locale}.FooBar.com'));
467
        $generator = $this->getGenerator($routes);
468
        $this->assertSame('//EN.FooBar.com/app.php/', $generator->generate('test', array('locale' => 'EN'), UrlGeneratorInterface::NETWORK_PATH));
469
    }
470
 
471
    public function testGenerateNetworkPath()
472
    {
473
        $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com', array('http')));
474
 
475
        $this->assertSame('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
476
            array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'network path with different host'
477
        );
478
        $this->assertSame('//fr.example.com/app.php/Fabien?query=string', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test',
479
            array('name' => 'Fabien', 'locale' => 'fr', 'query' => 'string'), UrlGeneratorInterface::NETWORK_PATH), 'network path although host same as context'
480
        );
481
        $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test',
482
            array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'absolute URL because scheme requirement does not match context'
483
        );
484
        $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
485
            array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL), 'absolute URL with same scheme because it is requested'
486
        );
487
    }
488
 
489
    public function testGenerateRelativePath()
490
    {
491
        $routes = new RouteCollection();
492
        $routes->add('article', new Route('/{author}/{article}/'));
493
        $routes->add('comments', new Route('/{author}/{article}/comments'));
494
        $routes->add('host', new Route('/{article}', array(), array(), array(), '{author}.example.com'));
495
        $routes->add('scheme', new Route('/{author}/blog', array(), array(), array(), '', array('https')));
496
        $routes->add('unrelated', new Route('/about'));
497
 
498
        $generator = $this->getGenerator($routes, array('host' => 'example.com', 'pathInfo' => '/fabien/symfony-is-great/'));
499
 
500
        $this->assertSame('comments', $generator->generate('comments',
501
            array('author' => 'fabien', 'article' => 'symfony-is-great'), UrlGeneratorInterface::RELATIVE_PATH)
502
        );
503
        $this->assertSame('comments?page=2', $generator->generate('comments',
504
            array('author' => 'fabien', 'article' => 'symfony-is-great', 'page' => 2), UrlGeneratorInterface::RELATIVE_PATH)
505
        );
506
        $this->assertSame('../twig-is-great/', $generator->generate('article',
507
            array('author' => 'fabien', 'article' => 'twig-is-great'), UrlGeneratorInterface::RELATIVE_PATH)
508
        );
509
        $this->assertSame('../../bernhard/forms-are-great/', $generator->generate('article',
510
            array('author' => 'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
511
        );
512
        $this->assertSame('//bernhard.example.com/app.php/forms-are-great', $generator->generate('host',
513
            array('author' => 'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
514
        );
515
        $this->assertSame('https://example.com/app.php/bernhard/blog', $generator->generate('scheme',
516
                array('author' => 'bernhard'), UrlGeneratorInterface::RELATIVE_PATH)
517
        );
518
        $this->assertSame('../../about', $generator->generate('unrelated',
519
            array(), UrlGeneratorInterface::RELATIVE_PATH)
520
        );
521
    }
522
 
523
    /**
524
     * @dataProvider provideRelativePaths
525
     */
526
    public function testGetRelativePath($sourcePath, $targetPath, $expectedPath)
527
    {
528
        $this->assertSame($expectedPath, UrlGenerator::getRelativePath($sourcePath, $targetPath));
529
    }
530
 
531
    public function provideRelativePaths()
532
    {
533
        return array(
534
            array(
535
                '/same/dir/',
536
                '/same/dir/',
537
                '',
538
            ),
539
            array(
540
                '/same/file',
541
                '/same/file',
542
                '',
543
            ),
544
            array(
545
                '/',
546
                '/file',
547
                'file',
548
            ),
549
            array(
550
                '/',
551
                '/dir/file',
552
                'dir/file',
553
            ),
554
            array(
555
                '/dir/file.html',
556
                '/dir/different-file.html',
557
                'different-file.html',
558
            ),
559
            array(
560
                '/same/dir/extra-file',
561
                '/same/dir/',
562
                './',
563
            ),
564
            array(
565
                '/parent/dir/',
566
                '/parent/',
567
                '../',
568
            ),
569
            array(
570
                '/parent/dir/extra-file',
571
                '/parent/',
572
                '../',
573
            ),
574
            array(
575
                '/a/b/',
576
                '/x/y/z/',
577
                '../../x/y/z/',
578
            ),
579
            array(
580
                '/a/b/c/d/e',
581
                '/a/c/d',
582
                '../../../c/d',
583
            ),
584
            array(
585
                '/a/b/c//',
586
                '/a/b/c/',
587
                '../',
588
            ),
589
            array(
590
                '/a/b/c/',
591
                '/a/b/c//',
592
                './/',
593
            ),
594
            array(
595
                '/root/a/b/c/',
596
                '/root/x/b/c/',
597
                '../../../x/b/c/',
598
            ),
599
            array(
600
                '/a/b/c/d/',
601
                '/a',
602
                '../../../../a',
603
            ),
604
            array(
605
                '/special-chars/sp%20ce/1€/mäh/e=mc²',
606
                '/special-chars/sp%20ce/1€/<µ>/e=mc²',
607
                '../<µ>/e=mc²',
608
            ),
609
            array(
610
                'not-rooted',
611
                'dir/file',
612
                'dir/file',
613
            ),
614
            array(
615
                '//dir/',
616
                '',
617
                '../../',
618
            ),
619
            array(
620
                '/dir/',
621
                '/dir/file:with-colon',
622
                './file:with-colon',
623
            ),
624
            array(
625
                '/dir/',
626
                '/dir/subdir/file:with-colon',
627
                'subdir/file:with-colon',
628
            ),
629
            array(
630
                '/dir/',
631
                '/dir/:subdir/',
632
                './:subdir/',
633
            ),
634
        );
635
    }
636
 
637
    protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null)
638
    {
639
        $context = new RequestContext('/app.php');
640
        foreach ($parameters as $key => $value) {
641
            $method = 'set'.$key;
642
            $context->$method($value);
643
        }
644
 
645
        return new UrlGenerator($routes, $context, $logger);
646
    }
647
 
648
    protected function getRoutes($name, Route $route)
649
    {
650
        $routes = new RouteCollection();
651
        $routes->add($name, $route);
652
 
653
        return $routes;
654
    }
655
}