Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refine the controller make command. #80

Merged
merged 13 commits into from
Nov 23, 2024
51 changes: 20 additions & 31 deletions src/Commands/DomainControllerMakeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
use Lunarstorm\LaravelDDD\Commands\Concerns\ForwardsToDomainCommands;
use Lunarstorm\LaravelDDD\Commands\Concerns\HasDomainStubs;
use Lunarstorm\LaravelDDD\Commands\Concerns\ResolvesDomainFromInput;

use function Laravel\Prompts\confirm;
use Lunarstorm\LaravelDDD\Support\Path;

class DomainControllerMakeCommand extends ControllerMakeCommand
{
Expand All @@ -17,33 +16,6 @@ class DomainControllerMakeCommand extends ControllerMakeCommand

protected $name = 'ddd:controller';

protected function buildModelReplacements(array $replace)
{
$modelClass = $this->parseModel($this->option('model'));

if (
! app()->runningUnitTests()
&& ! class_exists($modelClass)
&& confirm("A {$modelClass} model does not exist. Do you want to generate it?", default: true)
) {
$this->call('make:model', ['name' => $modelClass]);
}

$replace = $this->buildFormRequestReplacements($replace, $modelClass);

return array_merge($replace, [
'DummyFullModelClass' => $modelClass,
'{{ namespacedModel }}' => $modelClass,
'{{namespacedModel}}' => $modelClass,
'DummyModelClass' => class_basename($modelClass),
'{{ model }}' => class_basename($modelClass),
'{{model}}' => class_basename($modelClass),
'DummyModelVariable' => lcfirst(class_basename($modelClass)),
'{{ modelVariable }}' => lcfirst(class_basename($modelClass)),
'{{modelVariable}}' => lcfirst(class_basename($modelClass)),
]);
}

protected function buildFormRequestReplacements(array $replace, $modelClass)
{
[$namespace, $storeRequestClass, $updateRequestClass] = [
Expand Down Expand Up @@ -90,16 +62,33 @@ protected function buildClass($name)
return $stub;
}

// Handle Laravel 10 side effect
if (str($stub)->contains($invalidUse = "use {$this->getNamespace($name)}\Http\Controllers\Controller;\n")) {
$laravel10Replacements = [
' extends Controller' => '',
$invalidUse => '',
];

$stub = str_replace(
array_keys($laravel10Replacements),
array_values($laravel10Replacements),
$stub
);
}

$replace = [];

$appRootNamespace = $this->laravel->getNamespace();
$pathToAppBaseController = parent::getPath("Http\Controllers\Controller");
$pathToAppBaseController = Path::normalize(app()->path('Http/Controllers/Controller.php'));

$baseControllerExists = $this->files->exists($pathToAppBaseController);

if ($baseControllerExists) {
$controllerClass = class_basename($name);
$replace["\nclass {$controllerClass}\n"] = "\nuse {$appRootNamespace}Http\Controllers\Controller;\n\nclass {$controllerClass} extends Controller\n";
$fullyQualifiedBaseController = "{$appRootNamespace}Http\Controllers\Controller";
$namespaceLine = "namespace {$this->getNamespace($name)};";
$replace["{$namespaceLine}\n"] = "{$namespaceLine}\n\nuse {$fullyQualifiedBaseController};";
$replace["class {$controllerClass}\n"] = "class {$controllerClass} extends Controller\n";
}

$stub = str_replace(
Expand Down
58 changes: 37 additions & 21 deletions tests/Generator/ControllerMakeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\File;
use Lunarstorm\LaravelDDD\Support\Path;
use Lunarstorm\LaravelDDD\Tests\Fixtures\Enums\Feature;

beforeEach(function () {
Expand Down Expand Up @@ -35,16 +36,14 @@
);

expect(file_exists($expectedPath))->toBeTrue();
expect(file_exists(app_path('Http/Controllers/Controller.php')))->toBeTrue();

expect($contents = file_get_contents($expectedPath))
->toContain("namespace {$expectedNamespace};");
$contents = file_get_contents($expectedPath);

if (Feature::Laravel11->exists()) {
// These assertions don't seem to pass on Laravel 10
expect($contents)
->toContain("use App\Http\Controllers\Controller;")
->toContain('extends Controller');
}
expect($contents)
->toContain("namespace {$expectedNamespace};")
->toContain("use App\Http\Controllers\Controller;\nuse Illuminate\Http\Request;")
->toContain('extends Controller');
})->with([
'Invoicing:InvoiceController' => [
'Invoicing',
Expand All @@ -70,12 +69,20 @@

expect(file_exists($expectedPath))->toBeFalse();

Artisan::call('ddd:controller', [
$modelExists = class_exists($modelClass);

$command = $this->artisan('ddd:controller', [
'name' => $controllerName,
'--domain' => $domainName,
'--model' => $modelName,
]);

if (! $modelExists) {
$command->expectsQuestion("A {$modelClass} model does not exist. Do you want to generate it?", false);
}

$command->assertSuccessful()->execute();

expect(file_exists($expectedPath))->toBeTrue();

$modelVariable = lcfirst(class_basename($modelClass));
Expand Down Expand Up @@ -123,20 +130,28 @@
}
}

Artisan::call('ddd:controller', [
$modelExists = class_exists($modelClass);

$command = $this->artisan('ddd:controller', [
'name' => $controllerName,
'--domain' => $domainName,
'--model' => $modelName,
'--requests' => true,
]);

$output = Artisan::output();
if (! $modelExists) {
$command->expectsQuestion("A {$modelClass} model does not exist. Do you want to generate it?", false);
}

foreach ($generatedPaths as $path) {
if (Feature::IncludeFilepathInGeneratorCommandOutput->exists()) {
expect($output)->toContainFilepath($path);
$command->expectsOutputToContain(Path::normalize($path));
}
}

$command->assertSuccessful()->execute();

foreach ($generatedPaths as $path) {
expect(file_exists(base_path($path)))->toBeTrue("Expecting {$path} to exist");
}

Expand Down Expand Up @@ -194,27 +209,26 @@
expect(file_exists($expectedPath))->toBeFalse();

// Remove the base controller
$baseControllerPath = base_path('app/Http/Controllers/Controller.php');
$baseControllerPath = app_path('Http/Controllers/Controller.php');

if (file_exists($baseControllerPath)) {
unlink($baseControllerPath);
}

expect(file_exists($baseControllerPath))->toBeFalse();

Artisan::call("ddd:controller {$domainName}:{$controllerName}");
$this->artisan("ddd:controller {$domainName}:{$controllerName}")
->assertSuccessful()
->execute();

expect(file_exists($expectedPath))->toBeTrue();

expect($contents = file_get_contents($expectedPath))
->toContain("namespace {$expectedNamespace};");

if (Feature::Laravel11->exists()) {
// These assertions don't seem to pass on Laravel 10
expect($contents)
->not->toContain("use App\Http\Controllers\Controller;")
->not->toContain('extends Controller');
}
expect($contents)
->not->toContain("use App\Http\Controllers\Controller;")
->not->toContain('extends Controller');
})->with([
'Invoicing:InvoiceController' => [
'Invoicing',
Expand Down Expand Up @@ -253,7 +267,9 @@ class {{ class }}
file_put_contents(app()->basePath($stubFolder.'/controller.plain.stub'), $customStub);
expect(file_exists(app()->basePath($stubFolder.'/controller.plain.stub')))->toBeTrue();

Artisan::call("ddd:controller {$domainName}:{$controllerName}");
$this->artisan("ddd:controller {$domainName}:{$controllerName}")
->assertSuccessful()
->execute();

expect(file_exists($expectedPath))->toBeTrue();

Expand Down
3 changes: 3 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ protected function setupTestApplication()
File::copyDirectory($folder, app_path(basename($folder)));
}

File::ensureDirectoryExists(app_path('Http/Controllers'));
File::copy(__DIR__.'/.skeleton/app/Http/Controllers/Controller.php', app_path('Http/Controllers/Controller.php'));

File::copyDirectory(__DIR__.'/.skeleton/database', base_path('database'));
File::copyDirectory(__DIR__.'/.skeleton/src', base_path('src'));
File::copy(__DIR__.'/.skeleton/bootstrap/providers.php', base_path('bootstrap/providers.php'));
Expand Down