4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Routing\Tests\Generator;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Routing\RouteCollection;
16 use Symfony\Component\Routing\Route;
17 use Symfony\Component\Routing\Generator\UrlGenerator;
18 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
19 use Symfony\Component\Routing\RequestContext;
21 class UrlGeneratorTest extends TestCase
23 public function testAbsoluteUrlWithPort80()
25 $routes = $this->getRoutes('test', new Route('/testing'));
26 $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
28 $this->assertEquals('http://localhost/app.php/testing', $url);
31 public function testAbsoluteSecureUrlWithPort443()
33 $routes = $this->getRoutes('test', new Route('/testing'));
34 $url = $this->getGenerator($routes, array('scheme' => 'https'))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
36 $this->assertEquals('https://localhost/app.php/testing', $url);
39 public function testAbsoluteUrlWithNonStandardPort()
41 $routes = $this->getRoutes('test', new Route('/testing'));
42 $url = $this->getGenerator($routes, array('httpPort' => 8080))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
44 $this->assertEquals('http://localhost:8080/app.php/testing', $url);
47 public function testAbsoluteSecureUrlWithNonStandardPort()
49 $routes = $this->getRoutes('test', new Route('/testing'));
50 $url = $this->getGenerator($routes, array('httpsPort' => 8080, 'scheme' => 'https'))->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
52 $this->assertEquals('https://localhost:8080/app.php/testing', $url);
55 public function testRelativeUrlWithoutParameters()
57 $routes = $this->getRoutes('test', new Route('/testing'));
58 $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
60 $this->assertEquals('/app.php/testing', $url);
63 public function testRelativeUrlWithParameter()
65 $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
66 $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
68 $this->assertEquals('/app.php/testing/bar', $url);
71 public function testRelativeUrlWithNullParameter()
73 $routes = $this->getRoutes('test', new Route('/testing.{format}', array('format' => null)));
74 $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
76 $this->assertEquals('/app.php/testing', $url);
80 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
82 public function testRelativeUrlWithNullParameterButNotOptional()
84 $routes = $this->getRoutes('test', new Route('/testing/{foo}/bar', array('foo' => null)));
85 // This must raise an exception because the default requirement for "foo" is "[^/]+" which is not met with these params.
86 // Generating path "/testing//bar" would be wrong as matching this route would fail.
87 $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
90 public function testRelativeUrlWithOptionalZeroParameter()
92 $routes = $this->getRoutes('test', new Route('/testing/{page}'));
93 $url = $this->getGenerator($routes)->generate('test', array('page' => 0), UrlGeneratorInterface::ABSOLUTE_PATH);
95 $this->assertEquals('/app.php/testing/0', $url);
98 public function testNotPassedOptionalParameterInBetween()
100 $routes = $this->getRoutes('test', new Route('/{slug}/{page}', array('slug' => 'index', 'page' => 0)));
101 $this->assertSame('/app.php/index/1', $this->getGenerator($routes)->generate('test', array('page' => 1)));
102 $this->assertSame('/app.php/', $this->getGenerator($routes)->generate('test'));
105 public function testRelativeUrlWithExtraParameters()
107 $routes = $this->getRoutes('test', new Route('/testing'));
108 $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_PATH);
110 $this->assertEquals('/app.php/testing?foo=bar', $url);
113 public function testAbsoluteUrlWithExtraParameters()
115 $routes = $this->getRoutes('test', new Route('/testing'));
116 $url = $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
118 $this->assertEquals('http://localhost/app.php/testing?foo=bar', $url);
121 public function testUrlWithNullExtraParameters()
123 $routes = $this->getRoutes('test', new Route('/testing'));
124 $url = $this->getGenerator($routes)->generate('test', array('foo' => null), UrlGeneratorInterface::ABSOLUTE_URL);
126 $this->assertEquals('http://localhost/app.php/testing', $url);
129 public function testUrlWithExtraParametersFromGlobals()
131 $routes = $this->getRoutes('test', new Route('/testing'));
132 $generator = $this->getGenerator($routes);
133 $context = new RequestContext('/app.php');
134 $context->setParameter('bar', 'bar');
135 $generator->setContext($context);
136 $url = $generator->generate('test', array('foo' => 'bar'));
138 $this->assertEquals('/app.php/testing?foo=bar', $url);
141 public function testUrlWithGlobalParameter()
143 $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
144 $generator = $this->getGenerator($routes);
145 $context = new RequestContext('/app.php');
146 $context->setParameter('foo', 'bar');
147 $generator->setContext($context);
148 $url = $generator->generate('test', array());
150 $this->assertEquals('/app.php/testing/bar', $url);
153 public function testGlobalParameterHasHigherPriorityThanDefault()
155 $routes = $this->getRoutes('test', new Route('/{_locale}', array('_locale' => 'en')));
156 $generator = $this->getGenerator($routes);
157 $context = new RequestContext('/app.php');
158 $context->setParameter('_locale', 'de');
159 $generator->setContext($context);
160 $url = $generator->generate('test', array());
162 $this->assertSame('/app.php/de', $url);
166 * @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
168 public function testGenerateWithoutRoutes()
170 $routes = $this->getRoutes('foo', new Route('/testing/{foo}'));
171 $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
175 * @expectedException \Symfony\Component\Routing\Exception\MissingMandatoryParametersException
177 public function testGenerateForRouteWithoutMandatoryParameter()
179 $routes = $this->getRoutes('test', new Route('/testing/{foo}'));
180 $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_URL);
184 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
186 public function testGenerateForRouteWithInvalidOptionalParameter()
188 $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
189 $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
193 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
195 public function testGenerateForRouteWithInvalidParameter()
197 $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => '1|2')));
198 $this->getGenerator($routes)->generate('test', array('foo' => '0'), UrlGeneratorInterface::ABSOLUTE_URL);
201 public function testGenerateForRouteWithInvalidOptionalParameterNonStrict()
203 $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
204 $generator = $this->getGenerator($routes);
205 $generator->setStrictRequirements(false);
206 $this->assertNull($generator->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL));
209 public function testGenerateForRouteWithInvalidOptionalParameterNonStrictWithLogger()
211 $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
212 $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
213 $logger->expects($this->once())
215 $generator = $this->getGenerator($routes, array(), $logger);
216 $generator->setStrictRequirements(false);
217 $this->assertNull($generator->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL));
220 public function testGenerateForRouteWithInvalidParameterButDisabledRequirementsCheck()
222 $routes = $this->getRoutes('test', new Route('/testing/{foo}', array('foo' => '1'), array('foo' => 'd+')));
223 $generator = $this->getGenerator($routes);
224 $generator->setStrictRequirements(null);
225 $this->assertSame('/app.php/testing/bar', $generator->generate('test', array('foo' => 'bar')));
229 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
231 public function testGenerateForRouteWithInvalidMandatoryParameter()
233 $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => 'd+')));
234 $this->getGenerator($routes)->generate('test', array('foo' => 'bar'), UrlGeneratorInterface::ABSOLUTE_URL);
238 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
240 public function testGenerateForRouteWithInvalidUtf8Parameter()
242 $routes = $this->getRoutes('test', new Route('/testing/{foo}', array(), array('foo' => '\pL+'), array('utf8' => true)));
243 $this->getGenerator($routes)->generate('test', array('foo' => 'abc123'), UrlGeneratorInterface::ABSOLUTE_URL);
247 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
249 public function testRequiredParamAndEmptyPassed()
251 $routes = $this->getRoutes('test', new Route('/{slug}', array(), array('slug' => '.+')));
252 $this->getGenerator($routes)->generate('test', array('slug' => ''));
255 public function testSchemeRequirementDoesNothingIfSameCurrentScheme()
257 $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
258 $this->assertEquals('/app.php/', $this->getGenerator($routes)->generate('test'));
260 $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
261 $this->assertEquals('/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
264 public function testSchemeRequirementForcesAbsoluteUrl()
266 $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('https')));
267 $this->assertEquals('https://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
269 $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('http')));
270 $this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test'));
273 public function testSchemeRequirementCreatesUrlForFirstRequiredScheme()
275 $routes = $this->getRoutes('test', new Route('/', array(), array(), array(), '', array('Ftp', 'https')));
276 $this->assertEquals('ftp://localhost/app.php/', $this->getGenerator($routes)->generate('test'));
279 public function testPathWithTwoStartingSlashes()
281 $routes = $this->getRoutes('test', new Route('//path-and-not-domain'));
283 // this must not generate '//path-and-not-domain' because that would be a network path
284 $this->assertSame('/path-and-not-domain', $this->getGenerator($routes, array('BaseUrl' => ''))->generate('test'));
287 public function testNoTrailingSlashForMultipleOptionalParameters()
289 $routes = $this->getRoutes('test', new Route('/category/{slug1}/{slug2}/{slug3}', array('slug2' => null, 'slug3' => null)));
291 $this->assertEquals('/app.php/category/foo', $this->getGenerator($routes)->generate('test', array('slug1' => 'foo')));
294 public function testWithAnIntegerAsADefaultValue()
296 $routes = $this->getRoutes('test', new Route('/{default}', array('default' => 0)));
298 $this->assertEquals('/app.php/foo', $this->getGenerator($routes)->generate('test', array('default' => 'foo')));
301 public function testNullForOptionalParameterIsIgnored()
303 $routes = $this->getRoutes('test', new Route('/test/{default}', array('default' => 0)));
305 $this->assertEquals('/app.php/test', $this->getGenerator($routes)->generate('test', array('default' => null)));
308 public function testQueryParamSameAsDefault()
310 $routes = $this->getRoutes('test', new Route('/test', array('page' => 1)));
312 $this->assertSame('/app.php/test?page=2', $this->getGenerator($routes)->generate('test', array('page' => 2)));
313 $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('page' => 1)));
314 $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('page' => '1')));
315 $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));
318 public function testArrayQueryParamSameAsDefault()
320 $routes = $this->getRoutes('test', new Route('/test', array('array' => array('foo', 'bar'))));
322 $this->assertSame('/app.php/test?array%5B0%5D=bar&array%5B1%5D=foo', $this->getGenerator($routes)->generate('test', array('array' => array('bar', 'foo'))));
323 $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'))));
324 $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('array' => array('foo', 'bar'))));
325 $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', array('array' => array(1 => 'bar', 0 => 'foo'))));
326 $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));
329 public function testGenerateWithSpecialRouteName()
331 $routes = $this->getRoutes('$péß^a|', new Route('/bar'));
333 $this->assertSame('/app.php/bar', $this->getGenerator($routes)->generate('$péß^a|'));
336 public function testUrlEncoding()
338 $expectedPath = '/app.php/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
339 .'/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'
340 .'?query=%40%3A%5B%5D/%28%29%2A%27%22%20%2B%2C%3B-._~%26%24%3C%3E%7C%7B%7D%25%5C%5E%60%21%3Ffoo%3Dbar%23id';
342 // This tests the encoding of reserved characters that are used for delimiting of URI components (defined in RFC 3986)
343 // and other special ASCII chars. These chars are tested as static text path, variable path and query param.
344 $chars = '@:[]/()*\'" +,;-._~&$<>|{}%\\^`!?foo=bar#id';
345 $routes = $this->getRoutes('test', new Route("/$chars/{varpath}", array(), array('varpath' => '.+')));
346 $this->assertSame($expectedPath, $this->getGenerator($routes)->generate('test', array(
352 public function testEncodingOfRelativePathSegments()
354 $routes = $this->getRoutes('test', new Route('/dir/../dir/..'));
355 $this->assertSame('/app.php/dir/%2E%2E/dir/%2E%2E', $this->getGenerator($routes)->generate('test'));
356 $routes = $this->getRoutes('test', new Route('/dir/./dir/.'));
357 $this->assertSame('/app.php/dir/%2E/dir/%2E', $this->getGenerator($routes)->generate('test'));
358 $routes = $this->getRoutes('test', new Route('/a./.a/a../..a/...'));
359 $this->assertSame('/app.php/a./.a/a../..a/...', $this->getGenerator($routes)->generate('test'));
362 public function testAdjacentVariables()
364 $routes = $this->getRoutes('test', new Route('/{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '\d+')));
365 $generator = $this->getGenerator($routes);
366 $this->assertSame('/app.php/foo123', $generator->generate('test', array('x' => 'foo', 'y' => '123')));
367 $this->assertSame('/app.php/foo123bar.xml', $generator->generate('test', array('x' => 'foo', 'y' => '123', 'z' => 'bar', '_format' => 'xml')));
369 // The default requirement for 'x' should not allow the separator '.' in this case because it would otherwise match everything
370 // and following optional variables like _format could never match.
371 $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\InvalidParameterException');
372 $generator->generate('test', array('x' => 'do.t', 'y' => '123', 'z' => 'bar', '_format' => 'xml'));
375 public function testOptionalVariableWithNoRealSeparator()
377 $routes = $this->getRoutes('test', new Route('/get{what}', array('what' => 'All')));
378 $generator = $this->getGenerator($routes);
380 $this->assertSame('/app.php/get', $generator->generate('test'));
381 $this->assertSame('/app.php/getSites', $generator->generate('test', array('what' => 'Sites')));
384 public function testRequiredVariableWithNoRealSeparator()
386 $routes = $this->getRoutes('test', new Route('/get{what}Suffix'));
387 $generator = $this->getGenerator($routes);
389 $this->assertSame('/app.php/getSitesSuffix', $generator->generate('test', array('what' => 'Sites')));
392 public function testDefaultRequirementOfVariable()
394 $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
395 $generator = $this->getGenerator($routes);
397 $this->assertSame('/app.php/index.mobile.html', $generator->generate('test', array('page' => 'index', '_format' => 'mobile.html')));
401 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
403 public function testDefaultRequirementOfVariableDisallowsSlash()
405 $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
406 $this->getGenerator($routes)->generate('test', array('page' => 'index', '_format' => 'sl/ash'));
410 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
412 public function testDefaultRequirementOfVariableDisallowsNextSeparator()
414 $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));
415 $this->getGenerator($routes)->generate('test', array('page' => 'do.t', '_format' => 'html'));
418 public function testWithHostDifferentFromContext()
420 $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
422 $this->assertEquals('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', array('name' => 'Fabien', 'locale' => 'fr')));
425 public function testWithHostSameAsContext()
427 $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
429 $this->assertEquals('/app.php/Fabien', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test', array('name' => 'Fabien', 'locale' => 'fr')));
432 public function testWithHostSameAsContextAndAbsolute()
434 $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com'));
436 $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));
440 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
442 public function testUrlWithInvalidParameterInHost()
444 $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com'));
445 $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
449 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
451 public function testUrlWithInvalidParameterInHostWhenParamHasADefaultValue()
453 $routes = $this->getRoutes('test', new Route('/', array('foo' => 'bar'), array('foo' => 'bar'), array(), '{foo}.example.com'));
454 $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
458 * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException
460 public function testUrlWithInvalidParameterEqualsDefaultValueInHost()
462 $routes = $this->getRoutes('test', new Route('/', array('foo' => 'baz'), array('foo' => 'bar'), array(), '{foo}.example.com'));
463 $this->getGenerator($routes)->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH);
466 public function testUrlWithInvalidParameterInHostInNonStrictMode()
468 $routes = $this->getRoutes('test', new Route('/', array(), array('foo' => 'bar'), array(), '{foo}.example.com'));
469 $generator = $this->getGenerator($routes);
470 $generator->setStrictRequirements(false);
471 $this->assertNull($generator->generate('test', array('foo' => 'baz'), UrlGeneratorInterface::ABSOLUTE_PATH));
474 public function testHostIsCaseInsensitive()
476 $routes = $this->getRoutes('test', new Route('/', array(), array('locale' => 'en|de|fr'), array(), '{locale}.FooBar.com'));
477 $generator = $this->getGenerator($routes);
478 $this->assertSame('//EN.FooBar.com/app.php/', $generator->generate('test', array('locale' => 'EN'), UrlGeneratorInterface::NETWORK_PATH));
481 public function testGenerateNetworkPath()
483 $routes = $this->getRoutes('test', new Route('/{name}', array(), array(), array(), '{locale}.example.com', array('http')));
485 $this->assertSame('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
486 array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'network path with different host'
488 $this->assertSame('//fr.example.com/app.php/Fabien?query=string', $this->getGenerator($routes, array('host' => 'fr.example.com'))->generate('test',
489 array('name' => 'Fabien', 'locale' => 'fr', 'query' => 'string'), UrlGeneratorInterface::NETWORK_PATH), 'network path although host same as context'
491 $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, array('scheme' => 'https'))->generate('test',
492 array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::NETWORK_PATH), 'absolute URL because scheme requirement does not match context'
494 $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',
495 array('name' => 'Fabien', 'locale' => 'fr'), UrlGeneratorInterface::ABSOLUTE_URL), 'absolute URL with same scheme because it is requested'
499 public function testGenerateRelativePath()
501 $routes = new RouteCollection();
502 $routes->add('article', new Route('/{author}/{article}/'));
503 $routes->add('comments', new Route('/{author}/{article}/comments'));
504 $routes->add('host', new Route('/{article}', array(), array(), array(), '{author}.example.com'));
505 $routes->add('scheme', new Route('/{author}/blog', array(), array(), array(), '', array('https')));
506 $routes->add('unrelated', new Route('/about'));
508 $generator = $this->getGenerator($routes, array('host' => 'example.com', 'pathInfo' => '/fabien/symfony-is-great/'));
510 $this->assertSame('comments', $generator->generate('comments',
511 array('author' => 'fabien', 'article' => 'symfony-is-great'), UrlGeneratorInterface::RELATIVE_PATH)
513 $this->assertSame('comments?page=2', $generator->generate('comments',
514 array('author' => 'fabien', 'article' => 'symfony-is-great', 'page' => 2), UrlGeneratorInterface::RELATIVE_PATH)
516 $this->assertSame('../twig-is-great/', $generator->generate('article',
517 array('author' => 'fabien', 'article' => 'twig-is-great'), UrlGeneratorInterface::RELATIVE_PATH)
519 $this->assertSame('../../bernhard/forms-are-great/', $generator->generate('article',
520 array('author' => 'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
522 $this->assertSame('//bernhard.example.com/app.php/forms-are-great', $generator->generate('host',
523 array('author' => 'bernhard', 'article' => 'forms-are-great'), UrlGeneratorInterface::RELATIVE_PATH)
525 $this->assertSame('https://example.com/app.php/bernhard/blog', $generator->generate('scheme',
526 array('author' => 'bernhard'), UrlGeneratorInterface::RELATIVE_PATH)
528 $this->assertSame('../../about', $generator->generate('unrelated',
529 array(), UrlGeneratorInterface::RELATIVE_PATH)
534 * @dataProvider provideRelativePaths
536 public function testGetRelativePath($sourcePath, $targetPath, $expectedPath)
538 $this->assertSame($expectedPath, UrlGenerator::getRelativePath($sourcePath, $targetPath));
541 public function provideRelativePaths()
566 '/dir/different-file.html',
567 'different-file.html',
570 '/same/dir/extra-file',
580 '/parent/dir/extra-file',
615 '/special-chars/sp%20ce/1€/mäh/e=mc²',
616 '/special-chars/sp%20ce/1€/<µ>/e=mc²',
631 '/dir/file:with-colon',
636 '/dir/subdir/file:with-colon',
637 'subdir/file:with-colon',
647 public function testFragmentsCanBeAppendedToUrls()
649 $routes = $this->getRoutes('test', new Route('/testing'));
651 $url = $this->getGenerator($routes)->generate('test', array('_fragment' => 'frag ment'), UrlGeneratorInterface::ABSOLUTE_PATH);
652 $this->assertEquals('/app.php/testing#frag%20ment', $url);
654 $url = $this->getGenerator($routes)->generate('test', array('_fragment' => '0'), UrlGeneratorInterface::ABSOLUTE_PATH);
655 $this->assertEquals('/app.php/testing#0', $url);
658 public function testFragmentsDoNotEscapeValidCharacters()
660 $routes = $this->getRoutes('test', new Route('/testing'));
661 $url = $this->getGenerator($routes)->generate('test', array('_fragment' => '?/'), UrlGeneratorInterface::ABSOLUTE_PATH);
663 $this->assertEquals('/app.php/testing#?/', $url);
666 public function testFragmentsCanBeDefinedAsDefaults()
668 $routes = $this->getRoutes('test', new Route('/testing', array('_fragment' => 'fragment')));
669 $url = $this->getGenerator($routes)->generate('test', array(), UrlGeneratorInterface::ABSOLUTE_PATH);
671 $this->assertEquals('/app.php/testing#fragment', $url);
674 protected function getGenerator(RouteCollection $routes, array $parameters = array(), $logger = null)
676 $context = new RequestContext('/app.php');
677 foreach ($parameters as $key => $value) {
678 $method = 'set'.$key;
679 $context->$method($value);
682 return new UrlGenerator($routes, $context, $logger);
685 protected function getRoutes($name, Route $route)
687 $routes = new RouteCollection();
688 $routes->add($name, $route);