Skip to content

Commit 661d82b

Browse files
Refactor template commands and add unit tests
Refactored command utilities to improve accessibility and added public helper methods for table and info displays. Updated and added unit tests for `UseTemplateCommand` and `NewTemplateCommand` to ensure template generation and command execution functionality work as expected.
1 parent ea8a6cd commit 661d82b

File tree

5 files changed

+116
-9
lines changed

5 files changed

+116
-9
lines changed

src/Concerns/CommandsUtils.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@
1111
use Symfony\Component\Process\Process;
1212
use function Illuminate\Support\php_binary;
1313
use function Laravel\Prompts\error;
14+
use function Laravel\Prompts\info;
15+
use function Laravel\Prompts\table;
1416

1517
trait CommandsUtils
1618
{
1719

18-
private function getGlobalTemplatesPath(): string
20+
public string $display = '';
21+
22+
protected function getGlobalTemplatesPath(): string
1923
{
2024
// Determine OS-specific config directory
2125
if (windows_os()) {
@@ -27,7 +31,7 @@ private function getGlobalTemplatesPath(): string
2731
return $configDir . '\templates.json';
2832
}
2933

30-
private function getSavedTemplates(bool $noInteract = false): array
34+
protected function getSavedTemplates(bool $noInteract = false): array
3135
{
3236
// Get the global templates path
3337
$configPath = $this->getGlobalTemplatesPath();
@@ -159,4 +163,21 @@ protected function verifyApplicationDoesntExist(string $directory): void
159163
throw new RuntimeException('Application already exists!');
160164
}
161165
}
166+
167+
public function table(array $headers, array $rows): void
168+
{
169+
table($headers, $rows);
170+
$this->display .= json_encode([$headers, $rows]);
171+
}
172+
173+
public function info(string $message): void
174+
{
175+
info($message);
176+
$this->display .= $message;
177+
}
178+
179+
public function getDisplay(): string
180+
{
181+
return $this->display;
182+
}
162183
}

src/NewCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1202,7 +1202,7 @@ private function createTemplateCommand(InputInterface $input): string
12021202
return implode(' ', $commandParts);
12031203
}
12041204

1205-
private function saveTemplateCommand(mixed $templateName, mixed $templateDescription, string $templateCommand): void
1205+
protected function saveTemplateCommand(mixed $templateName, mixed $templateDescription, string $templateCommand): void
12061206
{
12071207
// Get the global config path for storing templates
12081208
$configPath = $this->getGlobalTemplatesPath();

src/ShowTemplatesCommand.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55
use Symfony\Component\Console\Command\Command;
66
use Symfony\Component\Console\Input\InputArgument;
77
use Symfony\Component\Console\Input\InputInterface;
8-
use Symfony\Component\Console\Input\InputOption;
98
use Symfony\Component\Console\Output\OutputInterface;
109

11-
use function Laravel\Prompts\info;
1210
use function Laravel\Prompts\intro;
13-
use function Laravel\Prompts\table;
1411
use function Laravel\Prompts\error;
1512

1613
class ShowTemplatesCommand extends Command
@@ -50,20 +47,20 @@ private function showTemplates(InputInterface $input): void
5047
}
5148

5249
// Display the template
53-
table(
50+
$this->table(
5451
['Template Name', 'Description', 'Command'],
5552
[$this->formatTemplates($template, $templates[$template])]
5653
);
5754
}
5855
else {
5956
// Format and display templates using Laravel Prompts table
60-
table(
57+
$this->table(
6158
['Template Name', 'Description', 'Command'],
6259
array_map(fn($name, $template) => $this->formatTemplates($name, $template), array_keys($templates), $templates)
6360
);
6461
}
6562

66-
info('Use a template by calling <fg=cyan>`laravelfs use <template-name> <project-name>`<'.'/'.'>');
63+
$this->info('Use a template by calling <fg=cyan>`laravelfs use <template-name> <project-name>`<'.'/'.'>');
6764
}
6865

6966
private function formatTemplates($name, $data): array
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace HichemTabTech\LaravelFS\Console\Tests\Unit;
4+
5+
use HichemTabTech\LaravelFS\Console\NewTemplateCommand;
6+
use Symfony\Component\Console\Tester\CommandTester;
7+
8+
beforeEach(function () {
9+
// Create a dummy NewTemplateCommand that overrides saveTemplateCommand() to capture the saved template.
10+
$this->command = new class extends NewTemplateCommand {
11+
public array|null $savedTemplate = null;
12+
public function saveTemplateCommand($templateName, $templateDescription, $templateCommand): void {
13+
$this->savedTemplate = [
14+
'name' => $templateName,
15+
'description' => $templateDescription,
16+
'command' => $templateCommand,
17+
];
18+
}
19+
};
20+
21+
$this->commandTester = new CommandTester($this->command);
22+
});
23+
24+
test('new:template command generates and saves a template', function () {
25+
// Provide arguments: template-name and template-description, plus any options if needed.
26+
$input = [
27+
'template-name' => 'test-template',
28+
'template-description' => 'A test template',
29+
// Simulate minimal required options (others will be empty/false)
30+
'--dev' => false,
31+
'--git' => false,
32+
];
33+
$exitCode = $this->commandTester->execute($input);
34+
expect($exitCode)->toBe(0)
35+
->and($this->command->savedTemplate)->toBeArray()
36+
->and($this->command->savedTemplate['name'])->toEqual('test-template')
37+
->and($this->command->savedTemplate['description'])->toEqual('A test template')
38+
->and($this->command->savedTemplate['command'])->toContain('laravelfs new');
39+
// Ensure the generated command starts with "laravelfs new"
40+
});
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace HichemTabTech\LaravelFS\Console\Tests\Unit;
4+
5+
use HichemTabTech\LaravelFS\Console\UseTemplateCommand;
6+
use Symfony\Component\Console\Input\InputInterface;
7+
use Symfony\Component\Console\Output\OutputInterface;
8+
use Symfony\Component\Console\Tester\CommandTester;
9+
use Symfony\Component\Process\Process;
10+
11+
beforeEach(function () {
12+
// Create a dummy UseTemplateCommand that overrides getSavedTemplates() and runCommands() for testing.
13+
$this->command = new class extends UseTemplateCommand {
14+
public bool $runCommandsCalled = false;
15+
public string|null $lastCommand = null;
16+
17+
protected function getSavedTemplates(bool $noInteract = false): array {
18+
return [
19+
'templates' => [
20+
'template1' => [
21+
'description' => 'A test template',
22+
'command' => 'laravelfs new <project-name> --react'
23+
]
24+
],
25+
'path' => '/fake/path'
26+
];
27+
}
28+
29+
protected function runCommands(array $commands, InputInterface $input, OutputInterface $output, ?string $workingPath = null, array $env = []): Process {
30+
$this->runCommandsCalled = true;
31+
$this->lastCommand = $commands[0];
32+
return new Process([]);
33+
}
34+
};
35+
36+
$this->commandTester = new CommandTester($this->command);
37+
});
38+
39+
test('use command executes template command with replaced project name', function () {
40+
$input = [
41+
'template-name' => 'template1',
42+
'project-name' => 'my-project',
43+
];
44+
$exitCode = $this->commandTester->execute($input);
45+
expect($exitCode)->toBe(0)
46+
->and($this->command->runCommandsCalled)->toBeTrue()
47+
->and($this->command->lastCommand)->toContain('my-project');
48+
// Check that the template command has replaced "<project-name>" with "my-project"
49+
});

0 commit comments

Comments
 (0)