Licitator 1.0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
6.3 KiB

5 years ago
  1. <?php
  2. namespace Prometeo\CommandsBundle\Commands;
  3. use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
  4. use Symfony\Bundle\MakerBundle\ConsoleStyle;
  5. use Symfony\Bundle\MakerBundle\DependencyBuilder;
  6. use Symfony\Bundle\MakerBundle\Generator;
  7. use Symfony\Bundle\MakerBundle\InputConfiguration;
  8. use Symfony\Component\Console\Command\Command;
  9. use Symfony\Component\Console\Input\InputArgument;
  10. use Symfony\Component\Console\Input\InputInterface;
  11. use Doctrine\Common\Annotations\AnnotationReader as Reader;
  12. /**
  13. * @author Javier Eguiluz <javier.eguiluz@gmail.com>
  14. * @author Ryan Weaver <weaverryan@gmail.com>
  15. */
  16. final class MakeUnitTest extends AbstractMaker
  17. {
  18. public static function getCommandName(): string
  19. {
  20. return 'prometeo:make:unit-test';
  21. }
  22. public function configureCommand(Command $command, InputConfiguration $inputConf)
  23. {
  24. $command
  25. ->setDescription('Creates a new unit test class')
  26. ->addArgument('name', InputArgument::OPTIONAL, 'The name of the unit test class (e.g. <fg=yellow>UtilTest</>)')
  27. ->addArgument('classtype', InputArgument::OPTIONAL, 'Type of class to test (e.g. <fg=yellow>Entity</>)')
  28. ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeUnitTest.txt'))
  29. ;
  30. }
  31. private function getPropertyNames(string $class): array
  32. {
  33. if (!class_exists($class)) {
  34. return [];
  35. }
  36. $reflClass = new \ReflectionClass($class);
  37. return array_map(function (\ReflectionProperty $prop) {
  38. return $prop->getName();
  39. }, $reflClass->getProperties());
  40. }
  41. private function getTypeProperties(string $class): array
  42. {
  43. if (!class_exists($class)) {
  44. return [];
  45. }
  46. $reader = new Reader();
  47. $reflClass = new \ReflectionClass($class);
  48. $properties= array_map(function (\ReflectionProperty $prop) {
  49. return $prop->getName();
  50. }, $reflClass->getProperties());
  51. $types=[];
  52. $classes=[];
  53. $classesArray=[];
  54. foreach($properties as $property) {
  55. if($type=$reader->getPropertyAnnotation(
  56. $reflClass->getProperty($property),
  57. 'Doctrine\ORM\Mapping\Column'
  58. )) {
  59. $types[$property] = $type->type;
  60. }
  61. if($type=$reader->getPropertyAnnotation(
  62. $reflClass->getProperty($property),
  63. 'Doctrine\ORM\Mapping\OneToMany'
  64. )) {
  65. $classesArray[$property]=$type->targetEntity;
  66. $types[$property] = $type->targetEntity;
  67. }
  68. if($type=$reader->getPropertyAnnotation(
  69. $reflClass->getProperty($property),
  70. 'Doctrine\ORM\Mapping\ManyToOne'
  71. )) {
  72. $classes[$property]=$type->targetEntity;
  73. $types[$property] = $type->targetEntity;
  74. }
  75. if($type=$reader->getPropertyAnnotation(
  76. $reflClass->getProperty($property),
  77. 'Doctrine\ORM\Mapping\ManyToMany'
  78. )) {
  79. $classesArray[$property]=$type->targetEntity;
  80. $types[$property] = $type->targetEntity;
  81. }
  82. }
  83. return ['tipos'=>$types,'clases'=>$classes, 'clasesArray'=>$classesArray];
  84. }
  85. public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator)
  86. {
  87. $originClass=$input->getArgument('name');
  88. $properties=$this->getPropertyNames('App\\'.$originClass);
  89. $tipos=$this->getTypeProperties('App\\'.$originClass)['tipos'];
  90. $clases=$this->getTypeProperties('App\\'.$originClass)['clases'];
  91. $clasesArray=$this->getTypeProperties('App\\'.$originClass)['clasesArray'];
  92. $dependantClasses=[];
  93. foreach($clases as $class){
  94. $dependantClasses[$class]['tipos']=$this->getTypeProperties($class)['tipos'];
  95. $dependantClasses[$class]['clases']=$this->getTypeProperties($class)['clases'];
  96. $dependantClasses[$class]['clasesArray']=$this->getTypeProperties($class)['clasesArray'];
  97. $dependantClasses[$class]['properties']=$this->getPropertyNames($class);
  98. }
  99. foreach($clasesArray as $class){
  100. $dependantClasses[$class]['tipos']=$this->getTypeProperties($class)['tipos'];
  101. $dependantClasses[$class]['clases']=$this->getTypeProperties($class)['clases'];
  102. $dependantClasses[$class]['clasesArray']=$this->getTypeProperties($class)['clasesArray'];
  103. $dependantClasses[$class]['properties']=$this->getPropertyNames($class);
  104. }
  105. $testClassNameDetails = $generator->createClassNameDetails(
  106. $input->getArgument('name'),
  107. 'Tests\\',
  108. 'Test'
  109. );
  110. if($input->getArgument('classtype')){
  111. switch ($input->getArgument('classtype')){
  112. case 'Entity':
  113. $endclass=explode('\\',$originClass);
  114. $originClass=end($endclass);
  115. $generator->generateClass(
  116. $testClassNameDetails->getFullName(),
  117. __DIR__.'/../Resources/skeleton/test/UnitEntity.tpl.php',
  118. [ 'dependantClasses'=>$dependantClasses,
  119. 'classesArray'=>$clasesArray,
  120. 'classes'=>$clases,
  121. 'types'=>$tipos,
  122. 'properties'=>$properties,
  123. 'originClass'=>$originClass]
  124. );break;
  125. case 'Command':
  126. $generator->generateClass(
  127. $testClassNameDetails->getFullName(),
  128. __DIR__.'/../Resources/skeleton/test/UnitCommand.tpl.php',
  129. []
  130. );break;
  131. }
  132. }else{
  133. $generator->generateClass(
  134. $testClassNameDetails->getFullName(),
  135. __DIR__.'/../Resources/skeleton/test/Unit.tpl.php',
  136. []
  137. );
  138. }
  139. $generator->writeChanges();
  140. $this->writeSuccessMessage($io);
  141. $io->text([
  142. 'Next: Open your new test class and start customizing it.',
  143. 'Find the documentation at <fg=yellow>https://symfony.com/doc/current/testing.html#unit-tests</>',
  144. ]);
  145. }
  146. public function configureDependencies(DependencyBuilder $dependencies)
  147. {
  148. }
  149. }