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.
 
 
 
 

140 lines
4.1 KiB

<?php
namespace App\Console\Commands;
use Database\Factories\BaseFactory;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class TestGenerator extends Command
{
const MODELS_NAMESPACE = 'App\\Models\\';
const BASE_FACTORY_TRAIT = 'Database\Factories\BaseFactory';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'generate:test {models?}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate test for requested model name';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return void
* @throws \Throwable
*/
public function handle()
{
$models = $this->getSelectedModels();
// if (!is_dir('tests/Feature/' . ucfirst($model))) {
// mkdir('tests/Feature/' . ucfirst($model), 0777, true);
// } else {
// $confirm = $this->confirm("$model tests before created, are you sure delete them and regenerate test?", true);
// if ($confirm) {
// system("rm -rf " . escapeshellarg('tests/Feature/' . ucfirst($model)));
// mkdir('tests/Feature/' . ucfirst($model), 0777, true);
// }
// }
foreach ($models as $model) {
$className = str_replace(self::MODELS_NAMESPACE, '', $model);
foreach (['store', 'update', 'show', 'delete'] as $test_name) {
$options = (new $model())->factory()->testGeneratorConfig()[$test_name] ?? null;
if ($options === null) {
continue;
}
//todo:need work
file_put_contents(
'tests/Feature/' . ucfirst($className) . '/' . ucfirst($className) . ucfirst($test_name) . 'Test.php',
view(
'tests.' . $test_name,
[
'model' => new $model(),
'sol' => "<?php",
'profile' => null,
'auth' => null,
])->render()
);
$this->info("Generate " . ucfirst($className) . ucfirst($test_name) . 'Test.php successfully!');
}
}
$this->info("\nGo enjoy it :) Powered with ❤️ from Haj Mehdi And Masoud Productions (registered trademark).");
}
/**
* @return \Illuminate\Support\Collection
* @throws \Throwable
*/
private function getSelectedModels()
{
$models = $this->argument('models');
$models = empty($models) ?
$this->getAllModels() :
collect(explode(',', $models));
return $models->map(fn($m) => self::MODELS_NAMESPACE . $m)->each(function ($model) {
$className = str_replace(self::MODELS_NAMESPACE, '', $model);
throw_if(!class_exists($model), $model . ' Not exists!');
throw_if(!$this->passRequirements(new $model), $className . 'Factory must have list, testGeneratorConfig and dependencyProvider functions');
throw_if(!$this->hasBaseFactoryTrait(new $model), $className . 'Factory use BaseFactory trait.');
})->toArray();
}
private function getAllModels()
{
$models = [];
$path = app_path('Models');
$files = File::files($path);
foreach ($files as $file) {
$models [] = str_replace('.php', '', $file->getFileName());
}
return collect($models);
}
public function passRequirements($model)
{
return
method_exists($model->factory(), 'list') &&
method_exists($model->factory(), 'testGeneratorConfig') &&
method_exists($model->factory(), 'dependencyProvider');
}
/**
* @param $model
* @return false
* @throws \ReflectionException
*/
public function hasBaseFactoryTrait($model)
{
return in_array(
BaseFactory::class,
array_keys((new \ReflectionClass(($model)->factory()))->getTraits())
);
}
}