* @author Ryan Weaver */ final class MakeUnitTest extends AbstractMaker { public static function getCommandName(): string { return 'prometeo:make:unit-test'; } public function configureCommand(Command $command, InputConfiguration $inputConf) { $command ->setDescription('Creates a new unit test class') ->addArgument('name', InputArgument::OPTIONAL, 'The name of the unit test class (e.g. UtilTest)') ->addArgument('classtype', InputArgument::OPTIONAL, 'Type of class to test (e.g. Entity)') ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeUnitTest.txt')) ; } private function getPropertyNames(string $class): array { if (!class_exists($class)) { return []; } $reflClass = new \ReflectionClass($class); return array_map(function (\ReflectionProperty $prop) { return $prop->getName(); }, $reflClass->getProperties()); } private function getTypeProperties(string $class): array { if (!class_exists($class)) { return []; } $reader = new Reader(); $reflClass = new \ReflectionClass($class); $properties= array_map(function (\ReflectionProperty $prop) { return $prop->getName(); }, $reflClass->getProperties()); $types=[]; $classes=[]; $classesArray=[]; foreach($properties as $property) { if($type=$reader->getPropertyAnnotation( $reflClass->getProperty($property), 'Doctrine\ORM\Mapping\Column' )) { $types[$property] = $type->type; } if($type=$reader->getPropertyAnnotation( $reflClass->getProperty($property), 'Doctrine\ORM\Mapping\OneToMany' )) { $classesArray[$property]=$type->targetEntity; $types[$property] = $type->targetEntity; } if($type=$reader->getPropertyAnnotation( $reflClass->getProperty($property), 'Doctrine\ORM\Mapping\ManyToOne' )) { $classes[$property]=$type->targetEntity; $types[$property] = $type->targetEntity; } if($type=$reader->getPropertyAnnotation( $reflClass->getProperty($property), 'Doctrine\ORM\Mapping\ManyToMany' )) { $classesArray[$property]=$type->targetEntity; $types[$property] = $type->targetEntity; } } return ['tipos'=>$types,'clases'=>$classes, 'clasesArray'=>$classesArray]; } public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) { $originClass=$input->getArgument('name'); $properties=$this->getPropertyNames('App\\'.$originClass); $tipos=$this->getTypeProperties('App\\'.$originClass)['tipos']; $clases=$this->getTypeProperties('App\\'.$originClass)['clases']; $clasesArray=$this->getTypeProperties('App\\'.$originClass)['clasesArray']; $dependantClasses=[]; foreach($clases as $class){ $dependantClasses[$class]['tipos']=$this->getTypeProperties($class)['tipos']; $dependantClasses[$class]['clases']=$this->getTypeProperties($class)['clases']; $dependantClasses[$class]['clasesArray']=$this->getTypeProperties($class)['clasesArray']; $dependantClasses[$class]['properties']=$this->getPropertyNames($class); } foreach($clasesArray as $class){ $dependantClasses[$class]['tipos']=$this->getTypeProperties($class)['tipos']; $dependantClasses[$class]['clases']=$this->getTypeProperties($class)['clases']; $dependantClasses[$class]['clasesArray']=$this->getTypeProperties($class)['clasesArray']; $dependantClasses[$class]['properties']=$this->getPropertyNames($class); } $testClassNameDetails = $generator->createClassNameDetails( $input->getArgument('name'), 'Tests\\', 'Test' ); if($input->getArgument('classtype')){ switch ($input->getArgument('classtype')){ case 'Entity': $endclass=explode('\\',$originClass); $originClass=end($endclass); $generator->generateClass( $testClassNameDetails->getFullName(), __DIR__.'/../Resources/skeleton/test/UnitEntity.tpl.php', [ 'dependantClasses'=>$dependantClasses, 'classesArray'=>$clasesArray, 'classes'=>$clases, 'types'=>$tipos, 'properties'=>$properties, 'originClass'=>$originClass] );break; case 'Command': $generator->generateClass( $testClassNameDetails->getFullName(), __DIR__.'/../Resources/skeleton/test/UnitCommand.tpl.php', [] );break; } }else{ $generator->generateClass( $testClassNameDetails->getFullName(), __DIR__.'/../Resources/skeleton/test/Unit.tpl.php', [] ); } $generator->writeChanges(); $this->writeSuccessMessage($io); $io->text([ 'Next: Open your new test class and start customizing it.', 'Find the documentation at https://symfony.com/doc/current/testing.html#unit-tests', ]); } public function configureDependencies(DependencyBuilder $dependencies) { } }