Skip to content

Commit

Permalink
feat(console): add make:view command (#864)
Browse files Browse the repository at this point in the history
Co-authored-by: Enzo Innocenzi <[email protected]>
  • Loading branch information
gturpin-dev and innocenzi authored Jan 9, 2025
1 parent 08df98c commit a4ab813
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 0 deletions.
86 changes: 86 additions & 0 deletions src/Tempest/View/src/Commands/MakeViewCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

declare(strict_types=1);

namespace Tempest\View\Commands;

use InvalidArgumentException;
use Tempest\Console\ConsoleArgument;
use Tempest\Console\ConsoleCommand;
use Tempest\Core\PublishesFiles;
use Tempest\Generation\DataObjects\StubFile;
use Tempest\Generation\Enums\StubFileType;
use Tempest\Generation\Exceptions\FileGenerationAbortedException;
use Tempest\Generation\Exceptions\FileGenerationFailedException;
use Tempest\View\Enums\ViewType;
use Tempest\View\Stubs\ViewStub;
use function Tempest\Support\str;

final class MakeViewCommand
{
use PublishesFiles;

#[ConsoleCommand(
name: 'make:view',
description: 'Creates a view file',
aliases: ['view:make', 'view:create', 'create:view'],
)]
public function __invoke(
#[ConsoleArgument(
description: 'The file name of the view',
)]
string $fileName,
#[ConsoleArgument(
name: 'type',
description: 'The type of the view to create',
)]
ViewType $viewType = ViewType::RAW,
): void {
try {
$suggestedPath = str($this->getSuggestedPath('Dummy'));
$suggestedPath = ($viewType === ViewType::RAW)
? $suggestedPath->replace('Dummy', $fileName . '.view')
: $suggestedPath->replace('Dummy', $fileName);

$suggestedPath = $suggestedPath->toString();
$targetPath = $this->promptTargetPath($suggestedPath);
$shouldOverride = $this->askForOverride($targetPath);

$stubFile = $this->getStubFileFromViewType($viewType);

if ($stubFile->type === StubFileType::RAW_FILE) {
$this->stubFileGenerator->generateRawFile(
stubFile: $stubFile,
targetPath: $targetPath,
shouldOverride: $shouldOverride,
);
} else {
$this->stubFileGenerator->generateClassFile(
stubFile: $stubFile,
targetPath: $targetPath,
shouldOverride: $shouldOverride,
replacements: [
'dummy.view.php' => str($fileName)->kebab()->toString() . '.view.php',
],
);
}

$this->success(sprintf('View successfully created at "%s".', $targetPath));
} catch (FileGenerationAbortedException|FileGenerationFailedException|InvalidArgumentException $e) {
$this->error($e->getMessage());
}
}

private function getStubFileFromViewType(ViewType $viewType): StubFile
{
try {
return match ($viewType) {
ViewType::RAW => StubFile::from(dirname(__DIR__) . '/Stubs/view.stub.php'),
ViewType::OBJECT => StubFile::from(ViewStub::class), // @phpstan-ignore match.alwaysTrue (Because this is a guardrail for the future implementations)
default => throw new InvalidArgumentException(sprintf('The "%s" view type has no supported stub file.', $viewType->value)),
};
} catch (InvalidArgumentException $invalidArgumentException) {
throw new FileGenerationFailedException(sprintf('Cannot retrieve stub file: %s', $invalidArgumentException->getMessage()));
}
}
}
15 changes: 15 additions & 0 deletions src/Tempest/View/src/Enums/ViewType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Tempest\View\Enums;

/**
* Represents the type of view.
* Used to differentiate between raw and class views.
*/
enum ViewType: string
{
case RAW = 'raw';
case OBJECT = 'class';
}
18 changes: 18 additions & 0 deletions src/Tempest/View/src/Stubs/ViewStub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Tempest\View\Stubs;

use Tempest\View\IsView;
use Tempest\View\View;

final class ViewStub implements View
{
use IsView;

public function __construct()
{
$this->path = __DIR__ . '/dummy.view.php';
}
}
Empty file.
54 changes: 54 additions & 0 deletions tests/Integration/View/Commands/MakeViewCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Tests\Tempest\Integration\Console\Commands;

use PHPUnit\Framework\Attributes\Test;
use Tempest\Core\ComposerNamespace;
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;

/**
* @internal
*/
final class MakeViewCommandTest extends FrameworkIntegrationTestCase
{
protected function setUp(): void
{
parent::setUp();

$this->installer->configure(
__DIR__ . '/install',
new ComposerNamespace('App\\', __DIR__ . '/install/App'),
);
}

protected function tearDown(): void
{
$this->installer->clean();

parent::tearDown();
}

#[Test]
public function make_view(): void
{
$this->console
->call('make:view home')
->submit();

$this->installer->assertFileExists('App/home.view.php');

$this->console
->call('make:view HomeView class')
->submit();

$filepath = 'App/HomeView.php';
$this->installer
->assertFileExists($filepath)
->assertFileContains($filepath, 'implements View')
->assertFileContains($filepath, "use Tempest\View\View")
->assertFileContains($filepath, 'use IsView')
->assertFileContains($filepath, "use Tempest\View\IsView");
}
}

0 comments on commit a4ab813

Please sign in to comment.