From e2505b5cdc89bcde5a17f9238fb944d7be5f4065 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Fri, 23 Jan 2015 18:16:45 +0100 Subject: [PATCH] [Routing] merge instead of replace class and method scheme/method annotations --- .../Routing/Loader/AnnotationClassLoader.php | 4 +- .../Loader/AnnotationClassLoaderTest.php | 79 +++++++++++++------ 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index 92abf3648ace..a76a788aeee1 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -145,8 +145,8 @@ protected function addRoute(RouteCollection $collection, $annot, $globals, \Refl } $requirements = array_replace($globals['requirements'], $annot->getRequirements()); $options = array_replace($globals['options'], $annot->getOptions()); - $schemes = array_replace($globals['schemes'], $annot->getSchemes()); - $methods = array_replace($globals['methods'], $annot->getMethods()); + $schemes = array_merge($globals['schemes'], $annot->getSchemes()); + $methods = array_merge($globals['methods'], $annot->getMethods()); $host = $annot->getHost(); if (null === $host) { diff --git a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php index 03ba15257e37..5f8f4945efe1 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/AnnotationClassLoaderTest.php @@ -73,22 +73,27 @@ public function getLoadTests() return array( array( 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', - array('name' => 'route1'), + array('name' => 'route1', 'path' => '/path'), array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'), ), array( 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', - array('name' => 'route1', 'defaults' => array('arg2' => 'foo')), + array('defaults' => array('arg2' => 'foo'), 'requirements' => array('arg3' => '\w+')), array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'), ), array( 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', - array('name' => 'route1', 'defaults' => array('arg2' => 'foobar')), + array('options' => array('foo' => 'bar')), array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'), ), array( 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', - array('name' => 'route1', 'defaults' => array('arg2' => 'foo'), 'condition' => 'context.getMethod() == "GET"'), + array('schemes' => array('https'), 'methods' => array('GET')), + array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'), + ), + array( + 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass', + array('condition' => 'context.getMethod() == "GET"'), array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'), ), ); @@ -97,9 +102,9 @@ public function getLoadTests() /** * @dataProvider getLoadTests */ - public function testLoad($className, $routeDatas = array(), $methodArgs = array()) + public function testLoad($className, $routeData = array(), $methodArgs = array()) { - $routeDatas = array_replace(array( + $routeData = array_replace(array( 'name' => 'route', 'path' => '/', 'requirements' => array(), @@ -107,52 +112,76 @@ public function testLoad($className, $routeDatas = array(), $methodArgs = array( 'defaults' => array(), 'schemes' => array(), 'methods' => array(), - 'condition' => null, - ), $routeDatas); + 'condition' => '', + ), $routeData); $this->reader ->expects($this->once()) ->method('getMethodAnnotations') - ->will($this->returnValue(array($this->getAnnotatedRoute($routeDatas)))) + ->will($this->returnValue(array($this->getAnnotatedRoute($routeData)))) ; + $routeCollection = $this->loader->load($className); - $route = $routeCollection->get($routeDatas['name']); + $route = $routeCollection->get($routeData['name']); - $this->assertSame($routeDatas['path'], $route->getPath(), '->load preserves path annotation'); - $this->assertSame($routeDatas['requirements'], $route->getRequirements(), '->load preserves requirements annotation'); - $this->assertCount(0, array_intersect($route->getOptions(), $routeDatas['options']), '->load preserves options annotation'); - $this->assertSame(array_replace($methodArgs, $routeDatas['defaults']), $route->getDefaults(), '->load preserves defaults annotation'); - $this->assertEquals($routeDatas['condition'], $route->getCondition(), '->load preserves condition annotation'); + $this->assertSame($routeData['path'], $route->getPath(), '->load preserves path annotation'); + $this->assertCount( + count($routeData['requirements']), + array_intersect_assoc($routeData['requirements'], $route->getRequirements()), + '->load preserves requirements annotation' + ); + $this->assertCount( + count($routeData['options']), + array_intersect_assoc($routeData['options'], $route->getOptions()), + '->load preserves options annotation' + ); + $defaults = array_replace($methodArgs, $routeData['defaults']); + $this->assertCount( + count($defaults), + array_intersect_assoc($defaults, $route->getDefaults()), + '->load preserves defaults annotation and merges them with default arguments in method signature' + ); + $this->assertEquals($routeData['schemes'], $route->getSchemes(), '->load preserves schemes annotation'); + $this->assertEquals($routeData['methods'], $route->getMethods(), '->load preserves methods annotation'); + $this->assertSame($routeData['condition'], $route->getCondition(), '->load preserves condition annotation'); } public function testClassRouteLoad() { - $classRouteDatas = array('path' => '/classRoutePrefix'); + $classRouteData = array( + 'path' => '/prefix', + 'schemes' => array('https'), + 'methods' => array('GET') + ); - $routeDatas = array( + $methodRouteData = array( 'name' => 'route1', - 'path' => '/', + 'path' => '/path', + 'schemes' => array('http'), + 'methods' => array('POST', 'PUT') ); $this->reader ->expects($this->once()) ->method('getClassAnnotation') - ->will($this->returnValue($this->getAnnotatedRoute($classRouteDatas))) + ->will($this->returnValue($this->getAnnotatedRoute($classRouteData))) ; - $this->reader ->expects($this->once()) ->method('getMethodAnnotations') - ->will($this->returnValue(array($this->getAnnotatedRoute($routeDatas)))) + ->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData)))) ; + $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass'); - $route = $routeCollection->get($routeDatas['name']); + $route = $routeCollection->get($methodRouteData['name']); - $this->assertSame($classRouteDatas['path'].$routeDatas['path'], $route->getPath(), '->load preserves class route path annotation'); + $this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path'); + $this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes'); + $this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods'); } - private function getAnnotatedRoute($datas) + private function getAnnotatedRoute($data) { - return new Route($datas); + return new Route($data); } }