ClassTest.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php declare(strict_types=1);
  2. namespace PhpParser\Builder;
  3. use PhpParser\Comment;
  4. use PhpParser\Node;
  5. use PhpParser\Node\Arg;
  6. use PhpParser\Node\Attribute;
  7. use PhpParser\Node\AttributeGroup;
  8. use PhpParser\Node\Identifier;
  9. use PhpParser\Node\Name;
  10. use PhpParser\Node\Scalar\LNumber;
  11. use PhpParser\Node\Stmt;
  12. class ClassTest extends \PHPUnit\Framework\TestCase
  13. {
  14. protected function createClassBuilder($class) {
  15. return new Class_($class);
  16. }
  17. public function testExtendsImplements() {
  18. $node = $this->createClassBuilder('SomeLogger')
  19. ->extend('BaseLogger')
  20. ->implement('Namespaced\Logger', new Name('SomeInterface'))
  21. ->implement('\Fully\Qualified', 'namespace\NamespaceRelative')
  22. ->getNode()
  23. ;
  24. $this->assertEquals(
  25. new Stmt\Class_('SomeLogger', [
  26. 'extends' => new Name('BaseLogger'),
  27. 'implements' => [
  28. new Name('Namespaced\Logger'),
  29. new Name('SomeInterface'),
  30. new Name\FullyQualified('Fully\Qualified'),
  31. new Name\Relative('NamespaceRelative'),
  32. ],
  33. ]),
  34. $node
  35. );
  36. }
  37. public function testAbstract() {
  38. $node = $this->createClassBuilder('Test')
  39. ->makeAbstract()
  40. ->getNode()
  41. ;
  42. $this->assertEquals(
  43. new Stmt\Class_('Test', [
  44. 'flags' => Stmt\Class_::MODIFIER_ABSTRACT
  45. ]),
  46. $node
  47. );
  48. }
  49. public function testFinal() {
  50. $node = $this->createClassBuilder('Test')
  51. ->makeFinal()
  52. ->getNode()
  53. ;
  54. $this->assertEquals(
  55. new Stmt\Class_('Test', [
  56. 'flags' => Stmt\Class_::MODIFIER_FINAL
  57. ]),
  58. $node
  59. );
  60. }
  61. public function testReadonly() {
  62. $node = $this->createClassBuilder('Test')
  63. ->makeReadonly()
  64. ->getNode()
  65. ;
  66. $this->assertEquals(
  67. new Stmt\Class_('Test', [
  68. 'flags' => Stmt\Class_::MODIFIER_READONLY
  69. ]),
  70. $node
  71. );
  72. }
  73. public function testStatementOrder() {
  74. $method = new Stmt\ClassMethod('testMethod');
  75. $property = new Stmt\Property(
  76. Stmt\Class_::MODIFIER_PUBLIC,
  77. [new Stmt\PropertyProperty('testProperty')]
  78. );
  79. $const = new Stmt\ClassConst([
  80. new Node\Const_('TEST_CONST', new Node\Scalar\String_('ABC'))
  81. ]);
  82. $use = new Stmt\TraitUse([new Name('SomeTrait')]);
  83. $node = $this->createClassBuilder('Test')
  84. ->addStmt($method)
  85. ->addStmt($property)
  86. ->addStmts([$const, $use])
  87. ->getNode()
  88. ;
  89. $this->assertEquals(
  90. new Stmt\Class_('Test', [
  91. 'stmts' => [$use, $const, $property, $method]
  92. ]),
  93. $node
  94. );
  95. }
  96. public function testDocComment() {
  97. $docComment = <<<'DOC'
  98. /**
  99. * Test
  100. */
  101. DOC;
  102. $class = $this->createClassBuilder('Test')
  103. ->setDocComment($docComment)
  104. ->getNode();
  105. $this->assertEquals(
  106. new Stmt\Class_('Test', [], [
  107. 'comments' => [
  108. new Comment\Doc($docComment)
  109. ]
  110. ]),
  111. $class
  112. );
  113. $class = $this->createClassBuilder('Test')
  114. ->setDocComment(new Comment\Doc($docComment))
  115. ->getNode();
  116. $this->assertEquals(
  117. new Stmt\Class_('Test', [], [
  118. 'comments' => [
  119. new Comment\Doc($docComment)
  120. ]
  121. ]),
  122. $class
  123. );
  124. }
  125. public function testAddAttribute() {
  126. $attribute = new Attribute(
  127. new Name('Attr'),
  128. [new Arg(new LNumber(1), false, false, [], new Identifier('name'))]
  129. );
  130. $attributeGroup = new AttributeGroup([$attribute]);
  131. $class = $this->createClassBuilder('ATTR_GROUP')
  132. ->addAttribute($attributeGroup)
  133. ->getNode();
  134. $this->assertEquals(
  135. new Stmt\Class_('ATTR_GROUP', [
  136. 'attrGroups' => [
  137. $attributeGroup,
  138. ]
  139. ], []),
  140. $class
  141. );
  142. }
  143. public function testInvalidStmtError() {
  144. $this->expectException(\LogicException::class);
  145. $this->expectExceptionMessage('Unexpected node of type "Stmt_Echo"');
  146. $this->createClassBuilder('Test')
  147. ->addStmt(new Stmt\Echo_([]))
  148. ;
  149. }
  150. public function testInvalidDocComment() {
  151. $this->expectException(\LogicException::class);
  152. $this->expectExceptionMessage('Doc comment must be a string or an instance of PhpParser\Comment\Doc');
  153. $this->createClassBuilder('Test')
  154. ->setDocComment(new Comment('Test'));
  155. }
  156. public function testEmptyName() {
  157. $this->expectException(\LogicException::class);
  158. $this->expectExceptionMessage('Name cannot be empty');
  159. $this->createClassBuilder('Test')
  160. ->extend('');
  161. }
  162. public function testInvalidName() {
  163. $this->expectException(\LogicException::class);
  164. $this->expectExceptionMessage('Name must be a string or an instance of Node\Name');
  165. $this->createClassBuilder('Test')
  166. ->extend(['Foo']);
  167. }
  168. }