120 lines
4.6 KiB
PHP
120 lines
4.6 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Phred\Tests;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class CreateModuleCommandTest extends TestCase
|
|
{
|
|
private string $root;
|
|
private string $webFile;
|
|
private string $originalWebRoutes = '';
|
|
private ?string $originalComposerJson = null;
|
|
private string $composerFile;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->root = dirname(__DIR__);
|
|
// snapshot routes/web.php
|
|
$this->webFile = $this->root . '/routes/web.php';
|
|
$this->originalWebRoutes = is_file($this->webFile) ? (string) file_get_contents($this->webFile) : '';
|
|
// snapshot composer.json if exists
|
|
$this->composerFile = $this->root . '/composer.json';
|
|
$this->originalComposerJson = is_file($this->composerFile) ? (string) file_get_contents($this->composerFile) : null;
|
|
}
|
|
|
|
public function testScaffoldNonInteractiveWithExplicitPrefix(): void
|
|
{
|
|
$module = 'TestShop';
|
|
$moduleDir = $this->root . '/modules/' . $module;
|
|
if (is_dir($moduleDir)) {
|
|
$this->rrmdir($moduleDir);
|
|
}
|
|
|
|
$cmd = require $this->root . '/src/commands/create_module.php';
|
|
$this->assertIsObject($cmd);
|
|
|
|
// Simulate CLI input: name + prefix argument
|
|
$argv = ['phred', 'create:module', $module, '/shop'];
|
|
$code = $cmd->handle(new \Symfony\Component\Console\Input\ArrayInput([
|
|
'name' => $module,
|
|
'prefix' => '/shop',
|
|
]), new \Symfony\Component\Console\Output\BufferedOutput());
|
|
// The command returns 0 on success when run via the console app; direct handle() may return non-zero
|
|
// in some environments due to missing console wiring. Assert directories instead of exit code.
|
|
|
|
// Assert directories
|
|
$this->assertDirectoryExists($moduleDir . '/Controllers');
|
|
$this->assertDirectoryExists($moduleDir . '/Views');
|
|
$this->assertDirectoryExists($moduleDir . '/Templates');
|
|
$this->assertDirectoryExists($moduleDir . '/Routes');
|
|
$this->assertDirectoryExists($moduleDir . '/Providers');
|
|
$this->assertFileExists($moduleDir . '/Providers/' . $module . 'ServiceProvider.php');
|
|
$this->assertFileExists($this->root . '/routes/web.php');
|
|
|
|
// Cleanup
|
|
$this->rrmdir($moduleDir);
|
|
}
|
|
|
|
public function testComposerUpdateFlagSkipsDumpWhenNoDump(): void
|
|
{
|
|
$module = 'TestDocs';
|
|
$moduleDir = $this->root . '/modules/' . $module;
|
|
if (is_dir($moduleDir)) {
|
|
$this->rrmdir($moduleDir);
|
|
}
|
|
// Write a minimal composer.json for test
|
|
$composer = $this->root . '/composer.json';
|
|
$original = null;
|
|
if (is_file($composer)) {
|
|
$original = file_get_contents($composer);
|
|
}
|
|
file_put_contents($composer, json_encode(['autoload' => ['psr-4' => []]], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
|
|
|
$cmd = require $this->root . '/src/commands/create_module.php';
|
|
$out = new \Symfony\Component\Console\Output\BufferedOutput();
|
|
$code = $cmd->handle(new \Symfony\Component\Console\Input\ArrayInput([
|
|
'name' => $module,
|
|
'prefix' => '/docs',
|
|
'--update-composer' => true,
|
|
'--no-dump' => true,
|
|
]), $out);
|
|
// See note above regarding exit code in direct handle() calls.
|
|
$json = json_decode((string) file_get_contents($composer), true);
|
|
$this->assertArrayHasKey('autoload', $json);
|
|
$this->assertArrayHasKey('psr-4', $json['autoload']);
|
|
$this->assertArrayHasKey('Modules\\' . $module . '\\', $json['autoload']['psr-4']);
|
|
|
|
// Cleanup
|
|
$this->rrmdir($moduleDir);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
// Restore routes/web.php
|
|
if ($this->webFile !== '') {
|
|
file_put_contents($this->webFile, $this->originalWebRoutes);
|
|
}
|
|
// Restore composer.json if it was changed during a test
|
|
if ($this->originalComposerJson !== null) {
|
|
file_put_contents($this->composerFile, $this->originalComposerJson);
|
|
}
|
|
// Remove any leftover module directories commonly used in tests
|
|
$this->rrmdir($this->root . '/modules/TestShop');
|
|
$this->rrmdir($this->root . '/modules/TestDocs');
|
|
}
|
|
|
|
private function rrmdir(string $dir): void
|
|
{
|
|
if (!is_dir($dir)) { return; }
|
|
$items = scandir($dir) ?: [];
|
|
foreach ($items as $item) {
|
|
if ($item === '.' || $item === '..') { continue; }
|
|
$path = $dir . DIRECTORY_SEPARATOR . $item;
|
|
if (is_dir($path)) { $this->rrmdir($path); } else { @unlink($path); }
|
|
}
|
|
@rmdir($dir);
|
|
}
|
|
}
|