diff --git a/src/Tempest/Console/src/Commands/MakeMiddlewareCommand.php b/src/Tempest/Console/src/Commands/MakeMiddlewareCommand.php new file mode 100644 index 000000000..df5d57d5c --- /dev/null +++ b/src/Tempest/Console/src/Commands/MakeMiddlewareCommand.php @@ -0,0 +1,68 @@ +getStubFileFromMiddlewareType($middlewareType); + $suggestedPath = $this->getSuggestedPath($className); + $targetPath = $this->promptTargetPath($suggestedPath); + $shouldOverride = $this->askForOverride($targetPath); + + $this->stubFileGenerator->generateClassFile( + stubFile: $stubFile, + targetPath: $targetPath, + shouldOverride: $shouldOverride, + ); + + $this->success(sprintf('Middleware successfully created at "%s".', $targetPath)); + } catch (FileGenerationAbortedException|FileGenerationFailedException|InvalidArgumentException $e) { + $this->error($e->getMessage()); + } + } + + private function getStubFileFromMiddlewareType(MiddlewareType $middlewareType): StubFile + { + return match ($middlewareType) { + MiddlewareType::CONSOLE => StubFile::from(ConsoleMiddlewareStub::class), + MiddlewareType::HTTP => StubFile::from(HttpMiddlewareStub::class), + MiddlewareType::EVENT_BUS => StubFile::from(EventBusMiddlewareStub::class), + MiddlewareType::COMMAND_BUS => StubFile::from(CommandBusMiddlewareStub::class), // @phpstan-ignore match.alwaysTrue (Because this is a guardrail for the future implementations) + default => throw new InvalidArgumentException(sprintf('The "%s" middleware type has no supported stub file.', $middlewareType->value)), + }; + } +} diff --git a/src/Tempest/Console/src/Enums/MiddlewareType.php b/src/Tempest/Console/src/Enums/MiddlewareType.php new file mode 100644 index 000000000..d3ebc1e05 --- /dev/null +++ b/src/Tempest/Console/src/Enums/MiddlewareType.php @@ -0,0 +1,36 @@ + ConsoleMiddleware::class, + self::HTTP => HttpMiddleware::class, + self::EVENT_BUS => EventBusMiddleware::class, + self::COMMAND_BUS => CommandBusMiddleware::class, + }; + } +} diff --git a/src/Tempest/Console/src/Stubs/CommandBusMiddlewareStub.php b/src/Tempest/Console/src/Stubs/CommandBusMiddlewareStub.php new file mode 100644 index 000000000..fa672f114 --- /dev/null +++ b/src/Tempest/Console/src/Stubs/CommandBusMiddlewareStub.php @@ -0,0 +1,16 @@ +installer->configure( + __DIR__ . '/install', + new ComposerNamespace('App\\', __DIR__ . '/install/App'), + ); + } + + protected function tearDown(): void + { + $this->installer->clean(); + + parent::tearDown(); + } + + #[DataProvider('command_input_provider')] + #[Test] + public function make_command( + string $commandArgs, + string $expectedPath, + string $expectedNamespace, + ): void { + $this->console + ->call("make:middleware {$commandArgs}") + ->submit(); + + $this->installer + ->assertFileExists($expectedPath) + ->assertFileContains($expectedPath, 'namespace ' . $expectedNamespace . ';'); + } + + public static function command_input_provider(): array + { + return [ + 'make_with_defaults' => [ + 'commandArgs' => 'BookMiddleware http', + 'expectedPath' => 'App/BookMiddleware.php', + 'expectedNamespace' => 'App', + ], + 'make_with_other_namespace' => [ + 'commandArgs' => 'Middlewares\\BookMiddleware http', + 'expectedPath' => 'App/Middlewares/BookMiddleware.php', + 'expectedNamespace' => 'App\\Middlewares', + ], + 'make_with_input_path' => [ + 'commandArgs' => 'Middlewares/BookMiddleware http', + 'expectedPath' => 'App/Middlewares/BookMiddleware.php', + 'expectedNamespace' => 'App\\Middlewares', + ], + ]; + } + + #[DataProvider('middleware_type_provider')] + #[Test] + public function make_command_with_each_type( + MiddlewareType $middlewareType, + string $middlewareInterface, + ): void { + $this->console + ->call("make:middleware TestMiddleware {$middlewareType->value}") + ->submit(); + + $filepath = 'App/TestMiddleware.php'; + $middlewareInterface = str($middlewareInterface)->classBasename()->toString(); + $this->installer + ->assertFileExists($filepath) + ->assertFileContains($filepath, 'implements ' . $middlewareInterface); + } + + public static function middleware_type_provider(): array + { + $cases = MiddlewareType::cases(); + + return array_combine( + keys: array_map(fn (MiddlewareType $case) => $case->value, $cases), + values: array_map(fn (MiddlewareType $case) => [ + 'middlewareType' => $case, + 'middlewareInterface' => $case->relatedInterface(), + ], $cases), + ); + } +}