ParamTest.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <?php declare(strict_types=1);
  2. namespace PhpParser\Builder;
  3. use PhpParser\Node;
  4. use PhpParser\Node\Arg;
  5. use PhpParser\Node\Attribute;
  6. use PhpParser\Node\AttributeGroup;
  7. use PhpParser\Node\Expr;
  8. use PhpParser\Node\Identifier;
  9. use PhpParser\Node\Name;
  10. use PhpParser\Node\Scalar;
  11. use PhpParser\Node\Scalar\LNumber;
  12. class ParamTest extends \PHPUnit\Framework\TestCase
  13. {
  14. public function createParamBuilder($name) {
  15. return new Param($name);
  16. }
  17. /**
  18. * @dataProvider provideTestDefaultValues
  19. */
  20. public function testDefaultValues($value, $expectedValueNode) {
  21. $node = $this->createParamBuilder('test')
  22. ->setDefault($value)
  23. ->getNode()
  24. ;
  25. $this->assertEquals($expectedValueNode, $node->default);
  26. }
  27. public function provideTestDefaultValues() {
  28. return [
  29. [
  30. null,
  31. new Expr\ConstFetch(new Node\Name('null'))
  32. ],
  33. [
  34. true,
  35. new Expr\ConstFetch(new Node\Name('true'))
  36. ],
  37. [
  38. false,
  39. new Expr\ConstFetch(new Node\Name('false'))
  40. ],
  41. [
  42. 31415,
  43. new Scalar\LNumber(31415)
  44. ],
  45. [
  46. 3.1415,
  47. new Scalar\DNumber(3.1415)
  48. ],
  49. [
  50. 'Hallo World',
  51. new Scalar\String_('Hallo World')
  52. ],
  53. [
  54. [1, 2, 3],
  55. new Expr\Array_([
  56. new Expr\ArrayItem(new Scalar\LNumber(1)),
  57. new Expr\ArrayItem(new Scalar\LNumber(2)),
  58. new Expr\ArrayItem(new Scalar\LNumber(3)),
  59. ])
  60. ],
  61. [
  62. ['foo' => 'bar', 'bar' => 'foo'],
  63. new Expr\Array_([
  64. new Expr\ArrayItem(
  65. new Scalar\String_('bar'),
  66. new Scalar\String_('foo')
  67. ),
  68. new Expr\ArrayItem(
  69. new Scalar\String_('foo'),
  70. new Scalar\String_('bar')
  71. ),
  72. ])
  73. ],
  74. [
  75. new Scalar\MagicConst\Dir,
  76. new Scalar\MagicConst\Dir
  77. ]
  78. ];
  79. }
  80. /**
  81. * @dataProvider provideTestTypes
  82. * @dataProvider provideTestNullableTypes
  83. * @dataProvider provideTestUnionTypes
  84. */
  85. public function testTypes($typeHint, $expectedType) {
  86. $node = $this->createParamBuilder('test')
  87. ->setTypeHint($typeHint)
  88. ->getNode()
  89. ;
  90. $type = $node->type;
  91. /* Manually implement comparison to avoid __toString stupidity */
  92. if ($expectedType instanceof Node\NullableType) {
  93. $this->assertInstanceOf(get_class($expectedType), $type);
  94. $expectedType = $expectedType->type;
  95. $type = $type->type;
  96. }
  97. $this->assertInstanceOf(get_class($expectedType), $type);
  98. $this->assertEquals($expectedType, $type);
  99. }
  100. public function provideTestTypes() {
  101. return [
  102. ['array', new Node\Identifier('array')],
  103. ['callable', new Node\Identifier('callable')],
  104. ['bool', new Node\Identifier('bool')],
  105. ['int', new Node\Identifier('int')],
  106. ['float', new Node\Identifier('float')],
  107. ['string', new Node\Identifier('string')],
  108. ['iterable', new Node\Identifier('iterable')],
  109. ['object', new Node\Identifier('object')],
  110. ['Array', new Node\Identifier('array')],
  111. ['CALLABLE', new Node\Identifier('callable')],
  112. ['mixed', new Node\Identifier('mixed')],
  113. ['Some\Class', new Node\Name('Some\Class')],
  114. ['\Foo', new Node\Name\FullyQualified('Foo')],
  115. ['self', new Node\Name('self')],
  116. [new Node\Name('Some\Class'), new Node\Name('Some\Class')],
  117. ];
  118. }
  119. public function provideTestNullableTypes() {
  120. return [
  121. ['?array', new Node\NullableType(new Node\Identifier('array'))],
  122. ['?Some\Class', new Node\NullableType(new Node\Name('Some\Class'))],
  123. [
  124. new Node\NullableType(new Node\Identifier('int')),
  125. new Node\NullableType(new Node\Identifier('int'))
  126. ],
  127. [
  128. new Node\NullableType(new Node\Name('Some\Class')),
  129. new Node\NullableType(new Node\Name('Some\Class'))
  130. ],
  131. ];
  132. }
  133. public function provideTestUnionTypes() {
  134. return [
  135. [
  136. new Node\UnionType([
  137. new Node\Name('Some\Class'),
  138. new Node\Identifier('array'),
  139. ]),
  140. new Node\UnionType([
  141. new Node\Name('Some\Class'),
  142. new Node\Identifier('array'),
  143. ]),
  144. ],
  145. [
  146. new Node\UnionType([
  147. new Node\Identifier('self'),
  148. new Node\Identifier('array'),
  149. new Node\Name\FullyQualified('Foo')
  150. ]),
  151. new Node\UnionType([
  152. new Node\Identifier('self'),
  153. new Node\Identifier('array'),
  154. new Node\Name\FullyQualified('Foo')
  155. ]),
  156. ],
  157. ];
  158. }
  159. public function testVoidTypeError() {
  160. $this->expectException(\LogicException::class);
  161. $this->expectExceptionMessage('Parameter type cannot be void');
  162. $this->createParamBuilder('test')->setType('void');
  163. }
  164. public function testInvalidTypeError() {
  165. $this->expectException(\LogicException::class);
  166. $this->expectExceptionMessage('Type must be a string, or an instance of Name, Identifier or ComplexType');
  167. $this->createParamBuilder('test')->setType(new \stdClass);
  168. }
  169. public function testByRef() {
  170. $node = $this->createParamBuilder('test')
  171. ->makeByRef()
  172. ->getNode()
  173. ;
  174. $this->assertEquals(
  175. new Node\Param(new Expr\Variable('test'), null, null, true),
  176. $node
  177. );
  178. }
  179. public function testVariadic() {
  180. $node = $this->createParamBuilder('test')
  181. ->makeVariadic()
  182. ->getNode()
  183. ;
  184. $this->assertEquals(
  185. new Node\Param(new Expr\Variable('test'), null, null, false, true),
  186. $node
  187. );
  188. }
  189. public function testMakePublic() {
  190. $node = $this->createParamBuilder('test')
  191. ->makePublic()
  192. ->getNode()
  193. ;
  194. $this->assertEquals(
  195. new Node\Param(new Expr\Variable('test'), null, null, false, false, [], Node\Stmt\Class_::MODIFIER_PUBLIC),
  196. $node
  197. );
  198. }
  199. public function testMakeProtected() {
  200. $node = $this->createParamBuilder('test')
  201. ->makeProtected()
  202. ->getNode()
  203. ;
  204. $this->assertEquals(
  205. new Node\Param(new Expr\Variable('test'), null, null, false, false, [], Node\Stmt\Class_::MODIFIER_PROTECTED),
  206. $node
  207. );
  208. }
  209. public function testMakePrivate() {
  210. $node = $this->createParamBuilder('test')
  211. ->makePrivate()
  212. ->getNode()
  213. ;
  214. $this->assertEquals(
  215. new Node\Param(new Expr\Variable('test'), null, null, false, false, [], Node\Stmt\Class_::MODIFIER_PRIVATE),
  216. $node
  217. );
  218. }
  219. public function testMakeReadonly() {
  220. $node = $this->createParamBuilder('test')
  221. ->makeReadonly()
  222. ->getNode()
  223. ;
  224. $this->assertEquals(
  225. new Node\Param(new Expr\Variable('test'), null, null, false, false, [], Node\Stmt\Class_::MODIFIER_READONLY),
  226. $node
  227. );
  228. }
  229. public function testAddAttribute() {
  230. $attribute = new Attribute(
  231. new Name('Attr'),
  232. [new Arg(new LNumber(1), false, false, [], new Identifier('name'))]
  233. );
  234. $attributeGroup = new AttributeGroup([$attribute]);
  235. $node = $this->createParamBuilder('attributeGroup')
  236. ->addAttribute($attributeGroup)
  237. ->getNode();
  238. $this->assertEquals(
  239. new Node\Param(new Expr\Variable('attributeGroup'), null, null, false, false, [], 0, [$attributeGroup]),
  240. $node
  241. );
  242. }
  243. }