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
163 lines
6.3 KiB
<?php
|
|
|
|
|
|
namespace Prometeo\CommandsBundle\Commands;
|
|
|
|
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
|
|
use Symfony\Bundle\MakerBundle\ConsoleStyle;
|
|
use Symfony\Bundle\MakerBundle\DependencyBuilder;
|
|
use Symfony\Bundle\MakerBundle\Generator;
|
|
use Symfony\Bundle\MakerBundle\InputConfiguration;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Input\InputArgument;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Doctrine\Common\Annotations\AnnotationReader as Reader;
|
|
|
|
|
|
/**
|
|
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
|
* @author Ryan Weaver <weaverryan@gmail.com>
|
|
*/
|
|
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. <fg=yellow>UtilTest</>)')
|
|
->addArgument('classtype', InputArgument::OPTIONAL, 'Type of class to test (e.g. <fg=yellow>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 <fg=yellow>https://symfony.com/doc/current/testing.html#unit-tests</>',
|
|
]);
|
|
}
|
|
|
|
public function configureDependencies(DependencyBuilder $dependencies)
|
|
{
|
|
}
|
|
}
|