ControllerMethodReflectorTest.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\AppFramework\Utility;
  8. use OC\AppFramework\Utility\ControllerMethodReflector;
  9. class BaseController {
  10. /**
  11. * @Annotation
  12. */
  13. public function test() {
  14. }
  15. /**
  16. * @Annotation
  17. */
  18. public function test2() {
  19. }
  20. /**
  21. * @Annotation
  22. */
  23. public function test3() {
  24. }
  25. }
  26. class MiddleController extends BaseController {
  27. /**
  28. * @NoAnnotation
  29. */
  30. public function test2() {
  31. }
  32. public function test3() {
  33. }
  34. /**
  35. * @psalm-param int<-4, 42> $rangedOne
  36. * @psalm-param int<min, max> $rangedTwo
  37. * @return void
  38. */
  39. public function test4(int $rangedOne, int $rangedTwo) {
  40. }
  41. }
  42. class EndController extends MiddleController {
  43. }
  44. class ControllerMethodReflectorTest extends \Test\TestCase {
  45. /**
  46. * @Annotation
  47. */
  48. public function testReadAnnotation(): void {
  49. $reader = new ControllerMethodReflector();
  50. $reader->reflect(
  51. '\Test\AppFramework\Utility\ControllerMethodReflectorTest',
  52. 'testReadAnnotation'
  53. );
  54. $this->assertTrue($reader->hasAnnotation('Annotation'));
  55. }
  56. /**
  57. * @Annotation(parameter=value)
  58. */
  59. public function testGetAnnotationParameterSingle(): void {
  60. $reader = new ControllerMethodReflector();
  61. $reader->reflect(
  62. self::class,
  63. __FUNCTION__
  64. );
  65. $this->assertSame('value', $reader->getAnnotationParameter('Annotation', 'parameter'));
  66. }
  67. /**
  68. * @Annotation(parameter1=value1, parameter2=value2,parameter3=value3)
  69. */
  70. public function testGetAnnotationParameterMultiple(): void {
  71. $reader = new ControllerMethodReflector();
  72. $reader->reflect(
  73. self::class,
  74. __FUNCTION__
  75. );
  76. $this->assertSame('value1', $reader->getAnnotationParameter('Annotation', 'parameter1'));
  77. $this->assertSame('value2', $reader->getAnnotationParameter('Annotation', 'parameter2'));
  78. $this->assertSame('value3', $reader->getAnnotationParameter('Annotation', 'parameter3'));
  79. }
  80. /**
  81. * @Annotation
  82. * @param test
  83. */
  84. public function testReadAnnotationNoLowercase(): void {
  85. $reader = new ControllerMethodReflector();
  86. $reader->reflect(
  87. '\Test\AppFramework\Utility\ControllerMethodReflectorTest',
  88. 'testReadAnnotationNoLowercase'
  89. );
  90. $this->assertTrue($reader->hasAnnotation('Annotation'));
  91. $this->assertFalse($reader->hasAnnotation('param'));
  92. }
  93. /**
  94. * @Annotation
  95. * @param int $test
  96. */
  97. public function testReadTypeIntAnnotations(): void {
  98. $reader = new ControllerMethodReflector();
  99. $reader->reflect(
  100. '\Test\AppFramework\Utility\ControllerMethodReflectorTest',
  101. 'testReadTypeIntAnnotations'
  102. );
  103. $this->assertEquals('int', $reader->getType('test'));
  104. }
  105. /**
  106. * @Annotation
  107. * @param int $a
  108. * @param int $b
  109. */
  110. public function arguments3($a, float $b, int $c, $d) {
  111. }
  112. /**
  113. * @requires PHP 7
  114. */
  115. public function testReadTypeIntAnnotationsScalarTypes(): void {
  116. $reader = new ControllerMethodReflector();
  117. $reader->reflect(
  118. '\Test\AppFramework\Utility\ControllerMethodReflectorTest',
  119. 'arguments3'
  120. );
  121. $this->assertEquals('int', $reader->getType('a'));
  122. $this->assertEquals('float', $reader->getType('b'));
  123. $this->assertEquals('int', $reader->getType('c'));
  124. $this->assertNull($reader->getType('d'));
  125. }
  126. /**
  127. * @Annotation
  128. * @param double $test something special
  129. */
  130. public function testReadTypeDoubleAnnotations(): void {
  131. $reader = new ControllerMethodReflector();
  132. $reader->reflect(
  133. '\Test\AppFramework\Utility\ControllerMethodReflectorTest',
  134. 'testReadTypeDoubleAnnotations'
  135. );
  136. $this->assertEquals('double', $reader->getType('test'));
  137. }
  138. /**
  139. * @Annotation
  140. * @param string $foo
  141. */
  142. public function testReadTypeWhitespaceAnnotations(): void {
  143. $reader = new ControllerMethodReflector();
  144. $reader->reflect(
  145. '\Test\AppFramework\Utility\ControllerMethodReflectorTest',
  146. 'testReadTypeWhitespaceAnnotations'
  147. );
  148. $this->assertEquals('string', $reader->getType('foo'));
  149. }
  150. public function arguments($arg, $arg2 = 'hi') {
  151. }
  152. public function testReflectParameters(): void {
  153. $reader = new ControllerMethodReflector();
  154. $reader->reflect(
  155. '\Test\AppFramework\Utility\ControllerMethodReflectorTest',
  156. 'arguments'
  157. );
  158. $this->assertEquals(['arg' => null, 'arg2' => 'hi'], $reader->getParameters());
  159. }
  160. public function arguments2($arg) {
  161. }
  162. public function testReflectParameters2(): void {
  163. $reader = new ControllerMethodReflector();
  164. $reader->reflect(
  165. '\Test\AppFramework\Utility\ControllerMethodReflectorTest',
  166. 'arguments2'
  167. );
  168. $this->assertEquals(['arg' => null], $reader->getParameters());
  169. }
  170. public function testInheritance(): void {
  171. $reader = new ControllerMethodReflector();
  172. $reader->reflect('Test\AppFramework\Utility\EndController', 'test');
  173. $this->assertTrue($reader->hasAnnotation('Annotation'));
  174. }
  175. public function testInheritanceOverride(): void {
  176. $reader = new ControllerMethodReflector();
  177. $reader->reflect('Test\AppFramework\Utility\EndController', 'test2');
  178. $this->assertTrue($reader->hasAnnotation('NoAnnotation'));
  179. $this->assertFalse($reader->hasAnnotation('Annotation'));
  180. }
  181. public function testInheritanceOverrideNoDocblock(): void {
  182. $reader = new ControllerMethodReflector();
  183. $reader->reflect('Test\AppFramework\Utility\EndController', 'test3');
  184. $this->assertFalse($reader->hasAnnotation('Annotation'));
  185. }
  186. public function testRangeDetection(): void {
  187. $reader = new ControllerMethodReflector();
  188. $reader->reflect('Test\AppFramework\Utility\EndController', 'test4');
  189. $rangeInfo1 = $reader->getRange('rangedOne');
  190. $this->assertSame(-4, $rangeInfo1['min']);
  191. $this->assertSame(42, $rangeInfo1['max']);
  192. $rangeInfo2 = $reader->getRange('rangedTwo');
  193. $this->assertSame(PHP_INT_MIN, $rangeInfo2['min']);
  194. $this->assertSame(PHP_INT_MAX, $rangeInfo2['max']);
  195. }
  196. }