From dc3f7a9ebd465121dc73f2f1c9909cfd488422d2 Mon Sep 17 00:00:00 2001 From: Arturs Vonda Date: Fri, 11 Jul 2014 21:32:20 +0300 Subject: [PATCH 1/2] [Routing] Add matched and default parameters to redirect responses --- .../Matcher/Dumper/PhpMatcherDumper.php | 50 +++++++++++-------- .../Component/Routing/Matcher/UrlMatcher.php | 4 +- .../Tests/Fixtures/dumper/url_matcher2.php | 25 ++++++---- .../Tests/Fixtures/dumper/url_matcher5.php | 45 ++++++++++------- .../Tests/Fixtures/dumper/url_matcher7.php | 30 ++++++----- .../Matcher/RedirectableUrlMatcherTest.php | 18 ++++++- 6 files changed, 108 insertions(+), 64 deletions(-) diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 8eae68c4c2..9a221e6c61 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -333,10 +333,34 @@ EOF; } } + $retOffset = strlen($code); + + // optimize parameters array + if ($matches || $hostMatches) { + $vars = array(); + if ($hostMatches) { + $vars[] = '$hostMatches'; + } + if ($matches) { + $vars[] = '$matches'; + } + $vars[] = "array('_route' => '$name')"; + + $code .= sprintf( + " \$ret = \$this->mergeDefaults(array_replace(%s), %s);\n", + implode(', ', $vars), + str_replace("\n", '', var_export($route->getDefaults(), true)) + ); + } elseif ($route->getDefaults()) { + $code .= sprintf(" \$ret = %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true))); + } else { + $code .= sprintf(" \$ret = array('_route' => '%s');\n", $name); + } + if ($hasTrailingSlash) { $code .= <<redirect(\$pathinfo.'/', '$name'); + return array_replace(\$ret, \$this->redirect(\$pathinfo.'/', '$name')); } @@ -351,33 +375,17 @@ EOF; $code .= <<redirect(\$pathinfo, '$name', key(\$requiredSchemes)); + return array_replace(\$ret, \$this->redirect(\$pathinfo, '$name', key(\$requiredSchemes))); } EOF; } - // optimize parameters array - if ($matches || $hostMatches) { - $vars = array(); - if ($hostMatches) { - $vars[] = '$hostMatches'; - } - if ($matches) { - $vars[] = '$matches'; - } - $vars[] = "array('_route' => '$name')"; - - $code .= sprintf( - " return \$this->mergeDefaults(array_replace(%s), %s);\n", - implode(', ', $vars), - str_replace("\n", '', var_export($route->getDefaults(), true)) - ); - } elseif ($route->getDefaults()) { - $code .= sprintf(" return %s;\n", str_replace("\n", '', var_export(array_replace($route->getDefaults(), array('_route' => $name)), true))); + if ($hasTrailingSlash || $schemes) { + $code .= " return \$ret;\n"; } else { - $code .= sprintf(" return array('_route' => '%s');\n", $name); + $code = substr_replace($code, 'return', $retOffset + 12, 6); } $code .= " }\n"; diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php index c646723b3a..f90555643a 100644 --- a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -164,7 +164,9 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface $status = $this->handleRouteRequirements($pathinfo, $name, $route); if (self::ROUTE_MATCH === $status[0]) { - return $status[1]; + $attributes = array_replace($matches, $hostMatches, (array) $status[1]); + + return $this->mergeDefaults($attributes, $route->getDefaults()); } if (self::REQUIREMENT_MISMATCH === $status[0]) { diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php index 91ec47899e..efab3dba7e 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php @@ -87,22 +87,24 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec // baz3 if ('/test/baz3' === $trimmedPathinfo) { + $ret = array('_route' => 'baz3'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'baz3'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'baz3')); } - return array('_route' => 'baz3'); + return $ret; } } // baz4 if (preg_match('#^/test/(?P[^/]++)/?$#s', $pathinfo, $matches)) { + $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ()); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'baz4'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'baz4')); } - return $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ()); + return $ret; } // baz5 @@ -181,11 +183,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec // hey if ('/multi/hey' === $trimmedPathinfo) { + $ret = array('_route' => 'hey'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'hey'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'hey')); } - return array('_route' => 'hey'); + return $ret; } // overridden2 @@ -326,22 +329,24 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec // secure if ('/secure' === $pathinfo) { + $ret = array('_route' => 'secure'); $requiredSchemes = array ( 'https' => 0,); if (!isset($requiredSchemes[$scheme])) { - return $this->redirect($pathinfo, 'secure', key($requiredSchemes)); + return array_replace($ret, $this->redirect($pathinfo, 'secure', key($requiredSchemes))); } - return array('_route' => 'secure'); + return $ret; } // nonsecure if ('/nonsecure' === $pathinfo) { + $ret = array('_route' => 'nonsecure'); $requiredSchemes = array ( 'http' => 0,); if (!isset($requiredSchemes[$scheme])) { - return $this->redirect($pathinfo, 'nonsecure', key($requiredSchemes)); + return array_replace($ret, $this->redirect($pathinfo, 'nonsecure', key($requiredSchemes))); } - return array('_route' => 'nonsecure'); + return $ret; } throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException(); diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php index 1e6824b341..42258149f5 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php @@ -61,29 +61,32 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec if (0 === strpos($pathinfo, '/a')) { // a_fourth if ('/a/44' === $trimmedPathinfo) { + $ret = array('_route' => 'a_fourth'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'a_fourth'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'a_fourth')); } - return array('_route' => 'a_fourth'); + return $ret; } // a_fifth if ('/a/55' === $trimmedPathinfo) { + $ret = array('_route' => 'a_fifth'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'a_fifth'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'a_fifth')); } - return array('_route' => 'a_fifth'); + return $ret; } // a_sixth if ('/a/66' === $trimmedPathinfo) { + $ret = array('_route' => 'a_sixth'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'a_sixth'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'a_sixth')); } - return array('_route' => 'a_sixth'); + return $ret; } } @@ -96,29 +99,32 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec if (0 === strpos($pathinfo, '/nested/group')) { // nested_a if ('/nested/group/a' === $trimmedPathinfo) { + $ret = array('_route' => 'nested_a'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'nested_a'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_a')); } - return array('_route' => 'nested_a'); + return $ret; } // nested_b if ('/nested/group/b' === $trimmedPathinfo) { + $ret = array('_route' => 'nested_b'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'nested_b'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_b')); } - return array('_route' => 'nested_b'); + return $ret; } // nested_c if ('/nested/group/c' === $trimmedPathinfo) { + $ret = array('_route' => 'nested_c'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'nested_c'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'nested_c')); } - return array('_route' => 'nested_c'); + return $ret; } } @@ -126,29 +132,32 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec elseif (0 === strpos($pathinfo, '/slashed/group')) { // slashed_a if ('/slashed/group' === $trimmedPathinfo) { + $ret = array('_route' => 'slashed_a'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'slashed_a'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_a')); } - return array('_route' => 'slashed_a'); + return $ret; } // slashed_b if ('/slashed/group/b' === $trimmedPathinfo) { + $ret = array('_route' => 'slashed_b'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'slashed_b'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_b')); } - return array('_route' => 'slashed_b'); + return $ret; } // slashed_c if ('/slashed/group/c' === $trimmedPathinfo) { + $ret = array('_route' => 'slashed_c'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'slashed_c'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'slashed_c')); } - return array('_route' => 'slashed_c'); + return $ret; } } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php index 876a90f2da..4548bcf52d 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher7.php @@ -38,11 +38,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec if (0 === strpos($pathinfo, '/trailing/simple')) { // simple_trailing_slash_no_methods if ('/trailing/simple/no-methods' === $trimmedPathinfo) { + $ret = array('_route' => 'simple_trailing_slash_no_methods'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'simple_trailing_slash_no_methods'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_no_methods')); } - return array('_route' => 'simple_trailing_slash_no_methods'); + return $ret; } // simple_trailing_slash_GET_method @@ -52,11 +53,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec goto not_simple_trailing_slash_GET_method; } + $ret = array('_route' => 'simple_trailing_slash_GET_method'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'simple_trailing_slash_GET_method'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_GET_method')); } - return array('_route' => 'simple_trailing_slash_GET_method'); + return $ret; } not_simple_trailing_slash_GET_method: @@ -67,11 +69,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec goto not_simple_trailing_slash_HEAD_method; } + $ret = array('_route' => 'simple_trailing_slash_HEAD_method'); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'simple_trailing_slash_HEAD_method'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'simple_trailing_slash_HEAD_method')); } - return array('_route' => 'simple_trailing_slash_HEAD_method'); + return $ret; } not_simple_trailing_slash_HEAD_method: @@ -91,11 +94,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec elseif (0 === strpos($pathinfo, '/trailing/regex')) { // regex_trailing_slash_no_methods if (0 === strpos($pathinfo, '/trailing/regex/no-methods') && preg_match('#^/trailing/regex/no\\-methods/(?P[^/]++)/?$#s', $pathinfo, $matches)) { + $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ()); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'regex_trailing_slash_no_methods'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_no_methods')); } - return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_no_methods')), array ()); + return $ret; } // regex_trailing_slash_GET_method @@ -105,11 +109,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec goto not_regex_trailing_slash_GET_method; } + $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ()); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'regex_trailing_slash_GET_method'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_GET_method')); } - return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_GET_method')), array ()); + return $ret; } not_regex_trailing_slash_GET_method: @@ -120,11 +125,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec goto not_regex_trailing_slash_HEAD_method; } + $ret = $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ()); if (substr($pathinfo, -1) !== '/') { - return $this->redirect($pathinfo.'/', 'regex_trailing_slash_HEAD_method'); + return array_replace($ret, $this->redirect($pathinfo.'/', 'regex_trailing_slash_HEAD_method')); } - return $this->mergeDefaults(array_replace($matches, array('_route' => 'regex_trailing_slash_HEAD_method')), array ()); + return $ret; } not_regex_trailing_slash_HEAD_method: diff --git a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php index ba4c6e972f..eb9a8492c3 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php @@ -65,8 +65,22 @@ class RedirectableUrlMatcherTest extends TestCase $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); $matcher ->expects($this->never()) - ->method('redirect') - ; + ->method('redirect'); $matcher->match('/foo'); } + + public function testRedirectWithParams() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo/{bar}', array(), array(), array(), '', array('https'))); + + $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); + $matcher + ->expects($this->once()) + ->method('redirect') + ->with('/foo/baz', 'foo', 'https') + ->will($this->returnValue(array('_route' => 'foo'))) + ; + $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz'), $matcher->match('/foo/baz')); + } } From 4c1fdd4edfca4523837e49a390b8a682bab7de50 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sun, 12 Jun 2016 18:04:21 +0200 Subject: [PATCH 2/2] [Routing] also add matched params for redirect due to trailing slash --- .../Routing/RedirectableUrlMatcherTest.php | 2 +- src/Symfony/Component/Routing/CHANGELOG.md | 1 + .../Matcher/Dumper/PhpMatcherDumper.php | 5 ++-- .../Matcher/RedirectableUrlMatcher.php | 4 ++-- .../Component/Routing/Matcher/UrlMatcher.php | 8 +------ .../Matcher/RedirectableUrlMatcherTest.php | 23 +++++++++++++++---- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php index fb5395ea6d..438ca2538d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableUrlMatcherTest.php @@ -33,7 +33,7 @@ class RedirectableUrlMatcherTest extends TestCase 'scheme' => null, 'httpPort' => $context->getHttpPort(), 'httpsPort' => $context->getHttpsPort(), - '_route' => null, + '_route' => 'foo', ), $matcher->match('/foo') ); diff --git a/src/Symfony/Component/Routing/CHANGELOG.md b/src/Symfony/Component/Routing/CHANGELOG.md index 07f8280fe5..b79318e29a 100644 --- a/src/Symfony/Component/Routing/CHANGELOG.md +++ b/src/Symfony/Component/Routing/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG ----- * Added support for prioritized routing loaders. + * Add matched and default parameters to redirect responses 3.3.0 ----- diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 9a221e6c61..cfe8459f4a 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -333,7 +333,8 @@ EOF; } } - $retOffset = strlen($code); + // the offset where the return value is appended below, with indendation + $retOffset = 12 + strlen($code); // optimize parameters array if ($matches || $hostMatches) { @@ -385,7 +386,7 @@ EOF; if ($hasTrailingSlash || $schemes) { $code .= " return \$ret;\n"; } else { - $code = substr_replace($code, 'return', $retOffset + 12, 6); + $code = substr_replace($code, 'return', $retOffset, 6); } $code .= " }\n"; diff --git a/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php index 900c59fa37..3770a9c24c 100644 --- a/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php @@ -32,9 +32,9 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable } try { - parent::match($pathinfo.'/'); + $parameters = parent::match($pathinfo.'/'); - return $this->redirect($pathinfo.'/', null); + return array_replace($parameters, $this->redirect($pathinfo.'/', isset($parameters['_route']) ? $parameters['_route'] : null)); } catch (ResourceNotFoundException $e2) { throw $e; } diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php index f90555643a..df80226cc4 100644 --- a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -163,17 +163,11 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface $status = $this->handleRouteRequirements($pathinfo, $name, $route); - if (self::ROUTE_MATCH === $status[0]) { - $attributes = array_replace($matches, $hostMatches, (array) $status[1]); - - return $this->mergeDefaults($attributes, $route->getDefaults()); - } - if (self::REQUIREMENT_MISMATCH === $status[0]) { continue; } - return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); + return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : array())); } } diff --git a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php index eb9a8492c3..ddd2133e96 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php @@ -24,7 +24,7 @@ class RedirectableUrlMatcherTest extends TestCase $coll->add('foo', new Route('/foo/')); $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); - $matcher->expects($this->once())->method('redirect'); + $matcher->expects($this->once())->method('redirect')->will($this->returnValue(array())); $matcher->match('/foo'); } @@ -69,7 +69,7 @@ class RedirectableUrlMatcherTest extends TestCase $matcher->match('/foo'); } - public function testRedirectWithParams() + public function testSchemeRedirectWithParams() { $coll = new RouteCollection(); $coll->add('foo', new Route('/foo/{bar}', array(), array(), array(), '', array('https'))); @@ -79,8 +79,23 @@ class RedirectableUrlMatcherTest extends TestCase ->expects($this->once()) ->method('redirect') ->with('/foo/baz', 'foo', 'https') - ->will($this->returnValue(array('_route' => 'foo'))) + ->will($this->returnValue(array('redirect' => 'value'))) ; - $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz'), $matcher->match('/foo/baz')); + $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'), $matcher->match('/foo/baz')); + } + + public function testSlashRedirectWithParams() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo/{bar}/')); + + $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); + $matcher + ->expects($this->once()) + ->method('redirect') + ->with('/foo/baz/', 'foo', null) + ->will($this->returnValue(array('redirect' => 'value'))) + ; + $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'), $matcher->match('/foo/baz')); } }