Skip to content

Commit

Permalink
Merge pull request #22 from CodeWithDennis/improve-file-check
Browse files Browse the repository at this point in the history
refactor: Improve handling of generating resource tests
  • Loading branch information
CodeWithDennis authored Mar 16, 2024
2 parents 4902c7f + bf7f176 commit eb37dd6
Showing 1 changed file with 73 additions and 71 deletions.
144 changes: 73 additions & 71 deletions src/Commands/FilamentResourceTestsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Collection;

use function Laravel\Prompts\confirm;
use function Laravel\Prompts\multiselect;

class FilamentResourceTestsCommand extends Command
Expand All @@ -27,48 +28,52 @@ public function __construct(Filesystem $files)
$this->files = $files;
}

protected function getStubPath(): string
public function handle(): int
{
return __DIR__.'/../../stubs/Resource.stub';
}
$availableResources = $this->getResources()
->map(fn ($resource): string => str($resource)->afterLast('Resources\\'));

protected function convertDoubleQuotedArrayString(string $string): array|string
{
return str_replace('"', '\'', str_replace(',', ', ', $string));
}
$selectedResources = multiselect(
label: 'What is the resource you would like to create this test for?',
options: $availableResources->flatten(),
required: true,
);

protected function getStubVariables(Resource $resource): array
{
$model = $resource->getModel();
$columns = collect($this->getResourceTable($resource)->getColumns());
foreach ($selectedResources as $selectedResource) {
$resource = $this->getResourceClass($selectedResource);

return [
'resource' => str($resource::class)->afterLast('\\'),
'model' => $model,
'modelSingularName' => str($model)->afterLast('\\'),
'modelPluralName' => str($model)->afterLast('\\')->plural(),
'resourceTableColumns' => $this->convertDoubleQuotedArrayString($columns->keys()),
'resourceTableColumnsWithoutHidden' => $this->convertDoubleQuotedArrayString($columns->filter(fn ($column) => ! $column->isToggledHiddenByDefault())->keys()),
'resourceTableToggleableColumns' => $this->convertDoubleQuotedArrayString($columns->filter(fn ($column) => $column->isToggleable())->keys()),
'resourceTableSortableColumns' => $this->convertDoubleQuotedArrayString($columns->filter(fn ($column) => $column->isSortable())->keys()),
'resourceTableSearchableColumns' => $this->convertDoubleQuotedArrayString($columns->filter(fn ($column) => $column->isSearchable())->keys()),
];
$path = $this->getSourceFilePath($selectedResource);

$this->makeDirectory(dirname($path));

$contents = $this->getSourceFile($resource);

if ($this->files->exists($path)) {
// If the file already exists, ask the user if they want to overwrite it.
if (! confirm("Test for {$selectedResource} already exists. Do you want to overwrite it?")) {
continue;
}
}

$this->files->put($path, $contents);

$this->info("Test for {$selectedResource} created successfully.");
}

return self::SUCCESS;
}

protected function getSourceFile(Resource $resource): array|bool|string
protected function getResources(): Collection
{
return $this->getStubContents($this->getStubPath(), $this->getStubVariables($resource));
return collect(Filament::getResources());
}

protected function getStubContents(string $stub, array $stubVariables = []): array|bool|string
protected function getResourceClass(string $resource): ?Resource
{
$contents = file_get_contents($stub);

foreach ($stubVariables as $search => $replace) {
$contents = str_replace('$'.$search.'$', $replace, $contents);
}
$match = $this->getResources()
->first(fn ($value): bool => str_contains($value, $resource) && class_exists($value));

return $contents;
return $match ? app()->make($match) : null;
}

protected function getSourceFilePath(string $name): string
Expand All @@ -91,17 +96,43 @@ protected function makeDirectory($path): string
return $path;
}

protected function getResourceClass(string $resource): ?Resource
protected function getSourceFile(Resource $resource): array|bool|string
{
$match = $this->getResources()
->first(fn ($value): bool => str_contains($value, $resource) && class_exists($value));
return $this->getStubContents($this->getStubPath(), $this->getStubVariables($resource));
}

return $match ? app()->make($match) : null;
protected function getStubContents(string $stub, array $stubVariables = []): array|bool|string
{
$contents = file_get_contents($stub);

foreach ($stubVariables as $search => $replace) {
$contents = str_replace('$'.$search.'$', $replace, $contents);
}

return $contents;
}

protected function getResources(): Collection
protected function getStubPath(): string
{
return collect(Filament::getResources());
return __DIR__.'/../../stubs/Resource.stub';
}

protected function getStubVariables(Resource $resource): array
{
$model = $resource->getModel();
$columns = collect($this->getResourceTable($resource)->getColumns());

return [
'resource' => str($resource::class)->afterLast('\\'),
'model' => $model,
'modelSingularName' => str($model)->afterLast('\\'),
'modelPluralName' => str($model)->afterLast('\\')->plural(),
'resourceTableColumns' => $this->convertDoubleQuotedArrayString($columns->keys()),
'resourceTableColumnsWithoutHidden' => $this->convertDoubleQuotedArrayString($columns->filter(fn ($column) => ! $column->isToggledHiddenByDefault())->keys()),
'resourceTableToggleableColumns' => $this->convertDoubleQuotedArrayString($columns->filter(fn ($column) => $column->isToggleable())->keys()),
'resourceTableSortableColumns' => $this->convertDoubleQuotedArrayString($columns->filter(fn ($column) => $column->isSortable())->keys()),
'resourceTableSearchableColumns' => $this->convertDoubleQuotedArrayString($columns->filter(fn ($column) => $column->isSearchable())->keys()),
];
}

protected function getResourceTable(Resource $resource): Table
Expand All @@ -111,6 +142,11 @@ protected function getResourceTable(Resource $resource): Table
return $resource::table(new Table($livewire));
}

protected function convertDoubleQuotedArrayString(string $string): array|string
{
return str_replace('"', '\'', str_replace(',', ', ', $string));
}

protected function getResourceTableColumns(Table $table): array
{
return $table->getColumns();
Expand All @@ -130,38 +166,4 @@ protected function getResourceTableFilters(Table $table): array
{
return $table->getFilters();
}

public function handle(): int
{
$availableResources = $this->getResources()
->map(fn ($resource): string => str($resource)->afterLast('Resources\\'));

$selectedResources = multiselect(
label: 'What is the resource you would like to create this test for?',
options: $availableResources->flatten(),
required: true,
);

foreach ($selectedResources as $selectedResource) {
$resource = $this->getResourceClass($selectedResource);

$path = $this->getSourceFilePath($selectedResource);

$this->makeDirectory(dirname($path));

$contents = $this->getSourceFile($resource);

if ($this->files->exists($path)) {
$this->warn("Test for {$selectedResource} already exists.");

break;
}

$this->files->put($path, $contents);

$this->info("Test for {$selectedResource} created successfully.");
}

return self::SUCCESS;
}
}

0 comments on commit eb37dd6

Please sign in to comment.