AnnotationClassLoaderTest.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Routing\Tests\Loader;
  11. use Symfony\Component\Routing\Annotation\Route;
  12. class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
  13. {
  14. protected $loader;
  15. private $reader;
  16. protected function setUp()
  17. {
  18. parent::setUp();
  19. $this->reader = $this->getReader();
  20. $this->loader = $this->getClassLoader($this->reader);
  21. }
  22. /**
  23. * @expectedException \InvalidArgumentException
  24. */
  25. public function testLoadMissingClass()
  26. {
  27. $this->loader->load('MissingClass');
  28. }
  29. /**
  30. * @expectedException \InvalidArgumentException
  31. */
  32. public function testLoadAbstractClass()
  33. {
  34. $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\AbstractClass');
  35. }
  36. /**
  37. * @dataProvider provideTestSupportsChecksResource
  38. */
  39. public function testSupportsChecksResource($resource, $expectedSupports)
  40. {
  41. $this->assertSame($expectedSupports, $this->loader->supports($resource), '->supports() returns true if the resource is loadable');
  42. }
  43. public function provideTestSupportsChecksResource()
  44. {
  45. return array(
  46. array('class', true),
  47. array('\fully\qualified\class\name', true),
  48. array('namespaced\class\without\leading\slash', true),
  49. array('ÿClassWithLegalSpecialCharacters', true),
  50. array('5', false),
  51. array('foo.foo', false),
  52. array(null, false),
  53. );
  54. }
  55. public function testSupportsChecksTypeIfSpecified()
  56. {
  57. $this->assertTrue($this->loader->supports('class', 'annotation'), '->supports() checks the resource type if specified');
  58. $this->assertFalse($this->loader->supports('class', 'foo'), '->supports() checks the resource type if specified');
  59. }
  60. public function getLoadTests()
  61. {
  62. return array(
  63. array(
  64. 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
  65. array('name' => 'route1', 'path' => '/path'),
  66. array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
  67. ),
  68. array(
  69. 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
  70. array('defaults' => array('arg2' => 'foo'), 'requirements' => array('arg3' => '\w+')),
  71. array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
  72. ),
  73. array(
  74. 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
  75. array('options' => array('foo' => 'bar')),
  76. array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
  77. ),
  78. array(
  79. 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
  80. array('schemes' => array('https'), 'methods' => array('GET')),
  81. array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
  82. ),
  83. array(
  84. 'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
  85. array('condition' => 'context.getMethod() == "GET"'),
  86. array('arg2' => 'defaultValue2', 'arg3' => 'defaultValue3'),
  87. ),
  88. );
  89. }
  90. /**
  91. * @dataProvider getLoadTests
  92. */
  93. public function testLoad($className, $routeData = array(), $methodArgs = array())
  94. {
  95. $routeData = array_replace(array(
  96. 'name' => 'route',
  97. 'path' => '/',
  98. 'requirements' => array(),
  99. 'options' => array(),
  100. 'defaults' => array(),
  101. 'schemes' => array(),
  102. 'methods' => array(),
  103. 'condition' => '',
  104. ), $routeData);
  105. $this->reader
  106. ->expects($this->once())
  107. ->method('getMethodAnnotations')
  108. ->will($this->returnValue(array($this->getAnnotatedRoute($routeData))))
  109. ;
  110. $routeCollection = $this->loader->load($className);
  111. $route = $routeCollection->get($routeData['name']);
  112. $this->assertSame($routeData['path'], $route->getPath(), '->load preserves path annotation');
  113. $this->assertCount(
  114. count($routeData['requirements']),
  115. array_intersect_assoc($routeData['requirements'], $route->getRequirements()),
  116. '->load preserves requirements annotation'
  117. );
  118. $this->assertCount(
  119. count($routeData['options']),
  120. array_intersect_assoc($routeData['options'], $route->getOptions()),
  121. '->load preserves options annotation'
  122. );
  123. $this->assertCount(
  124. count($routeData['defaults']),
  125. $route->getDefaults(),
  126. '->load preserves defaults annotation'
  127. );
  128. $this->assertEquals($routeData['schemes'], $route->getSchemes(), '->load preserves schemes annotation');
  129. $this->assertEquals($routeData['methods'], $route->getMethods(), '->load preserves methods annotation');
  130. $this->assertSame($routeData['condition'], $route->getCondition(), '->load preserves condition annotation');
  131. }
  132. public function testClassRouteLoad()
  133. {
  134. $classRouteData = array(
  135. 'path' => '/prefix',
  136. 'schemes' => array('https'),
  137. 'methods' => array('GET'),
  138. );
  139. $methodRouteData = array(
  140. 'name' => 'route1',
  141. 'path' => '/path',
  142. 'schemes' => array('http'),
  143. 'methods' => array('POST', 'PUT'),
  144. );
  145. $this->reader
  146. ->expects($this->once())
  147. ->method('getClassAnnotation')
  148. ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
  149. ;
  150. $this->reader
  151. ->expects($this->once())
  152. ->method('getMethodAnnotations')
  153. ->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData))))
  154. ;
  155. $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass');
  156. $route = $routeCollection->get($methodRouteData['name']);
  157. $this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path');
  158. $this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes');
  159. $this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods');
  160. }
  161. public function testInvokableClassRouteLoad()
  162. {
  163. $classRouteData = array(
  164. 'name' => 'route1',
  165. 'path' => '/',
  166. 'schemes' => array('https'),
  167. 'methods' => array('GET'),
  168. );
  169. $this->reader
  170. ->expects($this->exactly(2))
  171. ->method('getClassAnnotation')
  172. ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
  173. ;
  174. $this->reader
  175. ->expects($this->once())
  176. ->method('getMethodAnnotations')
  177. ->will($this->returnValue(array()))
  178. ;
  179. $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass');
  180. $route = $routeCollection->get($classRouteData['name']);
  181. $this->assertSame($classRouteData['path'], $route->getPath(), '->load preserves class route path');
  182. $this->assertEquals(array_merge($classRouteData['schemes'], $classRouteData['schemes']), $route->getSchemes(), '->load preserves class route schemes');
  183. $this->assertEquals(array_merge($classRouteData['methods'], $classRouteData['methods']), $route->getMethods(), '->load preserves class route methods');
  184. }
  185. public function testInvokableClassWithMethodRouteLoad()
  186. {
  187. $classRouteData = array(
  188. 'name' => 'route1',
  189. 'path' => '/prefix',
  190. 'schemes' => array('https'),
  191. 'methods' => array('GET'),
  192. );
  193. $methodRouteData = array(
  194. 'name' => 'route2',
  195. 'path' => '/path',
  196. 'schemes' => array('http'),
  197. 'methods' => array('POST', 'PUT'),
  198. );
  199. $this->reader
  200. ->expects($this->once())
  201. ->method('getClassAnnotation')
  202. ->will($this->returnValue($this->getAnnotatedRoute($classRouteData)))
  203. ;
  204. $this->reader
  205. ->expects($this->once())
  206. ->method('getMethodAnnotations')
  207. ->will($this->returnValue(array($this->getAnnotatedRoute($methodRouteData))))
  208. ;
  209. $routeCollection = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass');
  210. $route = $routeCollection->get($classRouteData['name']);
  211. $this->assertNull($route, '->load ignores class route');
  212. $route = $routeCollection->get($methodRouteData['name']);
  213. $this->assertSame($classRouteData['path'].$methodRouteData['path'], $route->getPath(), '->load concatenates class and method route path');
  214. $this->assertEquals(array_merge($classRouteData['schemes'], $methodRouteData['schemes']), $route->getSchemes(), '->load merges class and method route schemes');
  215. $this->assertEquals(array_merge($classRouteData['methods'], $methodRouteData['methods']), $route->getMethods(), '->load merges class and method route methods');
  216. }
  217. private function getAnnotatedRoute($data)
  218. {
  219. return new Route($data);
  220. }
  221. }