From fe3ea46f3f600032818c6029e8bd911fb2f8c4ae Mon Sep 17 00:00:00 2001 From: Mo Khosh Date: Fri, 9 Aug 2024 19:46:08 +0330 Subject: [PATCH 1/7] add toContainAsFile expectation --- tests/Pest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/Pest.php b/tests/Pest.php index 0a69b25..8f61220 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -16,6 +16,13 @@ |-------------------------------------------------------------------------- */ +expect()->extend('toContainAsFile', function ($needle) { + expect(file_get_contents($this->value)) + ->toContain($needle); + + return $this; +}); + /* |-------------------------------------------------------------------------- | Functions From bf24daeb366bab79d2f09cac05e3cbbefd7f21a3 Mon Sep 17 00:00:00 2001 From: Mo Khosh Date: Fri, 9 Aug 2024 19:46:38 +0330 Subject: [PATCH 2/7] load package service provider for tests --- tests/TestCase.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/TestCase.php b/tests/TestCase.php index 8447801..f2d37b2 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,6 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Orchestra\Testbench\TestCase as Orchestra; +use Spatie\ModelStates\ModelStatesServiceProvider; abstract class TestCase extends Orchestra { @@ -14,6 +15,13 @@ protected function setUp(): void $this->setUpDatabase(); } + protected function getPackageProviders($app) + { + return [ + ModelStatesServiceProvider::class, + ]; + } + protected function getEnvironmentSetUp($app) { $app['config']->set('database.default', 'sqlite'); From f6a945f2fe124b04cda70be0c55f4bd1726f7788 Mon Sep 17 00:00:00 2001 From: Mo Khosh Date: Fri, 9 Aug 2024 19:47:14 +0330 Subject: [PATCH 3/7] test it can generate abstract state classes --- tests/CommandsTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/CommandsTest.php diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php new file mode 100644 index 0000000..938bb97 --- /dev/null +++ b/tests/CommandsTest.php @@ -0,0 +1,11 @@ +app->basePath('app/Models/States'); + + $this->artisan('make:abstract-state AbstractState')->assertExitCode(0); + + expect($statesPath . '/AbstractState.php') + ->toBeFile() + ->toContainAsFile('class AbstractState extends State'); +}); From 6c816d3d95beb4dbeca1c3952e348388165423ec Mon Sep 17 00:00:00 2001 From: Mo Khosh Date: Fri, 9 Aug 2024 19:49:01 +0330 Subject: [PATCH 4/7] add make abstract state command --- src/Commands/MakeAbstractStateCommand.php | 24 +++++++++++++++++++++++ src/ModelStatesServiceProvider.php | 4 ++++ stubs/abstract-state.stub | 10 ++++++++++ 3 files changed, 38 insertions(+) create mode 100644 src/Commands/MakeAbstractStateCommand.php create mode 100644 stubs/abstract-state.stub diff --git a/src/Commands/MakeAbstractStateCommand.php b/src/Commands/MakeAbstractStateCommand.php new file mode 100644 index 0000000..32ea04c --- /dev/null +++ b/src/Commands/MakeAbstractStateCommand.php @@ -0,0 +1,24 @@ +name('laravel-model-states') + ->hasCommands([ + MakeAbstractStateCommand::class, + ]) ->hasConfigFile(); } } diff --git a/stubs/abstract-state.stub b/stubs/abstract-state.stub new file mode 100644 index 0000000..2c0ea4a --- /dev/null +++ b/stubs/abstract-state.stub @@ -0,0 +1,10 @@ + Date: Fri, 9 Aug 2024 19:58:57 +0330 Subject: [PATCH 5/7] add make state command --- src/Commands/MakeStateCommand.php | 58 ++++++++++++++++++++++++++++++ src/ModelStatesServiceProvider.php | 2 ++ stubs/state.stub | 8 +++++ tests/CommandsTest.php | 14 ++++++++ 4 files changed, 82 insertions(+) create mode 100644 src/Commands/MakeStateCommand.php create mode 100644 stubs/state.stub diff --git a/src/Commands/MakeStateCommand.php b/src/Commands/MakeStateCommand.php new file mode 100644 index 0000000..70fddc4 --- /dev/null +++ b/src/Commands/MakeStateCommand.php @@ -0,0 +1,58 @@ +type)], + ['parent', InputArgument::REQUIRED, 'The name of the parent abstract state'], + ]; + } + + protected function buildClass($name) + { + $stub = $this->files->get($this->getStub()); + $parent = $this->getParent(); + + return $this + ->replaceNamespace($stub, $name) + ->replaceParent($stub, $parent) + ->replaceClass($stub, $name); + } + + protected function replaceParent(&$stub, $name): self + { + $class = str_replace($this->getNamespace($name).'\\', '', $name); + + $stub = str_replace(['DummyParent', '{{ parent }}', '{{parent}}'], $class, $stub); + + return $this; + } + + protected function getParent(): string + { + return trim($this->argument('parent')); + } +} diff --git a/src/ModelStatesServiceProvider.php b/src/ModelStatesServiceProvider.php index 70d7114..a875d81 100644 --- a/src/ModelStatesServiceProvider.php +++ b/src/ModelStatesServiceProvider.php @@ -5,6 +5,7 @@ use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; use Spatie\ModelStates\Commands\MakeAbstractStateCommand; +use Spatie\ModelStates\Commands\MakeStateCommand; class ModelStatesServiceProvider extends PackageServiceProvider { @@ -14,6 +15,7 @@ public function configurePackage(Package $package): void ->name('laravel-model-states') ->hasCommands([ MakeAbstractStateCommand::class, + MakeStateCommand::class, ]) ->hasConfigFile(); } diff --git a/stubs/state.stub b/stubs/state.stub new file mode 100644 index 0000000..bc3b02d --- /dev/null +++ b/stubs/state.stub @@ -0,0 +1,8 @@ +toBeFile() ->toContainAsFile('class AbstractState extends State'); }); + +it('can generate states', function () { + $file = $this->app->basePath('app/Models/States') . '/State.php'; + + $this->artisan('make:state State') + ->expectsQuestion('What is the name of the parent abstract state?', 'AbstractState') + ->assertExitCode(0); + + expect($file) + ->toBeFile() + ->toContainAsFile('class State extends AbstractState'); + + unlink($file); +}); From 728205e09c8435d44818557ef06d482a421a2b77 Mon Sep 17 00:00:00 2001 From: Mo Khosh Date: Fri, 9 Aug 2024 19:59:13 +0330 Subject: [PATCH 6/7] cleanup after test --- tests/CommandsTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index 799e96c..a3abf94 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -1,13 +1,15 @@ app->basePath('app/Models/States'); + $file = $this->app->basePath('app/Models/States') . '/AbstractState.php'; $this->artisan('make:abstract-state AbstractState')->assertExitCode(0); - expect($statesPath . '/AbstractState.php') + expect($file) ->toBeFile() ->toContainAsFile('class AbstractState extends State'); + + unlink($file); }); it('can generate states', function () { From 5c242523ef8c5e68aed13b20f34e1cf91d4b06a5 Mon Sep 17 00:00:00 2001 From: Mo Khosh Date: Fri, 9 Aug 2024 20:02:06 +0330 Subject: [PATCH 7/7] add make transition command --- src/Commands/MakeTransitionCommand.php | 60 ++++++++++++++++++++++++++ src/ModelStatesServiceProvider.php | 2 + stubs/transition.stub | 28 ++++++++++++ tests/CommandsTest.php | 16 +++++++ 4 files changed, 106 insertions(+) create mode 100644 src/Commands/MakeTransitionCommand.php create mode 100644 stubs/transition.stub diff --git a/src/Commands/MakeTransitionCommand.php b/src/Commands/MakeTransitionCommand.php new file mode 100644 index 0000000..c200932 --- /dev/null +++ b/src/Commands/MakeTransitionCommand.php @@ -0,0 +1,60 @@ +type)], + ['parent', InputArgument::REQUIRED, 'The name of the model'], + ]; + } + + protected function buildClass($name) + { + $stub = $this->files->get($this->getStub()); + $parent = $this->getParent(); + + return $this + ->replaceNamespace($stub, $name) + ->replaceParent($stub, $parent) + ->replaceClass($stub, $name); + } + + protected function replaceParent(&$stub, $name): self + { + $class = str_replace($this->getNamespace($name).'\\', '', $name); + + $stub = str_replace(['DummyParent', '{{ parent }}', '{{parent}}'], $class, $stub); + $stub = str_replace('model', Str::camel($class), $stub); + + return $this; + } + + protected function getParent(): string + { + return trim($this->argument('parent')); + } +} diff --git a/src/ModelStatesServiceProvider.php b/src/ModelStatesServiceProvider.php index a875d81..4c0f934 100644 --- a/src/ModelStatesServiceProvider.php +++ b/src/ModelStatesServiceProvider.php @@ -6,6 +6,7 @@ use Spatie\LaravelPackageTools\PackageServiceProvider; use Spatie\ModelStates\Commands\MakeAbstractStateCommand; use Spatie\ModelStates\Commands\MakeStateCommand; +use Spatie\ModelStates\Commands\MakeTransitionCommand; class ModelStatesServiceProvider extends PackageServiceProvider { @@ -16,6 +17,7 @@ public function configurePackage(Package $package): void ->hasCommands([ MakeAbstractStateCommand::class, MakeStateCommand::class, + MakeTransitionCommand::class, ]) ->hasConfigFile(); } diff --git a/stubs/transition.stub b/stubs/transition.stub new file mode 100644 index 0000000..465802c --- /dev/null +++ b/stubs/transition.stub @@ -0,0 +1,28 @@ +model; + } + + public function canTransition(): bool + { + // + } +} diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index a3abf94..4565b52 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -25,3 +25,19 @@ unlink($file); }); + +it('can generate transitions', function () { + $file = $this->app->basePath('app/Models/States') . '/CustomTransition.php'; + + $this->artisan('make:transition CustomTransition') + ->expectsQuestion('What is the name of the model?', 'Model') + ->assertExitCode(0); + + expect($file) + ->toBeFile() + ->toContainAsFile('class CustomTransition extends Transition') + ->toContainAsFile('private readonly Model $model,') + ->toContainAsFile('return $this->model;'); + + unlink($file); +});