From 7c87e567e78a6744dafdc0d8cb20c2bc284dccf3 Mon Sep 17 00:00:00 2001 From: Andrea Marco Sartori <22cerbero22@gmail.com> Date: Tue, 26 Jul 2016 21:04:39 -0400 Subject: [PATCH] Applied fixes from StyleCI --- .../Workflow/Console/Drawing/DrawerSpec.php | 53 +- .../Workflow/Inflectors/InflectorSpec.php | 34 +- .../YamlPipelineRepositorySpec.php | 59 +- spec/Cerbero/Workflow/WorkflowSpec.php | 87 +- src/Console/Commands/AttachesPipesTrait.php | 194 +-- .../Commands/CreateWorkflowCommand.php | 245 +-- src/Console/Commands/DeleteIfForcedTrait.php | 44 +- .../Commands/DeleteWorkflowCommand.php | 142 +- src/Console/Commands/ReadWorkflowCommand.php | 135 +- .../Commands/UpdateWorkflowCommand.php | 186 ++- .../Commands/WorkflowGeneratorCommand.php | 131 +- src/Console/Drawing/Drawer.php | 582 +++---- src/Console/Drawing/Geometry.php | 640 +++---- src/Facades/Workflow.php | 26 +- src/Inflectors/Inflector.php | 151 +- src/Inflectors/InflectorInterface.php | 57 +- src/Pipes/AbstractPipe.php | 159 +- src/Pipes/PipeInterface.php | 31 +- .../PipelineRepositoryInterface.php | 135 +- src/Repositories/YamlPipelineRepository.php | 455 ++--- src/RunsWorkflow.php | 44 +- src/Workflow.php | 252 +-- src/WorkflowRunner.php | 27 +- src/WorkflowServiceProvider.php | 348 ++-- src/Wrappers/DispatcherInterface.php | 12 +- .../LaravelTraitNamespaceDetector.php | 34 +- src/Wrappers/MarshalDispatcher.php | 122 +- src/Wrappers/NamespaceDetectorInterface.php | 24 +- src/Wrappers/SymfonyYamlParser.php | 57 +- src/Wrappers/YamlParserInterface.php | 45 +- tests/_bootstrap.php | 1 + tests/_support/AcceptanceHelper.php | 2 +- tests/_support/AcceptanceTester.php | 7 +- tests/_support/FunctionalHelper.php | 582 ++++--- tests/_support/FunctionalTester.php | 7 +- tests/_support/UnitHelper.php | 2 +- tests/_support/UnitTester.php | 7 +- .../_generated/AcceptanceTesterActions.php | 635 ++++--- .../_generated/FunctionalTesterActions.php | 1467 +++++++++++------ .../_support/_generated/UnitTesterActions.php | 123 +- tests/acceptance/AcceptanceTester.php | 528 +++--- tests/acceptance/_bootstrap.php | 1 + ...dCreatedWorkflowIfAnotherOneExistsCept.php | 5 +- .../CreateUnguardedWorkflowCept.php | 5 +- .../CreateWorkflowWithManyPipesCept.php | 5 +- .../CreateWorkflowWithNoPipesCept.php | 5 +- ...eDetachedPipesDuringUpdateIfForcedCept.php | 5 +- .../DeleteWorkflowAndItsFilesCept.php | 5 +- .../DeleteWorkflowButSpareFilesCept.php | 5 +- ...isplayErrorIfWorkflowAlreadyExistsCept.php | 5 +- ...ErrorIfWorkflowNotExistsDuringReadCept.php | 5 +- ...rorIfWorkflowNotExistsDuringUpdateCept.php | 5 +- tests/functional/FunctionalTester.php | 1212 +++++++++----- .../ReadWorkflowWithManyPipesCept.php | 5 +- .../ReadWorkflowWithNoPipesCept.php | 5 +- .../ReadWorkflowWithOnePipeCept.php | 5 +- .../functional/UpdateExistingWorkflowCept.php | 5 +- tests/functional/_bootstrap.php | 1 + tests/unit/UnitTester.php | 94 +- tests/unit/_bootstrap.php | 1 + 60 files changed, 5285 insertions(+), 3966 deletions(-) diff --git a/spec/Cerbero/Workflow/Console/Drawing/DrawerSpec.php b/spec/Cerbero/Workflow/Console/Drawing/DrawerSpec.php index 0f4c7a3..a072a90 100644 --- a/spec/Cerbero/Workflow/Console/Drawing/DrawerSpec.php +++ b/spec/Cerbero/Workflow/Console/Drawing/DrawerSpec.php @@ -2,21 +2,20 @@ namespace spec\Cerbero\Workflow\Console\Drawing; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; -use Cerbero\Workflow\Repositories\PipelineRepositoryInterface; use Cerbero\Workflow\Console\Drawing\Geometry; +use Cerbero\Workflow\Repositories\PipelineRepositoryInterface; +use PhpSpec\ObjectBehavior; class DrawerSpec extends ObjectBehavior { - function let(PipelineRepositoryInterface $pipelines) - { - $geometry = new Geometry; + public function let(PipelineRepositoryInterface $pipelines) + { + $geometry = new Geometry(); - $this->beConstructedWith($pipelines, $geometry); - } + $this->beConstructedWith($pipelines, $geometry); + } - function it_is_initializable() + public function it_is_initializable() { $this->shouldHaveType('Cerbero\Workflow\Console\Drawing\Drawer'); } @@ -25,59 +24,63 @@ function it_is_initializable() * @testdox It draws a workflow with zero pipes. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_draws_a_workflow_with_zero_pipes($pipelines) { - $pipelines->getPipesByPipeline('RegisterUser')->willReturn([]); + $pipelines->getPipesByPipeline('RegisterUser')->willReturn([]); - $drawing = file_get_contents(__DIR__ . '/stubs/zero.stub'); + $drawing = file_get_contents(__DIR__.'/stubs/zero.stub'); - $this->draw('RegisterUser')->shouldReturn($drawing); + $this->draw('RegisterUser')->shouldReturn($drawing); } /** * @testdox It draws a workflow with one pipe. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_draws_a_workflow_with_one_pipe($pipelines) { - $pipelines->getPipesByPipeline('RegisterUser')->willReturn(['App\Workflows\RegisterUser\Notifier']); + $pipelines->getPipesByPipeline('RegisterUser')->willReturn(['App\Workflows\RegisterUser\Notifier']); - $drawing = file_get_contents(__DIR__ . '/stubs/one.stub'); + $drawing = file_get_contents(__DIR__.'/stubs/one.stub'); - $this->draw('RegisterUser')->shouldReturn($drawing); + $this->draw('RegisterUser')->shouldReturn($drawing); } /** * @testdox It draws a workflow with two pipe. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_draws_a_workflow_with_two_pipe($pipelines) { - $pipelines->getPipesByPipeline('RegisterUser')->willReturn(['App\Workflows\RegisterUser\Logger', 'App\Workflows\RegisterUser\Notifier']); + $pipelines->getPipesByPipeline('RegisterUser')->willReturn(['App\Workflows\RegisterUser\Logger', 'App\Workflows\RegisterUser\Notifier']); - $drawing = file_get_contents(__DIR__ . '/stubs/two.stub'); + $drawing = file_get_contents(__DIR__.'/stubs/two.stub'); - $this->draw('RegisterUser')->shouldReturn($drawing); + $this->draw('RegisterUser')->shouldReturn($drawing); } /** * @testdox It draws a workflow with many pipes. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_draws_a_workflow_with_many_pipes($pipelines) { - $pipelines->getPipesByPipeline('LoginUser')->willReturn(['LongName', 'TheLongestNameEver', 'LongerName', 'Name', 'VeryLongName']); + $pipelines->getPipesByPipeline('LoginUser')->willReturn(['LongName', 'TheLongestNameEver', 'LongerName', 'Name', 'VeryLongName']); - $drawing = file_get_contents(__DIR__ . '/stubs/many.stub'); + $drawing = file_get_contents(__DIR__.'/stubs/many.stub'); - $this->draw('LoginUser')->shouldReturn($drawing); + $this->draw('LoginUser')->shouldReturn($drawing); } } diff --git a/spec/Cerbero/Workflow/Inflectors/InflectorSpec.php b/spec/Cerbero/Workflow/Inflectors/InflectorSpec.php index 41662aa..5dcfb78 100644 --- a/spec/Cerbero/Workflow/Inflectors/InflectorSpec.php +++ b/spec/Cerbero/Workflow/Inflectors/InflectorSpec.php @@ -2,20 +2,19 @@ namespace spec\Cerbero\Workflow\Inflectors; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; use Cerbero\Workflow\Wrappers\NamespaceDetectorInterface; +use PhpSpec\ObjectBehavior; class InflectorSpec extends ObjectBehavior { - function let(NamespaceDetectorInterface $detector) - { - $this->beConstructedWith($detector); + public function let(NamespaceDetectorInterface $detector) + { + $this->beConstructedWith($detector); - $detector->detect()->willReturn('App'); - } + $detector->detect()->willReturn('App'); + } - function it_is_initializable() + public function it_is_initializable() { $this->shouldHaveType('Cerbero\Workflow\Inflectors\Inflector'); $this->shouldHaveType('Cerbero\Workflow\Inflectors\InflectorInterface'); @@ -25,36 +24,39 @@ function it_is_initializable() * @testdox It returns itself after setting the word to inflect. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_returns_itself_after_setting_the_word_to_inflect() { - $this->of('foo')->shouldReturn($this); + $this->of('foo')->shouldReturn($this); } /** * @testdox It inflects the request. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_inflects_the_request() { - $expected = 'App\Http\Requests\RegisterUserRequest'; + $expected = 'App\Http\Requests\RegisterUserRequest'; - $this->of('registerUser')->getRequest()->shouldReturn($expected); + $this->of('registerUser')->getRequest()->shouldReturn($expected); } /** * @testdox It inflects the job. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_inflects_the_job() { - $expected = 'App\Jobs\RegisterUserJob'; + $expected = 'App\Jobs\RegisterUserJob'; - $this->of('registerUser')->getJob()->shouldReturn($expected); + $this->of('registerUser')->getJob()->shouldReturn($expected); } } diff --git a/spec/Cerbero/Workflow/Repositories/YamlPipelineRepositorySpec.php b/spec/Cerbero/Workflow/Repositories/YamlPipelineRepositorySpec.php index 9480e81..afe1c8d 100644 --- a/spec/Cerbero/Workflow/Repositories/YamlPipelineRepositorySpec.php +++ b/spec/Cerbero/Workflow/Repositories/YamlPipelineRepositorySpec.php @@ -2,28 +2,27 @@ namespace spec\Cerbero\Workflow\Repositories; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; use Cerbero\Workflow\Wrappers\YamlParserInterface; use Illuminate\Filesystem\Filesystem; +use PhpSpec\ObjectBehavior; class YamlPipelineRepositorySpec extends ObjectBehavior { - /** * @author Andrea Marco Sartori - * @var array $pipeline Example of pipeline. + * + * @var array Example of pipeline. */ - private $pipeline = array('RegisterUser' => ['Notifier', 'Logger']); + private $pipeline = ['RegisterUser' => ['Notifier', 'Logger']]; - function let(YamlParserInterface $parser, Filesystem $files) - { - $this->beConstructedWith($parser, $files, 'path/to/workflows'); + public function let(YamlParserInterface $parser, Filesystem $files) + { + $this->beConstructedWith($parser, $files, 'path/to/workflows'); - $parser->parse('path/to/workflows/workflows.yml')->shouldBeCalled()->willReturn($this->pipeline); - } + $parser->parse('path/to/workflows/workflows.yml')->shouldBeCalled()->willReturn($this->pipeline); + } - function it_is_initializable() + public function it_is_initializable() { $this->shouldHaveType('Cerbero\Workflow\Repositories\YamlPipelineRepository'); $this->shouldHaveType('Cerbero\Workflow\Repositories\PipelineRepositoryInterface'); @@ -33,42 +32,46 @@ function it_is_initializable() * @testdox It returns false when a pipeline does not exist. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_returns_false_when_a_pipeline_does_not_exist() { - $this->exists('unknownPipeline')->shouldReturn(false); + $this->exists('unknownPipeline')->shouldReturn(false); } /** * @testdox It returns true when a pipeline exists. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_returns_true_when_a_pipeline_exists() { - $this->exists('RegisterUser')->shouldReturn(true); + $this->exists('RegisterUser')->shouldReturn(true); } /** * @testdox It returns the pipeline of a fiven workflow. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_returns_the_pipeline_of_a_fiven_workflow() { - $expected = ['Notifier', 'Logger']; + $expected = ['Notifier', 'Logger']; - $this->getPipesByPipeline('registerUser')->shouldReturn($expected); + $this->getPipesByPipeline('registerUser')->shouldReturn($expected); } /** * @testdox It retrieves the source of the pipelines. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_retrieves_the_source_of_the_pipelines() { @@ -79,7 +82,8 @@ public function it_retrieves_the_source_of_the_pipelines() * @testdox It creates the YAML file. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_creates_the_YAML_file($files) { @@ -94,7 +98,8 @@ public function it_creates_the_YAML_file($files) * @testdox It stores the given pipeline and its pipes. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_stores_the_given_pipeline_and_its_pipes($parser, $files) { @@ -109,7 +114,8 @@ public function it_stores_the_given_pipeline_and_its_pipes($parser, $files) * @testdox It updates an existing pipeline by attaching and detaching pipes. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_updates_an_existing_pipeline_by_attaching_and_detaching_pipes($parser, $files) { @@ -126,7 +132,8 @@ public function it_updates_an_existing_pipeline_by_attaching_and_detaching_pipes * @testdox It does not attach if no attachments are specified. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_does_not_attach_if_no_attachments_are_specified($parser, $files) { @@ -143,7 +150,8 @@ public function it_does_not_attach_if_no_attachments_are_specified($parser, $fil * @testdox It does not detach if no detachments are specified. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_does_not_detach_if_no_detachments_are_specified($parser, $files) { @@ -160,7 +168,8 @@ public function it_does_not_detach_if_no_detachments_are_specified($parser, $fil * @testdox It destroys a pipeline. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_destroys_a_pipeline($parser, $files) { diff --git a/spec/Cerbero/Workflow/WorkflowSpec.php b/spec/Cerbero/Workflow/WorkflowSpec.php index fb065c4..5be11f8 100644 --- a/spec/Cerbero/Workflow/WorkflowSpec.php +++ b/spec/Cerbero/Workflow/WorkflowSpec.php @@ -2,24 +2,23 @@ namespace spec\Cerbero\Workflow; -use PhpSpec\ObjectBehavior; -use Prophecy\Argument; -use Cerbero\Workflow\Repositories\PipelineRepositoryInterface; +use ArrayAccess; use Cerbero\Workflow\Inflectors\InflectorInterface; -use Illuminate\Contracts\Container\Container; +use Cerbero\Workflow\Repositories\PipelineRepositoryInterface; use Cerbero\Workflow\Wrappers\DispatcherInterface; -use ArrayAccess; - -class WorkflowSpec extends ObjectBehavior { +use Illuminate\Contracts\Container\Container; +use PhpSpec\ObjectBehavior; - public function let( - PipelineRepositoryInterface $pipelines, +class WorkflowSpec extends ObjectBehavior +{ + public function let( + PipelineRepositoryInterface $pipelines, InflectorInterface $inflector, Container $container, - DispatcherInterface $dispatcher - ) { - $this->beConstructedWith($pipelines, $inflector, $container, $dispatcher); - } + DispatcherInterface $dispatcher + ) { + $this->beConstructedWith($pipelines, $inflector, $container, $dispatcher); + } public function it_is_initializable() { @@ -30,30 +29,32 @@ public function it_is_initializable() * @testdox It throws an exception if a workflow does not exist. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_throws_an_exception_if_a_workflow_does_not_exist($pipelines) { - $pipelines->exists('unknownWorkflow')->shouldBeCalled()->willReturn(false); + $pipelines->exists('unknownWorkflow')->shouldBeCalled()->willReturn(false); - $this->shouldThrow('BadFunctionCallException')->duringUnknownWorkflow(); + $this->shouldThrow('BadFunctionCallException')->duringUnknownWorkflow(); } /** * @testdox It resolves the proper request if existing. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_resolves_the_proper_request_if_existing($pipelines, $container, Router $router, $inflector, $dispatcher, ExistingRequest $request) { - $pipelines->exists('registerUser')->willReturn(true); + $pipelines->exists('registerUser')->willReturn(true); - $inflector->of('registerUser')->shouldBeCalled(); + $inflector->of('registerUser')->shouldBeCalled(); - $inflector->getRequest()->willReturn('spec\Cerbero\Workflow\ExistingRequest'); + $inflector->getRequest()->willReturn('spec\Cerbero\Workflow\ExistingRequest'); - $container->make('spec\Cerbero\Workflow\ExistingRequest')->shouldBeCalled()->willReturn($request); + $container->make('spec\Cerbero\Workflow\ExistingRequest')->shouldBeCalled()->willReturn($request); $container->make('router')->willReturn($router); @@ -61,32 +62,33 @@ public function it_resolves_the_proper_request_if_existing($pipelines, $containe $router->parameters()->willReturn(['foo' => 'bar']); - $inflector->getJob()->willReturn('job'); + $inflector->getJob()->willReturn('job'); - $pipelines->getPipesByPipeline('registerUser')->willReturn(['pipe']); + $pipelines->getPipesByPipeline('registerUser')->willReturn(['pipe']); - $dispatcher->pipeThrough(['pipe'])->willReturn($dispatcher); + $dispatcher->pipeThrough(['pipe'])->willReturn($dispatcher); - $dispatcher->dispatchFrom('job', $request, ['foo' => 'bar'])->shouldBeCalled(); + $dispatcher->dispatchFrom('job', $request, ['foo' => 'bar'])->shouldBeCalled(); - $this->registerUser(); + $this->registerUser(); } /** * @testdox It dispatches a job through a pipeline from a default request. * * @author Andrea Marco Sartori - * @return void + * + * @return void */ public function it_dispatches_a_job_through_a_pipeline_from_a_default_request($pipelines, $container, Router $router, $inflector, $dispatcher, ArrayAccess $request) { - $pipelines->exists('registerUser')->willReturn(true); + $pipelines->exists('registerUser')->willReturn(true); - $inflector->of('registerUser')->shouldBeCalled(); + $inflector->of('registerUser')->shouldBeCalled(); - $inflector->getRequest()->willReturn('NotExistingRequest'); + $inflector->getRequest()->willReturn('NotExistingRequest'); - $container->make('Illuminate\Http\Request')->shouldBeCalled()->willReturn($request); + $container->make('Illuminate\Http\Request')->shouldBeCalled()->willReturn($request); $container->make('router')->willReturn($router); @@ -94,23 +96,26 @@ public function it_dispatches_a_job_through_a_pipeline_from_a_default_request($p $router->parameters()->willReturn(['foo' => 'bar']); - $inflector->getJob()->willReturn('job'); + $inflector->getJob()->willReturn('job'); - $pipelines->getPipesByPipeline('registerUser')->willReturn(['pipe']); + $pipelines->getPipesByPipeline('registerUser')->willReturn(['pipe']); - $dispatcher->pipeThrough(['pipe'])->willReturn($dispatcher); + $dispatcher->pipeThrough(['pipe'])->willReturn($dispatcher); - $dispatcher->dispatchFrom('job', $request, ['foo' => 'bar'])->shouldBeCalled(); + $dispatcher->dispatchFrom('job', $request, ['foo' => 'bar'])->shouldBeCalled(); - $this->registerUser('foo', 'bar'); + $this->registerUser('foo', 'bar'); } - } -abstract class ExistingRequest implements ArrayAccess {} +abstract class ExistingRequest implements ArrayAccess +{ +} + +interface Router +{ + public function current(); -interface Router { - function current(); - function parameters(); + public function parameters(); } diff --git a/src/Console/Commands/AttachesPipesTrait.php b/src/Console/Commands/AttachesPipesTrait.php index 029629e..dada8fa 100644 --- a/src/Console/Commands/AttachesPipesTrait.php +++ b/src/Console/Commands/AttachesPipesTrait.php @@ -1,100 +1,108 @@ -getPipesByOption('attach') as $pipe) - { - $this->currentPipe = $pipe; - - parent::fire(); - } - } - - /** - * Retrieve a list of pipes. - * - * @author Andrea Marco Sartori - * @param string $option - * @return array - */ - protected function getPipesByOption($option) - { - $pipes = $this->option($option); - - preg_match_all('/\w+/', $pipes, $matches); - - return array_map('ucfirst', $matches[0]); - } - - /** - * Get the default namespace for the class. - * - * @param string $rootNamespace - * @return string - */ - protected function getDefaultNamespace($rootNamespace) - { - $workflows = $this->getWorkflowsNamespace(); - - $pipeline = $this->getWorkflowName(); - - return "{$rootNamespace}\\{$workflows}\\{$pipeline}"; - } - - /** - * Retrieve the namespace of the workflows. - * - * @author Andrea Marco Sartori - * @return string - */ - protected function getWorkflowsNamespace() - { - $relative = ltrim(config('workflow.path'), app_path()); - - $chunks = array_map('ucfirst', explode('/', $relative)); - - return implode('\\', $chunks); - } - - /** - * Retrieve a list of pipes with their namespaces. - * - * @author Andrea Marco Sartori - * @param string $option - * @return array - */ - protected function getNamespacedPipesByOption($option) - { - return array_map([$this, 'parseName'], $this->getPipesByOption($option)); - } - - /** - * Get the desired class name from the input. - * - * @return string - */ - protected function getNameInput() - { - return $this->currentPipe; - } - +trait AttachesPipesTrait +{ + /** + * @author Andrea Marco Sartori + * + * @var string $currentPipe Pipe to generate. + */ + protected $currentPipe; + + /** + * Generate the specified pipes. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function generatePipes() + { + foreach ($this->getPipesByOption('attach') as $pipe) { + $this->currentPipe = $pipe; + + parent::fire(); + } + } + + /** + * Retrieve a list of pipes. + * + * @author Andrea Marco Sartori + * + * @param string $option + * + * @return array + */ + protected function getPipesByOption($option) + { + $pipes = $this->option($option); + + preg_match_all('/\w+/', $pipes, $matches); + + return array_map('ucfirst', $matches[0]); + } + + /** + * Get the default namespace for the class. + * + * @param string $rootNamespace + * + * @return string + */ + protected function getDefaultNamespace($rootNamespace) + { + $workflows = $this->getWorkflowsNamespace(); + + $pipeline = $this->getWorkflowName(); + + return "{$rootNamespace}\\{$workflows}\\{$pipeline}"; + } + + /** + * Retrieve the namespace of the workflows. + * + * @author Andrea Marco Sartori + * + * @return string + */ + protected function getWorkflowsNamespace() + { + $relative = ltrim(config('workflow.path'), app_path()); + + $chunks = array_map('ucfirst', explode('/', $relative)); + + return implode('\\', $chunks); + } + + /** + * Retrieve a list of pipes with their namespaces. + * + * @author Andrea Marco Sartori + * + * @param string $option + * + * @return array + */ + protected function getNamespacedPipesByOption($option) + { + return array_map([$this, 'parseName'], $this->getPipesByOption($option)); + } + + /** + * Get the desired class name from the input. + * + * @return string + */ + protected function getNameInput() + { + return $this->currentPipe; + } } diff --git a/src/Console/Commands/CreateWorkflowCommand.php b/src/Console/Commands/CreateWorkflowCommand.php index 6317895..40b2997 100644 --- a/src/Console/Commands/CreateWorkflowCommand.php +++ b/src/Console/Commands/CreateWorkflowCommand.php @@ -1,125 +1,128 @@ -inflector->of($name = $this->getWorkflowName()); - - if($this->pipelines->exists($name)) - { - return $this->error("The workflow [$name] already exists."); - } - - $this->generateAllNeededFiles(); - - $this->pipelines->store($name, $this->getNamespacedPipesByOption('attach')); - - $this->info('Workflow created successfully.'); - } - - /** - * Generate all the needed files. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function generateAllNeededFiles() - { - $this->settleRepositoryIfNotExists(); - - $this->generateJob(); - - $this->generateRequestIfGuarded(); - - $this->generatePipes(); - } - - /** - * Settle the pipeline repository if it does not exist. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function settleRepositoryIfNotExists() - { - $source = $this->pipelines->getSource(); - - if( ! $this->files->exists($source)) - { - $this->pipelines->settle(); - } - } - - /** - * Create the job to handle. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function generateJob() - { - $name = $this->inflector->getJob(); - - $this->call('make:job', compact('name')); - } - - /** - * Create the request if unguard is not set. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function generateRequestIfGuarded() - { - if( ! $this->option('unguard')) - { - $name = $this->inflector->getRequest(); - - $this->call('make:request', compact('name')); - } - } - - /** - * Get the console command options. - * - * @return array - */ - protected function getOptions() - { - return [ - ['attach', '-a', InputOption::VALUE_OPTIONAL, 'The pipes to attach to the workflow.', null], - ['unguard', '-u', InputOption::VALUE_NONE, 'Do not make this workflow validate data.', null], - ]; - } +use Symfony\Component\Console\Input\InputOption; +class CreateWorkflowCommand extends WorkflowGeneratorCommand +{ + use AttachesPipesTrait; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'workflow:create'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Create a new workflow'; + + /** + * @author Andrea Marco Sartori + * + * @var string $type Type of class to generate. + */ + protected $type = 'Pipe'; + + /** + * Execute the console command. + * + * @return mixed + */ + public function fire() + { + $this->inflector->of($name = $this->getWorkflowName()); + + if ($this->pipelines->exists($name)) { + return $this->error("The workflow [$name] already exists."); + } + + $this->generateAllNeededFiles(); + + $this->pipelines->store($name, $this->getNamespacedPipesByOption('attach')); + + $this->info('Workflow created successfully.'); + } + + /** + * Generate all the needed files. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function generateAllNeededFiles() + { + $this->settleRepositoryIfNotExists(); + + $this->generateJob(); + + $this->generateRequestIfGuarded(); + + $this->generatePipes(); + } + + /** + * Settle the pipeline repository if it does not exist. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function settleRepositoryIfNotExists() + { + $source = $this->pipelines->getSource(); + + if (!$this->files->exists($source)) { + $this->pipelines->settle(); + } + } + + /** + * Create the job to handle. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function generateJob() + { + $name = $this->inflector->getJob(); + + $this->call('make:job', compact('name')); + } + + /** + * Create the request if unguard is not set. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function generateRequestIfGuarded() + { + if (!$this->option('unguard')) { + $name = $this->inflector->getRequest(); + + $this->call('make:request', compact('name')); + } + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['attach', '-a', InputOption::VALUE_OPTIONAL, 'The pipes to attach to the workflow.', null], + ['unguard', '-u', InputOption::VALUE_NONE, 'Do not make this workflow validate data.', null], + ]; + } } diff --git a/src/Console/Commands/DeleteIfForcedTrait.php b/src/Console/Commands/DeleteIfForcedTrait.php index 630209c..e0fe1b6 100644 --- a/src/Console/Commands/DeleteIfForcedTrait.php +++ b/src/Console/Commands/DeleteIfForcedTrait.php @@ -1,29 +1,31 @@ -option('force')) return; - - foreach ($files as $file) - { - if($this->files->exists($path = $this->getPath($file))) - { - $this->files->delete($path); - } - } - } +trait DeleteIfForcedTrait +{ + /** + * Delete the given files if force is set. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function deleteIfForced(array $files) + { + if (!$this->option('force')) { + return; + } + foreach ($files as $file) { + if ($this->files->exists($path = $this->getPath($file))) { + $this->files->delete($path); + } + } + } } diff --git a/src/Console/Commands/DeleteWorkflowCommand.php b/src/Console/Commands/DeleteWorkflowCommand.php index babd7ae..16abcbf 100644 --- a/src/Console/Commands/DeleteWorkflowCommand.php +++ b/src/Console/Commands/DeleteWorkflowCommand.php @@ -1,74 +1,76 @@ -inflector->of($name = $this->getWorkflowName()); - - if( ! $this->pipelines->exists($name)) - { - return $this->error("The workflow [$name] does not exist."); - } - - $this->deleteAllFilesOfWorkflowIfForced($name); +namespace Cerbero\Workflow\Console\Commands; - $this->pipelines->destroy($name); - - $this->info('Workflow deleted successfully.'); - } - - /** - * Delete all the generated files of the given workflow if forced. - * - * @author Andrea Marco Sartori - * @param string $workflow - * @return void - */ - protected function deleteAllFilesOfWorkflowIfForced($workflow) - { - $files = $this->pipelines->getPipesByPipeline($workflow); - - $files[] = $this->inflector->getRequest(); - - $files[] = $this->inflector->getJob(); - - $this->deleteIfForced($files); - } - - /** - * Get the console command options. - * - * @return array - */ - protected function getOptions() - { - return [ - ['force', '-f', InputOption::VALUE_NONE, 'Delete all the generated files of a workflow.'], - ]; - } +use Symfony\Component\Console\Input\InputOption; +class DeleteWorkflowCommand extends WorkflowGeneratorCommand +{ + use DeleteIfForcedTrait; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'workflow:delete'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Delete an existing workflow'; + + /** + * Execute the console command. + * + * @return mixed + */ + public function fire() + { + $this->inflector->of($name = $this->getWorkflowName()); + + if (!$this->pipelines->exists($name)) { + return $this->error("The workflow [$name] does not exist."); + } + + $this->deleteAllFilesOfWorkflowIfForced($name); + + $this->pipelines->destroy($name); + + $this->info('Workflow deleted successfully.'); + } + + /** + * Delete all the generated files of the given workflow if forced. + * + * @author Andrea Marco Sartori + * + * @param string $workflow + * + * @return void + */ + protected function deleteAllFilesOfWorkflowIfForced($workflow) + { + $files = $this->pipelines->getPipesByPipeline($workflow); + + $files[] = $this->inflector->getRequest(); + + $files[] = $this->inflector->getJob(); + + $this->deleteIfForced($files); + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['force', '-f', InputOption::VALUE_NONE, 'Delete all the generated files of a workflow.'], + ]; + } } diff --git a/src/Console/Commands/ReadWorkflowCommand.php b/src/Console/Commands/ReadWorkflowCommand.php index e8987e6..e5d31c6 100644 --- a/src/Console/Commands/ReadWorkflowCommand.php +++ b/src/Console/Commands/ReadWorkflowCommand.php @@ -1,81 +1,84 @@ -pipelines = $pipelines; + /** + * Set the dependencies. + * + * @param \Cerbero\Workflow\Repositories\PipelineRepositoryInterface $pipelines + * @param \Cerbero\Workflow\Console\Drawing\Drawer $drawer + * + * @return void + */ + public function __construct(PipelineRepositoryInterface $pipelines, Drawer $drawer) + { + parent::__construct(); - $this->drawer = $drawer; - } + $this->pipelines = $pipelines; - /** - * Execute the console command. - * - * @return mixed - */ - public function fire() - { - $workflow = ucfirst($this->argument('name')); + $this->drawer = $drawer; + } - if( ! $this->pipelines->exists($workflow)) - { - return $this->error("The workflow [$workflow] does not exist."); - } + /** + * Execute the console command. + * + * @return mixed + */ + public function fire() + { + $workflow = ucfirst($this->argument('name')); - $this->info($this->drawer->draw($workflow)); - } + if (!$this->pipelines->exists($workflow)) { + return $this->error("The workflow [$workflow] does not exist."); + } - /** - * Get the console command arguments. - * - * @return array - */ - protected function getArguments() - { - return [ - ['name', InputArgument::REQUIRED, 'The name of the workflow.'], - ]; - } + $this->info($this->drawer->draw($workflow)); + } + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['name', InputArgument::REQUIRED, 'The name of the workflow.'], + ]; + } } diff --git a/src/Console/Commands/UpdateWorkflowCommand.php b/src/Console/Commands/UpdateWorkflowCommand.php index 7388800..7800a79 100644 --- a/src/Console/Commands/UpdateWorkflowCommand.php +++ b/src/Console/Commands/UpdateWorkflowCommand.php @@ -1,95 +1,99 @@ -getWorkflowName(); - - if( ! $this->pipelines->exists($name)) - { - return $this->error("The workflow [$name] does not exist."); - } - - $this->generatePipes(); - - $this->deleteDetachedIfForced(); - - $this->updateWorkflow($name); - - $this->info('Workflow updated successfully.'); - } - - /** - * Delete the detached pipes if force is set. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function deleteDetachedIfForced() - { - $detachments = $this->getNamespacedPipesByOption('detach'); - - $this->deleteIfForced($detachments); - } - - /** - * Update the given workflow. - * - * @author Andrea Marco Sartori - * @param string $workflow - * @return void - */ - protected function updateWorkflow($workflow) - { - $attachments = $this->getNamespacedPipesByOption('attach'); - - $detachments = $this->getNamespacedPipesByOption('detach'); - - $this->pipelines->update($workflow, $attachments, $detachments); - } - - /** - * Get the console command options. - * - * @return array - */ - protected function getOptions() - { - return [ - ['attach', '-a', InputOption::VALUE_OPTIONAL, 'The pipes to attach to the workflow.', null], - ['detach', '-d', InputOption::VALUE_OPTIONAL, 'The pipes to detach from the workflow.', null], - ['force', '-f', InputOption::VALUE_NONE, 'Delete the files of detached pipes.'], - ]; - } +use Symfony\Component\Console\Input\InputOption; +class UpdateWorkflowCommand extends WorkflowGeneratorCommand +{ + use AttachesPipesTrait, DeleteIfForcedTrait; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'workflow:update'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Update an existing workflow'; + + /** + * @author Andrea Marco Sartori + * + * @var string $type Type of class to generate. + */ + protected $type = 'Pipe'; + + /** + * Execute the console command. + * + * @return mixed + */ + public function fire() + { + $name = $this->getWorkflowName(); + + if (!$this->pipelines->exists($name)) { + return $this->error("The workflow [$name] does not exist."); + } + + $this->generatePipes(); + + $this->deleteDetachedIfForced(); + + $this->updateWorkflow($name); + + $this->info('Workflow updated successfully.'); + } + + /** + * Delete the detached pipes if force is set. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function deleteDetachedIfForced() + { + $detachments = $this->getNamespacedPipesByOption('detach'); + + $this->deleteIfForced($detachments); + } + + /** + * Update the given workflow. + * + * @author Andrea Marco Sartori + * + * @param string $workflow + * + * @return void + */ + protected function updateWorkflow($workflow) + { + $attachments = $this->getNamespacedPipesByOption('attach'); + + $detachments = $this->getNamespacedPipesByOption('detach'); + + $this->pipelines->update($workflow, $attachments, $detachments); + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + ['attach', '-a', InputOption::VALUE_OPTIONAL, 'The pipes to attach to the workflow.', null], + ['detach', '-d', InputOption::VALUE_OPTIONAL, 'The pipes to detach from the workflow.', null], + ['force', '-f', InputOption::VALUE_NONE, 'Delete the files of detached pipes.'], + ]; + } } diff --git a/src/Console/Commands/WorkflowGeneratorCommand.php b/src/Console/Commands/WorkflowGeneratorCommand.php index 716af02..bf90f8d 100644 --- a/src/Console/Commands/WorkflowGeneratorCommand.php +++ b/src/Console/Commands/WorkflowGeneratorCommand.php @@ -1,81 +1,86 @@ -pipelines = $pipelines; + /** + * Set the dependencies. + * + * @param \Illuminate\Filesystem\Filesystem $files + * + * @return void + */ + public function __construct( + Filesystem $files, + PipelineRepositoryInterface $pipelines, + InflectorInterface $inflector + ) { + parent::__construct($files); - $this->inflector = $inflector; - } + $this->pipelines = $pipelines; - /** - * Get the stub file for the generator. - * - * @return string - */ - protected function getStub() - { - return __DIR__ . '/../Stubs/pipe.stub'; - } + $this->inflector = $inflector; + } - /** - * Retrieve the name of the workflow. - * - * @author Andrea Marco Sartori - * @return string - */ - protected function getWorkflowName() - { - $name = $this->argument('name'); + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getStub() + { + return __DIR__.'/../Stubs/pipe.stub'; + } - return ucfirst($name); - } + /** + * Retrieve the name of the workflow. + * + * @author Andrea Marco Sartori + * + * @return string + */ + protected function getWorkflowName() + { + $name = $this->argument('name'); - /** - * Get the console command arguments. - * - * @return array - */ - protected function getArguments() - { - return [ - ['name', InputArgument::REQUIRED, 'The name of the workflow.'], - ]; - } + return ucfirst($name); + } + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['name', InputArgument::REQUIRED, 'The name of the workflow.'], + ]; + } } diff --git a/src/Console/Drawing/Drawer.php b/src/Console/Drawing/Drawer.php index b7719c9..71ccaaa 100644 --- a/src/Console/Drawing/Drawer.php +++ b/src/Console/Drawing/Drawer.php @@ -1,4 +1,6 @@ -pipelines = $pipelines; - - $this->geometry = $geometry; - } - - /** - * Draw the given workflow. - * - * @author Andrea Marco Sartori - * @param string $workflow - * @return string - */ - public function draw($workflow) - { - $this->geometry->setCore($workflow); - - $this->setPipesOfWorkflow($workflow); - - $this->drawCenteredChar(static::NOCK); - - $this->drawPipesBeginning(); - - $this->drawCore(); - - $this->drawPipesEnd(); - - $this->drawCenteredChar(static::PILE); - - return $this->drawing; - } - - /** - * Set the pipes of the given workflow. - * - * @author Andrea Marco Sartori - * @param string $workflow - * @return void - */ - protected function setPipesOfWorkflow($workflow) - { - $pipes = $this->pipelines->getPipesByPipeline($workflow); - - $this->pipes = array_map(function($pipe) - { - $chunks = explode('\\', $pipe); - - return end($chunks); - - }, $pipes); - - $this->geometry->setPipes($this->pipes); - } - - /** - * Draw a character in the middle of the drawing. - * - * @author Andrea Marco Sartori - * @param string $character - * @return void - */ - protected function drawCenteredChar($character) - { - $spaces = str_repeat(' ', $this->geometry->getHalfWidth()); - - $this->drawRow($spaces . $character); - } - - /** - * Draw a row of the drawing. - * - * @author Andrea Marco Sartori - * @param string $row - * @return void - */ - protected function drawRow($row) - { - $this->drawing .= $row . PHP_EOL; - } - - /** - * Draw the beginning of all pipes. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function drawPipesBeginning() - { - foreach ($this->pipes as $pipe) - { - $this->drawBorderTop(); - - $this->drawBordered( - $this->geometry->getSpacedPipe($pipe, static::NOCK, 'before()') - ); - } - } - - /** - * Draw content wrapped by borders. - * - * @author Andrea Marco Sartori - * @param string $content - * @return void - */ - protected function drawBordered($content) - { - $left = $this->geometry->getLeftBordersWith(static::BORDER_X); - - $right = $this->geometry->getRightBordersWith(static::BORDER_X); - - $this->drawRow($left.$content.$right); - } - - /** - * Draw the top border. - * - * @author Andrea Marco Sartori - * @param boolean $isCore - * @return void - */ - protected function drawBorderTop($isCore = false) - { - $crossroads = $isCore ? static::CROSSROADS_UP : static::CROSSROADS; - - $this->drawBorder(static::BORDER_NW, $crossroads, static::BORDER_NE); - - $this->geometry->increaseNesting(); - } - - /** - * Draw a border with the given bendings. - * - * @author Andrea Marco Sartori - * @param string $left - * @param string $middle - * @param string $right - * @return void - */ - protected function drawBorder($left, $middle, $right) - { - $width = $this->geometry->getWidthButBorders(); - - $border = str_repeat(static::BORDER_Y, $width); - - $this->replaceUtf8($border, $left, 0); - $this->replaceUtf8($border, $middle, floor($width / 2)); - $this->replaceUtf8($border, $right, $width - 1); - - $this->drawBordered($border); - } - - /** - * Replace a character in a given position of a string. - * - * @author Andrea Marco Sartori - * @param string $original - * @param string $replacement - * @param integer $position - * @return void - */ - private function replaceUtf8(&$original, $replacement, $position) - { - $start = mb_substr($original, 0, $position, "UTF-8"); - - $end = mb_substr($original, $position + 1, mb_strlen($original, 'UTF-8'), "UTF-8"); - - $original = $start . $replacement . $end; - } - - /** - * Draw the core of the workflow. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function drawCore() - { - $this->drawBorderTop(true); - - $this->drawBordered($this->geometry->getSpacedCore()); - - $this->drawBorderBottom(true); - } - - /** - * Draw the bottom border. - * - * @author Andrea Marco Sartori - * @param boolean $isCore - * @return void - */ - protected function drawBorderBottom($isCore = false) - { - $this->geometry->decreaseNesting(); - - $crossroads = $isCore ? static::CROSSROADS_DOWN : static::CROSSROADS; - - $this->drawBorder(static::BORDER_SW, $crossroads, static::BORDER_SE); - } - - /** - * Draw the end of all pipes. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function drawPipesEnd() - { - $pipes = array_reverse($this->pipes); - - foreach ($pipes as $pipe) - { - $this->drawBordered( - $this->geometry->getSpacedPipe($pipe, static::NOCK, 'after()') - ); - - $this->drawBorderBottom(); - } - } - +class Drawer +{ + const BORDER_X = '║'; + + const BORDER_Y = '═'; + + const BORDER_NW = '╔'; + + const BORDER_NE = '╗'; + + const BORDER_SE = '╝'; + + const BORDER_SW = '╚'; + + const NOCK = '║'; + + const PILE = '∇'; + + const CROSSROADS = '╬'; + + const CROSSROADS_UP = '╩'; + + const CROSSROADS_DOWN = '╦'; + + /** + * @author Andrea Marco Sartori + * + * @var Cerbero\Workflow\Repositories\PipelineRepositoryInterface $pipelines Pipeline repository. + */ + protected $pipelines; + + /** + * @author Andrea Marco Sartori + * + * @var Cerbero\Workflow\Console\Drawing\Geometry $geometry The applied geometry. + */ + protected $geometry; + + /** + * @author Andrea Marco Sartori + * + * @var array $pipes List of pipes. + */ + protected $pipes; + + /** + * @author Andrea Marco Sartori + * + * @var string $drawing The resulting drawing. + */ + protected $drawing = ''; + + /** + * Set the dependencies. + * + * @author Andrea Marco Sartori + * + * @param Cerbero\Workflow\Repositories\PipelineRepositoryInterface $pipelines + * @param Cerbero\Workflow\Console\Drawing\Geometry $geometry + * + * @return void + */ + public function __construct(PipelineRepositoryInterface $pipelines, Geometry $geometry) + { + $this->pipelines = $pipelines; + + $this->geometry = $geometry; + } + + /** + * Draw the given workflow. + * + * @author Andrea Marco Sartori + * + * @param string $workflow + * + * @return string + */ + public function draw($workflow) + { + $this->geometry->setCore($workflow); + + $this->setPipesOfWorkflow($workflow); + + $this->drawCenteredChar(static::NOCK); + + $this->drawPipesBeginning(); + + $this->drawCore(); + + $this->drawPipesEnd(); + + $this->drawCenteredChar(static::PILE); + + return $this->drawing; + } + + /** + * Set the pipes of the given workflow. + * + * @author Andrea Marco Sartori + * + * @param string $workflow + * + * @return void + */ + protected function setPipesOfWorkflow($workflow) + { + $pipes = $this->pipelines->getPipesByPipeline($workflow); + + $this->pipes = array_map(function ($pipe) { + $chunks = explode('\\', $pipe); + + return end($chunks); + }, $pipes); + + $this->geometry->setPipes($this->pipes); + } + + /** + * Draw a character in the middle of the drawing. + * + * @author Andrea Marco Sartori + * + * @param string $character + * + * @return void + */ + protected function drawCenteredChar($character) + { + $spaces = str_repeat(' ', $this->geometry->getHalfWidth()); + + $this->drawRow($spaces.$character); + } + + /** + * Draw a row of the drawing. + * + * @author Andrea Marco Sartori + * + * @param string $row + * + * @return void + */ + protected function drawRow($row) + { + $this->drawing .= $row.PHP_EOL; + } + + /** + * Draw the beginning of all pipes. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function drawPipesBeginning() + { + foreach ($this->pipes as $pipe) { + $this->drawBorderTop(); + + $this->drawBordered( + $this->geometry->getSpacedPipe($pipe, static::NOCK, 'before()') + ); + } + } + + /** + * Draw content wrapped by borders. + * + * @author Andrea Marco Sartori + * + * @param string $content + * + * @return void + */ + protected function drawBordered($content) + { + $left = $this->geometry->getLeftBordersWith(static::BORDER_X); + + $right = $this->geometry->getRightBordersWith(static::BORDER_X); + + $this->drawRow($left.$content.$right); + } + + /** + * Draw the top border. + * + * @author Andrea Marco Sartori + * + * @param bool $isCore + * + * @return void + */ + protected function drawBorderTop($isCore = false) + { + $crossroads = $isCore ? static::CROSSROADS_UP : static::CROSSROADS; + + $this->drawBorder(static::BORDER_NW, $crossroads, static::BORDER_NE); + + $this->geometry->increaseNesting(); + } + + /** + * Draw a border with the given bendings. + * + * @author Andrea Marco Sartori + * + * @param string $left + * @param string $middle + * @param string $right + * + * @return void + */ + protected function drawBorder($left, $middle, $right) + { + $width = $this->geometry->getWidthButBorders(); + + $border = str_repeat(static::BORDER_Y, $width); + + $this->replaceUtf8($border, $left, 0); + $this->replaceUtf8($border, $middle, floor($width / 2)); + $this->replaceUtf8($border, $right, $width - 1); + + $this->drawBordered($border); + } + + /** + * Replace a character in a given position of a string. + * + * @author Andrea Marco Sartori + * + * @param string $original + * @param string $replacement + * @param int $position + * + * @return void + */ + private function replaceUtf8(&$original, $replacement, $position) + { + $start = mb_substr($original, 0, $position, 'UTF-8'); + + $end = mb_substr($original, $position + 1, mb_strlen($original, 'UTF-8'), 'UTF-8'); + + $original = $start.$replacement.$end; + } + + /** + * Draw the core of the workflow. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function drawCore() + { + $this->drawBorderTop(true); + + $this->drawBordered($this->geometry->getSpacedCore()); + + $this->drawBorderBottom(true); + } + + /** + * Draw the bottom border. + * + * @author Andrea Marco Sartori + * + * @param bool $isCore + * + * @return void + */ + protected function drawBorderBottom($isCore = false) + { + $this->geometry->decreaseNesting(); + + $crossroads = $isCore ? static::CROSSROADS_DOWN : static::CROSSROADS; + + $this->drawBorder(static::BORDER_SW, $crossroads, static::BORDER_SE); + } + + /** + * Draw the end of all pipes. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function drawPipesEnd() + { + $pipes = array_reverse($this->pipes); + + foreach ($pipes as $pipe) { + $this->drawBordered( + $this->geometry->getSpacedPipe($pipe, static::NOCK, 'after()') + ); + + $this->drawBorderBottom(); + } + } } diff --git a/src/Console/Drawing/Geometry.php b/src/Console/Drawing/Geometry.php index 053c9d6..ac2f131 100644 --- a/src/Console/Drawing/Geometry.php +++ b/src/Console/Drawing/Geometry.php @@ -1,311 +1,343 @@ -core = $core; - } - - /** - * Set the pipes. - * - * @author Andrea Marco Sartori - * @param array $pipes - * @return void - */ - public function setPipes(array $pipes) - { - $this->pipes = $pipes; - } - - /** - * Calculate the half width of the drawing. - * - * @author Andrea Marco Sartori - * @param boolean $up - * @return integer - */ - public function getHalfWidth($up = false) - { - $number = $this->getTotalWidth(); - - return $this->roundHalf($number, $up); - } - - /** - * Round the half of a number, either up or down. - * - * @author Andrea Marco Sartori - * @param integer $number - * @param boolean $up - * @return integer - */ - private function roundHalf($number, $up) - { - $round = $up ? 'ceil' : 'floor'; - - return $round($number / 2); - } - - /** - * Calculate the total width of the drawing. - * - * @author Andrea Marco Sartori - * @return integer - */ - protected function getTotalWidth() - { - $borders = (static::BORDER_WIDTH + static::MIN_SPACE_FROM_BORDER_X) * 2; - - if(empty($this->pipes)) - { - return $borders + $this->getCoreLength(); - } - - $borders *= count($this->pipes); - - $name = ($this->getLongestPipeLength() + static::SPACE_FROM_ARROW) * 2; - - return $borders + $name + static::ARROW_WIDTH; - } - - /** - * Calculate the length of the core name. - * - * @author Andrea Marco Sartori - * @return integer - */ - protected function getCoreLength() - { - return strlen($this->core); - } - - /** - * Calculate the length of the longest pipe name. - * - * @author Andrea Marco Sartori - * @return integer - */ - protected function getLongestPipeLength() - { - if(empty($this->pipes)) return 0; - - return array_reduce($this->pipes, function($carry, $pipe) - { - return strlen($pipe) > $carry ? strlen($pipe) : $carry; - - }, static::MIN_PIPE_LENGTH); - } - - /** - * Retrieve the spaced pipe and method pair. - * - * @author Andrea Marco Sartori - * @param string $pipe - * @param string $arrow - * @param string $method - * @return string - */ - public function getSpacedPipe($pipe, $arrow, $method) - { - $left = $this->getSpacesByWord($pipe); - - $arrow = $this->addSpacesToArrow($arrow); - - $right = $this->getSpacesByWord($method); - - return $left.$pipe.$arrow.$method.$right; - } - - /** - * Retrieve the blank spaces close to a word. - * - * @author Andrea Marco Sartori - * @param string $word - * @return string - */ - protected function getSpacesByWord($word) - { - $length = $this->getSideBordersLength() + static::SPACE_FROM_ARROW + static::ARROW_WIDTH; - - $extra = $this->getHalfWidth(true) - $length - strlen($word); - - return $extra > 0 ? str_repeat(' ', $extra) : ''; - } - - /** - * Retrieve the length of the borders of a side. - * - * @author Andrea Marco Sartori - * @return integer - */ - protected function getSideBordersLength() - { - $border = (static::BORDER_WIDTH + static::MIN_SPACE_FROM_BORDER_X); - - return $border * $this->nesting; - } - - /** - * Add spaces around the given arrow. - * - * @author Andrea Marco Sartori - * @param string $arrow - * @return string - */ - protected function addSpacesToArrow($arrow) - { - $spaces = str_repeat(' ', static::SPACE_FROM_ARROW); - - return "{$spaces}{$arrow}{$spaces}"; - } - - /** - * Retrieve the left borders formatted with the given border. - * - * @author Andrea Marco Sartori - * @param string $border - * @return string - */ - public function getLeftBordersWith($border) - { - $border = str_repeat($border, static::BORDER_WIDTH); - - $space = str_repeat(' ', static::MIN_SPACE_FROM_BORDER_X); - - return str_repeat("{$border}{$space}", $this->nesting); - } - - /** - * Retrieve the right borders formatted with the given border. - * - * @author Andrea Marco Sartori - * @param string $border - * @return string - */ - public function getRightBordersWith($border) - { - $space = str_repeat(' ', static::MIN_SPACE_FROM_BORDER_X); - - $border = str_repeat($border, static::BORDER_WIDTH); - - return str_repeat("{$space}{$border}", $this->nesting); - } - - /** - * Increase the nesting level. - * - * @author Andrea Marco Sartori - * @return void - */ - public function increaseNesting() - { - $this->nesting++; - } - - /** - * Calculate the width of the drawing without the borders. - * - * @author Andrea Marco Sartori - * @return integer - */ - public function getWidthButBorders() - { - return $this->getTotalWidth() - $this->getBordersLength(); - } - - /** - * Calculate the length of the borders. - * - * @author Andrea Marco Sartori - * @return integer - */ - protected function getBordersLength() - { - return $this->getSideBordersLength() * 2; - } - - /** - * Retrieve the spaced core name. - * - * @author Andrea Marco Sartori - * @return string - */ - public function getSpacedCore() - { - $left = $this->getSpacesByCore(); - - $right = $this->getSpacesByCore(true); - - return $left.$this->core.$right; - } - - /** - * Retrieve the blank spaces close to the core. - * - * @author Andrea Marco Sartori - * @param boolean $up - * @return string - */ - protected function getSpacesByCore($up = false) - { - $free = $this->getTotalWidth() - $this->getBordersLength() - $this->getCoreLength(); - - return $free < 1 ? '' : str_repeat(' ', $this->roundHalf($free, $up)); - } - - /** - * Decrease the nesting level. - * - * @author Andrea Marco Sartori - * @return void - */ - public function decreaseNesting() - { - $this->nesting--; - } - +class Geometry +{ + const BORDER_WIDTH = 1; + + const MIN_SPACE_FROM_BORDER_X = 1; + + const MIN_SPACE_FROM_BORDER_Y = 0; + + const ARROW_WIDTH = 1; + + const MIN_PIPE_LENGTH = 8; + + const SPACE_FROM_ARROW = 1; + + /** + * @author Andrea Marco Sartori + * + * @var string $core The name of the core. + */ + protected $core; + + /** + * @author Andrea Marco Sartori + * + * @var array $pipes List of pipes. + */ + protected $pipes; + + /** + * @author Andrea Marco Sartori + * + * @var int $nesting Nesting level. + */ + protected $nesting = 0; + + /** + * Set the name of the core. + * + * @author Andrea Marco Sartori + * + * @param string $core + * + * @return void + */ + public function setCore($core) + { + $this->core = $core; + } + + /** + * Set the pipes. + * + * @author Andrea Marco Sartori + * + * @param array $pipes + * + * @return void + */ + public function setPipes(array $pipes) + { + $this->pipes = $pipes; + } + + /** + * Calculate the half width of the drawing. + * + * @author Andrea Marco Sartori + * + * @param bool $up + * + * @return int + */ + public function getHalfWidth($up = false) + { + $number = $this->getTotalWidth(); + + return $this->roundHalf($number, $up); + } + + /** + * Round the half of a number, either up or down. + * + * @author Andrea Marco Sartori + * + * @param int $number + * @param bool $up + * + * @return int + */ + private function roundHalf($number, $up) + { + $round = $up ? 'ceil' : 'floor'; + + return $round($number / 2); + } + + /** + * Calculate the total width of the drawing. + * + * @author Andrea Marco Sartori + * + * @return int + */ + protected function getTotalWidth() + { + $borders = (static::BORDER_WIDTH + static::MIN_SPACE_FROM_BORDER_X) * 2; + + if (empty($this->pipes)) { + return $borders + $this->getCoreLength(); + } + + $borders *= count($this->pipes); + + $name = ($this->getLongestPipeLength() + static::SPACE_FROM_ARROW) * 2; + + return $borders + $name + static::ARROW_WIDTH; + } + + /** + * Calculate the length of the core name. + * + * @author Andrea Marco Sartori + * + * @return int + */ + protected function getCoreLength() + { + return strlen($this->core); + } + + /** + * Calculate the length of the longest pipe name. + * + * @author Andrea Marco Sartori + * + * @return int + */ + protected function getLongestPipeLength() + { + if (empty($this->pipes)) { + return 0; + } + + return array_reduce($this->pipes, function ($carry, $pipe) { + return strlen($pipe) > $carry ? strlen($pipe) : $carry; + }, static::MIN_PIPE_LENGTH); + } + + /** + * Retrieve the spaced pipe and method pair. + * + * @author Andrea Marco Sartori + * + * @param string $pipe + * @param string $arrow + * @param string $method + * + * @return string + */ + public function getSpacedPipe($pipe, $arrow, $method) + { + $left = $this->getSpacesByWord($pipe); + + $arrow = $this->addSpacesToArrow($arrow); + + $right = $this->getSpacesByWord($method); + + return $left.$pipe.$arrow.$method.$right; + } + + /** + * Retrieve the blank spaces close to a word. + * + * @author Andrea Marco Sartori + * + * @param string $word + * + * @return string + */ + protected function getSpacesByWord($word) + { + $length = $this->getSideBordersLength() + static::SPACE_FROM_ARROW + static::ARROW_WIDTH; + + $extra = $this->getHalfWidth(true) - $length - strlen($word); + + return $extra > 0 ? str_repeat(' ', $extra) : ''; + } + + /** + * Retrieve the length of the borders of a side. + * + * @author Andrea Marco Sartori + * + * @return int + */ + protected function getSideBordersLength() + { + $border = (static::BORDER_WIDTH + static::MIN_SPACE_FROM_BORDER_X); + + return $border * $this->nesting; + } + + /** + * Add spaces around the given arrow. + * + * @author Andrea Marco Sartori + * + * @param string $arrow + * + * @return string + */ + protected function addSpacesToArrow($arrow) + { + $spaces = str_repeat(' ', static::SPACE_FROM_ARROW); + + return "{$spaces}{$arrow}{$spaces}"; + } + + /** + * Retrieve the left borders formatted with the given border. + * + * @author Andrea Marco Sartori + * + * @param string $border + * + * @return string + */ + public function getLeftBordersWith($border) + { + $border = str_repeat($border, static::BORDER_WIDTH); + + $space = str_repeat(' ', static::MIN_SPACE_FROM_BORDER_X); + + return str_repeat("{$border}{$space}", $this->nesting); + } + + /** + * Retrieve the right borders formatted with the given border. + * + * @author Andrea Marco Sartori + * + * @param string $border + * + * @return string + */ + public function getRightBordersWith($border) + { + $space = str_repeat(' ', static::MIN_SPACE_FROM_BORDER_X); + + $border = str_repeat($border, static::BORDER_WIDTH); + + return str_repeat("{$space}{$border}", $this->nesting); + } + + /** + * Increase the nesting level. + * + * @author Andrea Marco Sartori + * + * @return void + */ + public function increaseNesting() + { + $this->nesting++; + } + + /** + * Calculate the width of the drawing without the borders. + * + * @author Andrea Marco Sartori + * + * @return int + */ + public function getWidthButBorders() + { + return $this->getTotalWidth() - $this->getBordersLength(); + } + + /** + * Calculate the length of the borders. + * + * @author Andrea Marco Sartori + * + * @return int + */ + protected function getBordersLength() + { + return $this->getSideBordersLength() * 2; + } + + /** + * Retrieve the spaced core name. + * + * @author Andrea Marco Sartori + * + * @return string + */ + public function getSpacedCore() + { + $left = $this->getSpacesByCore(); + + $right = $this->getSpacesByCore(true); + + return $left.$this->core.$right; + } + + /** + * Retrieve the blank spaces close to the core. + * + * @author Andrea Marco Sartori + * + * @param bool $up + * + * @return string + */ + protected function getSpacesByCore($up = false) + { + $free = $this->getTotalWidth() - $this->getBordersLength() - $this->getCoreLength(); + + return $free < 1 ? '' : str_repeat(' ', $this->roundHalf($free, $up)); + } + + /** + * Decrease the nesting level. + * + * @author Andrea Marco Sartori + * + * @return void + */ + public function decreaseNesting() + { + $this->nesting--; + } } diff --git a/src/Facades/Workflow.php b/src/Facades/Workflow.php index a6efff5..09977a6 100644 --- a/src/Facades/Workflow.php +++ b/src/Facades/Workflow.php @@ -1,17 +1,21 @@ -namespace = $detector->detect(); - } + /** + * @author Andrea Marco Sartori + * + * @var string $namespace The application namespace. + */ + protected $namespace; - /** - * Set the word to inflect. - * - * @author Andrea Marco Sartori - * @param string $word - * @return $this - */ - public function of($word) - { - $this->word = $word; + /** + * Set the application namespace. + * + * @author Andrea Marco Sartori + * + * @param Cerbero\Workflow\Wrappers\NamespaceDetectorInterface $detector Application namespace detector. + * + * @return void + */ + public function __construct(NamespaceDetectorInterface $detector) + { + $this->namespace = $detector->detect(); + } - return $this; - } + /** + * Set the word to inflect. + * + * @author Andrea Marco Sartori + * + * @param string $word + * + * @return $this + */ + public function of($word) + { + $this->word = $word; - /** - * Retrieve the inflected request. - * - * @author Andrea Marco Sartori - * @return string - */ - public function getRequest() - { - return $this->compose('Request', 'Http\Requests'); - } + return $this; + } - /** - * Compose the word to inflect. - * - * @author Andrea Marco Sartori - * @param string $suffix - * @param string $path - * @return string - */ - protected function compose($suffix, $path) - { - $name = ucfirst($this->word) . $suffix; + /** + * Retrieve the inflected request. + * + * @author Andrea Marco Sartori + * + * @return string + */ + public function getRequest() + { + return $this->compose('Request', 'Http\Requests'); + } - return $this->namespace . "\\{$path}\\{$name}"; - } + /** + * Compose the word to inflect. + * + * @author Andrea Marco Sartori + * + * @param string $suffix + * @param string $path + * + * @return string + */ + protected function compose($suffix, $path) + { + $name = ucfirst($this->word).$suffix; - /** - * Retrieve the inflected job. - * - * @author Andrea Marco Sartori - * @return string - */ - public function getJob() - { - return $this->compose('Job', 'Jobs'); - } + return $this->namespace."\\{$path}\\{$name}"; + } + /** + * Retrieve the inflected job. + * + * @author Andrea Marco Sartori + * + * @return string + */ + public function getJob() + { + return $this->compose('Job', 'Jobs'); + } } diff --git a/src/Inflectors/InflectorInterface.php b/src/Inflectors/InflectorInterface.php index 94560e6..91c3fb4 100644 --- a/src/Inflectors/InflectorInterface.php +++ b/src/Inflectors/InflectorInterface.php @@ -1,35 +1,40 @@ -container = $container; - } +abstract class AbstractPipe implements PipeInterface +{ + /** + * @author Andrea Marco Sartori + * + * @var Illuminate\Contracts\Container\Container $container Service container. + */ + protected $container; - /** - * Handle the given job. - * - * @author Andrea Marco Sartori - * @param mixed $job - * @param Closure $next - * @return mixed - */ - public function handle($job, Closure $next) - { - $this->callBefore($job); + /** + * Set the dependencies. + * + * @author Andrea Marco Sartori + * + * @param Illuminate\Contracts\Container\Container $container + * + * @return void + */ + public function __construct(Container $container) + { + $this->container = $container; + } - $handled = $next($job); + /** + * Handle the given job. + * + * @author Andrea Marco Sartori + * + * @param mixed $job + * @param Closure $next + * + * @return mixed + */ + public function handle($job, Closure $next) + { + $this->callBefore($job); - $this->callAfter($handled, $job); + $handled = $next($job); - return $handled; - } + $this->callAfter($handled, $job); - /** - * Call the before method. - * - * @author Andrea Marco Sartori - * @param Cerbero\Jobs\Job $job - * @return void - */ - protected function callBefore($job) - { - $this->callIfExists('before', [$job]); - } + return $handled; + } - /** - * Call a method if it exists and resolve its dependencies. - * - * @author Andrea Marco Sartori - * @param string $method - * @param array $parameters - * @return void - */ - private function callIfExists($method, array $parameters = []) - { - if(method_exists($this, $method)) - { - $this->container->call([$this, $method], $parameters); - } - } + /** + * Call the before method. + * + * @author Andrea Marco Sartori + * + * @param Cerbero\Jobs\Job $job + * + * @return void + */ + protected function callBefore($job) + { + $this->callIfExists('before', [$job]); + } - /** - * Call the after method. - * - * @author Andrea Marco Sartori - * @param mixed $handled - * @param Cerbero\Jobs\Job $job - * @return void - */ - protected function callAfter($handled, $job) - { - $this->callIfExists('after', [$handled, $job]); - } + /** + * Call a method if it exists and resolve its dependencies. + * + * @author Andrea Marco Sartori + * + * @param string $method + * @param array $parameters + * + * @return void + */ + private function callIfExists($method, array $parameters = []) + { + if (method_exists($this, $method)) { + $this->container->call([$this, $method], $parameters); + } + } + /** + * Call the after method. + * + * @author Andrea Marco Sartori + * + * @param mixed $handled + * @param Cerbero\Jobs\Job $job + * + * @return void + */ + protected function callAfter($handled, $job) + { + $this->callIfExists('after', [$handled, $job]); + } } diff --git a/src/Pipes/PipeInterface.php b/src/Pipes/PipeInterface.php index cfa3eed..467b510 100644 --- a/src/Pipes/PipeInterface.php +++ b/src/Pipes/PipeInterface.php @@ -1,22 +1,25 @@ -parser = $parser; - - $this->files = $files; - - $this->path = $path; - - $this->pipelines = $this->parseYaml(); - } - - /** - * Parse the YAML file. - * - * @author Andrea Marco Sartori - * @return array - */ - private function parseYaml() - { - $file = $this->getSource(); - - return (array) $this->parser->parse($file); - } - - /** - * Retrieve the source of the pipelines. - * - * @author Andrea Marco Sartori - * @return string - */ - public function getSource() - { - $path = rtrim($this->path, '/'); - - return "{$path}/workflows.yml"; - } - - /** - * Determine whether a given pipeline exists. - * - * @author Andrea Marco Sartori - * @param string $pipeline - * @return boolean - */ - public function exists($pipeline) - { - $this->normalizePipeline($pipeline); - - return array_key_exists($pipeline, $this->pipelines); - } - - /** - * Normalize the name of the given pipeline. - * - * @author Andrea Marco Sartori - * @param string $pipeline - * @return void - */ - protected function normalizePipeline(&$pipeline) - { - $pipeline = ucfirst($pipeline); - } - - /** - * Retrieve the pipes of a given pipeline. - * - * @author Andrea Marco Sartori - * @param string $pipeline - * @return array - */ - public function getPipesByPipeline($pipeline) - { - $this->normalizePipeline($pipeline); - - return $this->pipelines[$pipeline]; - } - - /** - * Create the pipelines storage. - * - * @author Andrea Marco Sartori - * @return void - */ - public function settle() - { - $this->files->makeDirectory($this->path, 0755, true, true); - - $this->files->put($this->getSource(), ''); - } - - /** - * Store the given pipeline and its pipes. - * - * @author Andrea Marco Sartori - * @param string $pipeline - * @param array $pipes - * @return void - */ - public function store($pipeline, array $pipes) - { - $workflow = [$pipeline => $pipes]; - - $yaml = $this->parser->dump($workflow); - - $this->files->append($this->getSource(), $yaml); - } - - /** - * Update the given pipeline and its pipes. - * - * @author Andrea Marco Sartori - * @param string $pipeline - * @param array $attachments - * @param array $detachments - * @return void - */ - public function update($pipeline, array $attachments, array $detachments) - { - $this->detach($this->pipelines[$pipeline], $detachments); - - $this->attach($this->pipelines[$pipeline], $attachments); - - $this->refreshPipelines(); - } - - /** - * Detach pipes from a given pipeline. - * - * @author Andrea Marco Sartori - * @param array $pipeline - * @param array $pipes - * @return void - */ - protected function detach(array &$pipeline, array $pipes) - { - $pipeline = array_diff($pipeline, $pipes); - } - - /** - * Attach pipes to a given pipeline. - * - * @author Andrea Marco Sartori - * @param array $pipeline - * @param array $pipes - * @return void - */ - protected function attach(array &$pipeline, array $pipes) - { - $pipeline = array_merge($pipeline, $pipes); - } - - /** - * Refresh the pipelines source. - * - * @author Andrea Marco Sartori - * @return void - */ - protected function refreshPipelines() - { - $yaml = $this->parser->dump($this->pipelines); - - $this->files->put($this->getSource(), $yaml); - } - - /** - * Destroy a given pipeline. - * - * @author Andrea Marco Sartori - * @param string $pipeline - * @return void - */ - public function destroy($pipeline) - { - unset($this->pipelines[$pipeline]); - - $this->refreshPipelines(); - } - +class YamlPipelineRepository implements PipelineRepositoryInterface +{ + /** + * @author Andrea Marco Sartori + * + * @var array $pipelines Pipelines list. + */ + protected $pipelines; + + /** + * @author Andrea Marco Sartori + * + * @var Cerbero\Workflow\Wrappers\YamlParserInterface $parser YAML parser. + */ + protected $parser; + + /** + * @author Andrea Marco Sartori + * + * @var Illuminate\Filesystem\Filesystem $files Filesystem. + */ + protected $files; + + /** + * @author Andrea Marco Sartori + * + * @var string $path The workflows path. + */ + protected $path; + + /** + * Set the dependencies. + * + * @author Andrea Marco Sartori + * + * @param Cerbero\Workflow\Wrappers\YamlParserInterface $parser + * @param Illuminate\Filesystem\Filesystem $files + * @param string $path + * + * @return void + */ + public function __construct(YamlParserInterface $parser, Filesystem $files, $path) + { + $this->parser = $parser; + + $this->files = $files; + + $this->path = $path; + + $this->pipelines = $this->parseYaml(); + } + + /** + * Parse the YAML file. + * + * @author Andrea Marco Sartori + * + * @return array + */ + private function parseYaml() + { + $file = $this->getSource(); + + return (array) $this->parser->parse($file); + } + + /** + * Retrieve the source of the pipelines. + * + * @author Andrea Marco Sartori + * + * @return string + */ + public function getSource() + { + $path = rtrim($this->path, '/'); + + return "{$path}/workflows.yml"; + } + + /** + * Determine whether a given pipeline exists. + * + * @author Andrea Marco Sartori + * + * @param string $pipeline + * + * @return bool + */ + public function exists($pipeline) + { + $this->normalizePipeline($pipeline); + + return array_key_exists($pipeline, $this->pipelines); + } + + /** + * Normalize the name of the given pipeline. + * + * @author Andrea Marco Sartori + * + * @param string $pipeline + * + * @return void + */ + protected function normalizePipeline(&$pipeline) + { + $pipeline = ucfirst($pipeline); + } + + /** + * Retrieve the pipes of a given pipeline. + * + * @author Andrea Marco Sartori + * + * @param string $pipeline + * + * @return array + */ + public function getPipesByPipeline($pipeline) + { + $this->normalizePipeline($pipeline); + + return $this->pipelines[$pipeline]; + } + + /** + * Create the pipelines storage. + * + * @author Andrea Marco Sartori + * + * @return void + */ + public function settle() + { + $this->files->makeDirectory($this->path, 0755, true, true); + + $this->files->put($this->getSource(), ''); + } + + /** + * Store the given pipeline and its pipes. + * + * @author Andrea Marco Sartori + * + * @param string $pipeline + * @param array $pipes + * + * @return void + */ + public function store($pipeline, array $pipes) + { + $workflow = [$pipeline => $pipes]; + + $yaml = $this->parser->dump($workflow); + + $this->files->append($this->getSource(), $yaml); + } + + /** + * Update the given pipeline and its pipes. + * + * @author Andrea Marco Sartori + * + * @param string $pipeline + * @param array $attachments + * @param array $detachments + * + * @return void + */ + public function update($pipeline, array $attachments, array $detachments) + { + $this->detach($this->pipelines[$pipeline], $detachments); + + $this->attach($this->pipelines[$pipeline], $attachments); + + $this->refreshPipelines(); + } + + /** + * Detach pipes from a given pipeline. + * + * @author Andrea Marco Sartori + * + * @param array $pipeline + * @param array $pipes + * + * @return void + */ + protected function detach(array &$pipeline, array $pipes) + { + $pipeline = array_diff($pipeline, $pipes); + } + + /** + * Attach pipes to a given pipeline. + * + * @author Andrea Marco Sartori + * + * @param array $pipeline + * @param array $pipes + * + * @return void + */ + protected function attach(array &$pipeline, array $pipes) + { + $pipeline = array_merge($pipeline, $pipes); + } + + /** + * Refresh the pipelines source. + * + * @author Andrea Marco Sartori + * + * @return void + */ + protected function refreshPipelines() + { + $yaml = $this->parser->dump($this->pipelines); + + $this->files->put($this->getSource(), $yaml); + } + + /** + * Destroy a given pipeline. + * + * @author Andrea Marco Sartori + * + * @param string $pipeline + * + * @return void + */ + public function destroy($pipeline) + { + unset($this->pipelines[$pipeline]); + + $this->refreshPipelines(); + } } diff --git a/src/RunsWorkflow.php b/src/RunsWorkflow.php index 7acd65c..9cee654 100644 --- a/src/RunsWorkflow.php +++ b/src/RunsWorkflow.php @@ -1,28 +1,32 @@ -workflow = $workflow; - } +trait RunsWorkflow +{ + /** + * @author Andrea Marco Sartori + * + * @var Cerbero\Workflow\Workflow $workflow Workflows hub. + */ + protected $workflow; + /** + * Set the workflow to run. + * + * @author Andrea Marco Sartori + * + * @param Cerbero\Workflow\Workflow $workflow + * + * @return void + */ + public function setWorkflow(Workflow $workflow) + { + $this->workflow = $workflow; + } } diff --git a/src/Workflow.php b/src/Workflow.php index cbaf469..36b79ab 100644 --- a/src/Workflow.php +++ b/src/Workflow.php @@ -1,7 +1,9 @@ -pipelines = $pipelines; - $this->inflector = $inflector; - $this->container = $container; - $this->dispatcher = $dispatcher; - } - - /** - * Dynamically call pipelines. - * - * @author Andrea Marco Sartori - * @param string $name - * @param array $arguments - * @return mixed - */ - public function __call($name, $arguments) - { - $this->failIfNotExists($name); - - $this->inflector->of($name); - - return $this->dispatchWorkflow($name); - } - - /** - * Throw an exception if the given workflow does not exist. - * - * @author Andrea Marco Sartori - * @param string $workflow - * @return void - */ - protected function failIfNotExists($workflow) - { - if( ! $this->pipelines->exists($workflow)) - { - $error = "The workflow [$workflow] does not exist."; - - throw new \BadFunctionCallException($error); - } - } - - /** - * Dispatch the given workflow. - * - * @author Andrea Marco Sartori - * @param string $workflow - * @return mixed - */ - protected function dispatchWorkflow($workflow) - { - $job = $this->inflector->getJob(); - - $request = $this->resolveRequest(); - - $pipes = $this->pipelines->getPipesByPipeline($workflow); - - $parameters = $this->container->make('router')->current()->parameters(); - - return $this->dispatcher->pipeThrough($pipes)->dispatchFrom($job, $request, $parameters); - } - - /** - * Resolve the apter request. - * - * @author Andrea Marco Sartori - * @return Illuminate\Http\Request - */ - protected function resolveRequest() - { - if(class_exists($request = $this->inflector->getRequest())) - { - return $this->container->make($request); - } - - return $this->container->make('Illuminate\Http\Request'); - } - +class Workflow +{ + /** + * @author Andrea Marco Sartori + * + * @var Cerbero\Workflow\Repositories\PipelineRepositoryInterface $pipelines Pipelines repository. + */ + protected $pipelines; + + /** + * @author Andrea Marco Sartori + * + * @var Cerbero\Workflow\Inflectors\InflectorInterface $inflector Inflector. + */ + protected $inflector; + + /** + * @author Andrea Marco Sartori + * + * @var Illuminate\Contracts\Container\Container $container Service container. + */ + protected $container; + + /** + * @author Andrea Marco Sartori + * + * @var Cerbero\Workflow\Wrappers\DispatcherInterface $dispatcher Bus dispatcher. + */ + protected $dispatcher; + + /** + * Set the dependencies. + * + * @author Andrea Marco Sartori + * + * @param Cerbero\Workflow\Repositories\PipelineRepositoryInterface $pipelines + * @param Cerbero\Workflow\Wrappers\DispatcherInterface $dispatcher + * @param Cerbero\Workflow\Inflectors\InflectorInterface $inflector + * @param Illuminate\Contracts\Container\Container $container + * + * @return void + */ + public function __construct( + PipelineRepositoryInterface $pipelines, + InflectorInterface $inflector, + Container $container, + DispatcherInterface $dispatcher + ) { + $this->pipelines = $pipelines; + $this->inflector = $inflector; + $this->container = $container; + $this->dispatcher = $dispatcher; + } + + /** + * Dynamically call pipelines. + * + * @author Andrea Marco Sartori + * + * @param string $name + * @param array $arguments + * + * @return mixed + */ + public function __call($name, $arguments) + { + $this->failIfNotExists($name); + + $this->inflector->of($name); + + return $this->dispatchWorkflow($name); + } + + /** + * Throw an exception if the given workflow does not exist. + * + * @author Andrea Marco Sartori + * + * @param string $workflow + * + * @return void + */ + protected function failIfNotExists($workflow) + { + if (!$this->pipelines->exists($workflow)) { + $error = "The workflow [$workflow] does not exist."; + + throw new \BadFunctionCallException($error); + } + } + + /** + * Dispatch the given workflow. + * + * @author Andrea Marco Sartori + * + * @param string $workflow + * + * @return mixed + */ + protected function dispatchWorkflow($workflow) + { + $job = $this->inflector->getJob(); + + $request = $this->resolveRequest(); + + $pipes = $this->pipelines->getPipesByPipeline($workflow); + + $parameters = $this->container->make('router')->current()->parameters(); + + return $this->dispatcher->pipeThrough($pipes)->dispatchFrom($job, $request, $parameters); + } + + /** + * Resolve the apter request. + * + * @author Andrea Marco Sartori + * + * @return Illuminate\Http\Request + */ + protected function resolveRequest() + { + if (class_exists($request = $this->inflector->getRequest())) { + return $this->container->make($request); + } + + return $this->container->make('Illuminate\Http\Request'); + } } diff --git a/src/WorkflowRunner.php b/src/WorkflowRunner.php index cfaa0eb..5fbe0e7 100644 --- a/src/WorkflowRunner.php +++ b/src/WorkflowRunner.php @@ -1,19 +1,22 @@ -publishConfig(); - - $this->commands($this->commands); - - $facade = 'Cerbero\Workflow\Facades\Workflow'; - - AliasLoader::getInstance()->alias('Workflow', $facade); - } - - /** - * Publish the configuration file. - * - * @author Andrea Marco Sartori - * @return void - */ - private function publishConfig() - { - $config = __DIR__ . '/config/workflow.php'; - - $this->publishes([$config => config_path('workflow.php')]); - - $this->mergeConfigFrom($config, 'workflow'); - } - - /** - * Register the services. - * - * @author Andrea Marco Sartori - * @return void - */ - public function register() - { - $this->registerPipelineRepository(); - - $this->registerInflector(); - - $this->registerDispatcher(); - - $this->registerWorkflow(); - - $this->registerWorkflowRunnersHook(); - - $this->registerCommands(); - } - - /** - * Register the pipeline repository. - * - * @author Andrea Marco Sartori - * @return void - */ - private function registerPipelineRepository() - { - $abstract = 'Cerbero\Workflow\Repositories\PipelineRepositoryInterface'; - - $this->app->bind($abstract, function($app) - { - return new YamlPipelineRepository - ( - new SymfonyYamlParser, - - new \Illuminate\Filesystem\Filesystem, - - config('workflow.path') - ); - }); - } - - /** - * Register the inflector. - * - * @author Andrea Marco Sartori - * @return void - */ - private function registerInflector() - { - $abstract = 'Cerbero\Workflow\Inflectors\InflectorInterface'; - - $this->app->bind($abstract, function() - { - return new Inflector(new LaravelTraitNamespaceDetector); - }); - } - - /** - * Register the bus dispatcher. - * - * @author Andrea Marco Sartori - * @return void - */ - private function registerDispatcher() - { - $abstract = 'Cerbero\Workflow\Wrappers\DispatcherInterface'; - - $this->app->bind($abstract, function($app) - { - return $app['Cerbero\Workflow\Wrappers\MarshalDispatcher']; - }); - } - - /** - * Register the package main class. - * - * @author Andrea Marco Sartori - * @return void - */ - private function registerWorkflow() - { - $this->app->singleton('cerbero.workflow', function($app) - { - return $app['Cerbero\Workflow\Workflow']; - }); - } - - /** - * Register the hook for the workflow runners. - * - * @author Andrea Marco Sartori - * @return void - */ - private function registerWorkflowRunnersHook() - { - $this->app->afterResolving(function(WorkflowRunner $runner, $app) - { - $runner->setWorkflow($app['cerbero.workflow']); - }); - } - - /** - * Register the console commands. - * - * @author Andrea Marco Sartori - * @return void - */ - private function registerCommands() - { - foreach ($this->commands as $command) - { - $name = ucfirst(last(explode('.', $command))); - - $this->app->singleton($command, function($app) use($name) - { - return $app["Cerbero\Workflow\Console\Commands\\{$name}WorkflowCommand"]; - }); - } - } - +class WorkflowServiceProvider extends ServiceProvider +{ + /** + * @author Andrea Marco Sartori + * + * @var array $commands List of registered commands. + */ + protected $commands = [ + 'cerbero.workflow.create', + 'cerbero.workflow.read', + 'cerbero.workflow.update', + 'cerbero.workflow.delete', + ]; + + /** + * Boot the package up. + * + * @author Andrea Marco Sartori + * + * @return void + */ + public function boot() + { + $this->publishConfig(); + + $this->commands($this->commands); + + $facade = 'Cerbero\Workflow\Facades\Workflow'; + + AliasLoader::getInstance()->alias('Workflow', $facade); + } + + /** + * Publish the configuration file. + * + * @author Andrea Marco Sartori + * + * @return void + */ + private function publishConfig() + { + $config = __DIR__.'/config/workflow.php'; + + $this->publishes([$config => config_path('workflow.php')]); + + $this->mergeConfigFrom($config, 'workflow'); + } + + /** + * Register the services. + * + * @author Andrea Marco Sartori + * + * @return void + */ + public function register() + { + $this->registerPipelineRepository(); + + $this->registerInflector(); + + $this->registerDispatcher(); + + $this->registerWorkflow(); + + $this->registerWorkflowRunnersHook(); + + $this->registerCommands(); + } + + /** + * Register the pipeline repository. + * + * @author Andrea Marco Sartori + * + * @return void + */ + private function registerPipelineRepository() + { + $abstract = 'Cerbero\Workflow\Repositories\PipelineRepositoryInterface'; + + $this->app->bind($abstract, function ($app) { + return new YamlPipelineRepository( + new SymfonyYamlParser(), + + new \Illuminate\Filesystem\Filesystem(), + + config('workflow.path') + ); + }); + } + + /** + * Register the inflector. + * + * @author Andrea Marco Sartori + * + * @return void + */ + private function registerInflector() + { + $abstract = 'Cerbero\Workflow\Inflectors\InflectorInterface'; + + $this->app->bind($abstract, function () { + return new Inflector(new LaravelTraitNamespaceDetector()); + }); + } + + /** + * Register the bus dispatcher. + * + * @author Andrea Marco Sartori + * + * @return void + */ + private function registerDispatcher() + { + $abstract = 'Cerbero\Workflow\Wrappers\DispatcherInterface'; + + $this->app->bind($abstract, function ($app) { + return $app['Cerbero\Workflow\Wrappers\MarshalDispatcher']; + }); + } + + /** + * Register the package main class. + * + * @author Andrea Marco Sartori + * + * @return void + */ + private function registerWorkflow() + { + $this->app->singleton('cerbero.workflow', function ($app) { + return $app['Cerbero\Workflow\Workflow']; + }); + } + + /** + * Register the hook for the workflow runners. + * + * @author Andrea Marco Sartori + * + * @return void + */ + private function registerWorkflowRunnersHook() + { + $this->app->afterResolving(function (WorkflowRunner $runner, $app) { + $runner->setWorkflow($app['cerbero.workflow']); + }); + } + + /** + * Register the console commands. + * + * @author Andrea Marco Sartori + * + * @return void + */ + private function registerCommands() + { + foreach ($this->commands as $command) { + $name = ucfirst(last(explode('.', $command))); + + $this->app->singleton($command, function ($app) use ($name) { + return $app["Cerbero\Workflow\Console\Commands\\{$name}WorkflowCommand"]; + }); + } + } } diff --git a/src/Wrappers/DispatcherInterface.php b/src/Wrappers/DispatcherInterface.php index 9e4c087..bc325d2 100644 --- a/src/Wrappers/DispatcherInterface.php +++ b/src/Wrappers/DispatcherInterface.php @@ -6,11 +6,11 @@ interface DispatcherInterface { - /** * Set the pipes commands should be piped through before dispatching. * - * @param array $pipes + * @param array $pipes + * * @return $this */ public function pipeThrough(array $pipes); @@ -18,11 +18,11 @@ public function pipeThrough(array $pipes); /** * Marshal a command and dispatch it. * - * @param mixed $command - * @param \ArrayAccess $source - * @param array $extras + * @param mixed $command + * @param \ArrayAccess $source + * @param array $extras + * * @return mixed */ public function dispatchFrom($command, ArrayAccess $source, array $extras = []); - } diff --git a/src/Wrappers/LaravelTraitNamespaceDetector.php b/src/Wrappers/LaravelTraitNamespaceDetector.php index 385fcd9..60fefa6 100644 --- a/src/Wrappers/LaravelTraitNamespaceDetector.php +++ b/src/Wrappers/LaravelTraitNamespaceDetector.php @@ -1,4 +1,6 @@ -getAppNamespace(); +class LaravelTraitNamespaceDetector implements NamespaceDetectorInterface +{ + use AppNamespaceDetectorTrait; - return rtrim($namespace, '\\'); - } + /** + * Detect the namespace used by an application. + * + * @author Andrea Marco Sartori + * + * @return string + */ + public function detect() + { + $namespace = $this->getAppNamespace(); + return rtrim($namespace, '\\'); + } } diff --git a/src/Wrappers/MarshalDispatcher.php b/src/Wrappers/MarshalDispatcher.php index 6ccbfc7..c7b1f6b 100644 --- a/src/Wrappers/MarshalDispatcher.php +++ b/src/Wrappers/MarshalDispatcher.php @@ -2,11 +2,11 @@ namespace Cerbero\Workflow\Wrappers; -use Exception; use ArrayAccess; +use Exception; +use Illuminate\Contracts\Bus\Dispatcher; use ReflectionClass; use ReflectionParameter; -use Illuminate\Contracts\Bus\Dispatcher; /** * Wrapper to marshal commands before dispatching them. @@ -15,73 +15,82 @@ */ class MarshalDispatcher implements DispatcherInterface { + /** + * @author Andrea Marco Sartori + * + * @var Illuminate\Contracts\Bus\Dispatcher $dispatcher Bus dispatcher. + */ + protected $dispatcher; + + /** + * @author Andrea Marco Sartori + * + * @var string Command to dispatch + */ + protected $command; - /** - * @author Andrea Marco Sartori - * @var Illuminate\Contracts\Bus\Dispatcher $dispatcher Bus dispatcher. - */ - protected $dispatcher; - - /** - * @author Andrea Marco Sartori - * @var string $command Command to dispatch - */ - protected $command; - - /** - * @author Andrea Marco Sartori - * @var \ArrayAccess $values Parameters values - */ - protected $values; - - /** - * Set the dependencies. - * - * @author Andrea Marco Sartori - * @param Illuminate\Contracts\Bus\Dispatcher $dispatcher - * @return void - */ - public function __construct(Dispatcher $dispatcher) - { - $this->dispatcher = $dispatcher; - } - - /** + /** + * @author Andrea Marco Sartori + * + * @var \ArrayAccess Parameters values + */ + protected $values; + + /** + * Set the dependencies. + * + * @author Andrea Marco Sartori + * + * @param Illuminate\Contracts\Bus\Dispatcher $dispatcher + * + * @return void + */ + public function __construct(Dispatcher $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + /** * Set the pipes commands should be piped through before dispatching. * - * @author Andrea Marco Sartori - * @param array $pipes + * @author Andrea Marco Sartori + * + * @param array $pipes + * * @return $this */ public function pipeThrough(array $pipes) { - $this->dispatcher->pipeThrough($pipes); + $this->dispatcher->pipeThrough($pipes); - return $this; + return $this; } /** * Marshal a command and dispatch it. * - * @author Andrea Marco Sartori - * @param mixed $command - * @param \ArrayAccess $source - * @param array $extras + * @author Andrea Marco Sartori + * + * @param mixed $command + * @param \ArrayAccess $source + * @param array $extras + * * @return mixed */ public function dispatchFrom($command, ArrayAccess $source, array $extras = []) { - $this->command = $command; + $this->command = $command; - $this->values = array_merge((array) $source, $extras); + $this->values = array_merge((array) $source, $extras); - return $this->dispatcher->dispatch($this->marshal()); + return $this->dispatcher->dispatch($this->marshal()); } /** * Marshal the command to dispatch. * - * @author Andrea Marco Sartori + * @author Andrea Marco Sartori + * * @return mixed */ protected function marshal() @@ -99,38 +108,37 @@ protected function marshal() * Retrieve the arguments to inject into the command constructor. * * @author Andrea Marco Sartori - * @param array $parameters - * @return array + * + * @param array $parameters + * + * @return array */ protected function getParamsToInject(array $parameters) { - return array_map(function ($parameter) - { + return array_map(function ($parameter) { return $this->grabParameter($parameter); - }, $parameters); } /** * Get a parameter value for a marshaled command. * - * @author Andrea Marco Sartori - * @param \ReflectionParameter $parameter + * @author Andrea Marco Sartori + * + * @param \ReflectionParameter $parameter + * * @return mixed */ protected function grabParameter(ReflectionParameter $parameter) { - if (isset($this->values[$parameter->name])) - { + if (isset($this->values[$parameter->name])) { return $this->values[$parameter->name]; } - if ($parameter->isDefaultValueAvailable()) - { + if ($parameter->isDefaultValueAvailable()) { return $parameter->getDefaultValue(); } throw new Exception("Unable to map parameter [{$parameter->name}] to command [{$this->command}]"); } - } diff --git a/src/Wrappers/NamespaceDetectorInterface.php b/src/Wrappers/NamespaceDetectorInterface.php index 84c16d0..c611155 100644 --- a/src/Wrappers/NamespaceDetectorInterface.php +++ b/src/Wrappers/NamespaceDetectorInterface.php @@ -1,18 +1,20 @@ -getModule($module); - } - - /** - * Run an Artisan command. - * - * @author Andrea Marco Sartori - * @param string $command - * @return void - */ - public function runArtisan($command) - { - $this->filesystem->amInPath(base_path()); - - $this->cli->runShellCommand("php artisan {$command}"); - } - - /** - * Check if the content of a generated job is equal to the given stub. - * - * @author Andrea Marco Sartori - * @param string $job - * @param string $stub - * @return void - */ - public function seeInJob($job, $stub) - { - $file = "Jobs/{$job}.php"; - - $this->seeStubInFile($file, $stub); - } - - /** - * Check if the content of a generated request is equal to the given stub. - * - * @author Andrea Marco Sartori - * @param string $request - * @param string $stub - * @return void - */ - public function seeInRequest($request, $stub) - { - $file = "Http/Requests/{$request}.php"; - - $this->seeStubInFile($file, $stub); - } - - /** - * Check if the content of a generated pipe is equal to the given stub. - * - * @author Andrea Marco Sartori - * @param string $pipe - * @param string $stub - * @param string $path - * @return void - */ - public function seeInPipe($pipe, $stub, $path = 'Workflows') - { - $file = "{$path}/{$pipe}.php"; - - $this->seeStubInFile($file, $stub); - } - - /** - * Check if the content of the generated workflows list is equal to the given stub. - * - * @author Andrea Marco Sartori - * @param string $stub - * @param string $path - * @return void - */ - public function seeInWorkflows($stub, $path = 'Workflows') - { - $file = "{$path}/workflows.yml"; - - $this->seeStubInFile($file, $stub); - } - - /** - * Check if the content of a file is equal to the given stub. - * - * @author Andrea Marco Sartori - * @param string $file - * @param string $stub - * @return void - */ - public function seeStubInFile($file, $stub) - { - $I = $this->filesystem; - - $I->openFile(app_path($file)); - - $content = $this->getContentOfStub($stub); - - $I->seeFileContentsEqual($content); - } - - /** - * Retrieve the content of a stub. - * - * @author Andrea Marco Sartori - * @param string $stub - * @return string - */ - protected function getContentOfStub($stub) - { - $path = __DIR__ . "/stubs/{$stub}"; - - return file_get_contents($path); - } - - /** - * Remove all the generated files for a given workflow. - * - * @author Andrea Marco Sartori - * @param string $workflow - * @param string $path - * @return void - */ - public function clearWorkflow($workflow, $path = "Workflows") - { - $this->deleteDirIfExists($path); - - $this->deleteFileIfExists("Jobs/{$workflow}Job.php"); - - $this->deleteFileIfExists("Http/Requests/{$workflow}Request.php"); - } - - /** - * Delete a directory if exists. - * - * @author Andrea Marco Sartori - * @param string $path - * @return void - */ - protected function deleteDirIfExists($path) - { - if(file_exists($dir = app_path($path))) - { - $this->filesystem->deleteDir($dir); - } - } - - /** - * Delete a file if exists. - * - * @author Andrea Marco Sartori - * @param string $path - * @return void - */ - protected function deleteFileIfExists($path) - { - if(file_exists($file = app_path($path))) - { - $this->filesystem->deleteFile($file); - } - } - - /** - * Assert a given request does not exist. - * - * @author Andrea Marco Sartori - * @param string $request - * @return void - */ - public function dontSeeRequest($request) - { - $file = app_path("Http/Requests/{$request}.php"); - - $this->filesystem->dontSeeFileFound($file); - } - - /** - * Assert a given pipe does exist. - * - * @author Andrea Marco Sartori - * @param string $pipe - * @param string $path - * @return void - */ - public function seePipe($pipe, $path = 'Workflows') - { - $file = app_path("{$path}/{$pipe}.php"); - - $this->filesystem->seeFileFound($file); - } - - /** - * Assert a given pipe does not exist. - * - * @author Andrea Marco Sartori - * @param string $pipe - * @param string $path - * @return void - */ - public function dontSeePipe($pipe, $path = 'Workflows') - { - $file = app_path("{$path}/{$pipe}.php"); - - $this->filesystem->dontSeeFileFound($file); - } - - /** - * Assert a given job does exist. - * - * @author Andrea Marco Sartori - * @param string $job - * @param string $path - * @return void - */ - public function seeJob($job, $path = 'Jobs') - { - $file = app_path("{$path}/{$job}.php"); - - $this->filesystem->seeFileFound($file); - } - - /** - * Assert a given job does not exist. - * - * @author Andrea Marco Sartori - * @param string $job - * @param string $path - * @return void - */ - public function dontSeeJob($job, $path = 'Jobs') - { - $file = app_path("{$path}/{$job}.php"); - - $this->filesystem->dontSeeFileFound($file); - } - - /** - * Assert a given request does exist. - * - * @author Andrea Marco Sartori - * @param string $request - * @param string $path - * @return void - */ - public function seeRequest($request, $path = 'Http/Requests') - { - $file = app_path("{$path}/{$request}.php"); - - $this->filesystem->seeFileFound($file); - } - - /** - * Check if a drawing is identical to a given stub. - * - * @author Andrea Marco Sartori - * @param string $stub - * @return void - */ - public function seeDrawingIs($stub) - { - $content = $this->getContentOfStub("Drawings/$stub"); - - $this->cli->seeInShellOutput($content); - } - +class FunctionalHelper extends \Codeception\Module +{ + /** + * Dynamically get modules. + * + * @author Andrea Marco Sartori + * + * @param string $name + * + * @return mixed + */ + public function __get($name) + { + $module = ucfirst($name); + + return $this->getModule($module); + } + + /** + * Run an Artisan command. + * + * @author Andrea Marco Sartori + * + * @param string $command + * + * @return void + */ + public function runArtisan($command) + { + $this->filesystem->amInPath(base_path()); + + $this->cli->runShellCommand("php artisan {$command}"); + } + + /** + * Check if the content of a generated job is equal to the given stub. + * + * @author Andrea Marco Sartori + * + * @param string $job + * @param string $stub + * + * @return void + */ + public function seeInJob($job, $stub) + { + $file = "Jobs/{$job}.php"; + + $this->seeStubInFile($file, $stub); + } + + /** + * Check if the content of a generated request is equal to the given stub. + * + * @author Andrea Marco Sartori + * + * @param string $request + * @param string $stub + * + * @return void + */ + public function seeInRequest($request, $stub) + { + $file = "Http/Requests/{$request}.php"; + + $this->seeStubInFile($file, $stub); + } + + /** + * Check if the content of a generated pipe is equal to the given stub. + * + * @author Andrea Marco Sartori + * + * @param string $pipe + * @param string $stub + * @param string $path + * + * @return void + */ + public function seeInPipe($pipe, $stub, $path = 'Workflows') + { + $file = "{$path}/{$pipe}.php"; + + $this->seeStubInFile($file, $stub); + } + + /** + * Check if the content of the generated workflows list is equal to the given stub. + * + * @author Andrea Marco Sartori + * + * @param string $stub + * @param string $path + * + * @return void + */ + public function seeInWorkflows($stub, $path = 'Workflows') + { + $file = "{$path}/workflows.yml"; + + $this->seeStubInFile($file, $stub); + } + + /** + * Check if the content of a file is equal to the given stub. + * + * @author Andrea Marco Sartori + * + * @param string $file + * @param string $stub + * + * @return void + */ + public function seeStubInFile($file, $stub) + { + $I = $this->filesystem; + + $I->openFile(app_path($file)); + + $content = $this->getContentOfStub($stub); + + $I->seeFileContentsEqual($content); + } + + /** + * Retrieve the content of a stub. + * + * @author Andrea Marco Sartori + * + * @param string $stub + * + * @return string + */ + protected function getContentOfStub($stub) + { + $path = __DIR__."/stubs/{$stub}"; + + return file_get_contents($path); + } + + /** + * Remove all the generated files for a given workflow. + * + * @author Andrea Marco Sartori + * + * @param string $workflow + * @param string $path + * + * @return void + */ + public function clearWorkflow($workflow, $path = 'Workflows') + { + $this->deleteDirIfExists($path); + + $this->deleteFileIfExists("Jobs/{$workflow}Job.php"); + + $this->deleteFileIfExists("Http/Requests/{$workflow}Request.php"); + } + + /** + * Delete a directory if exists. + * + * @author Andrea Marco Sartori + * + * @param string $path + * + * @return void + */ + protected function deleteDirIfExists($path) + { + if (file_exists($dir = app_path($path))) { + $this->filesystem->deleteDir($dir); + } + } + + /** + * Delete a file if exists. + * + * @author Andrea Marco Sartori + * + * @param string $path + * + * @return void + */ + protected function deleteFileIfExists($path) + { + if (file_exists($file = app_path($path))) { + $this->filesystem->deleteFile($file); + } + } + + /** + * Assert a given request does not exist. + * + * @author Andrea Marco Sartori + * + * @param string $request + * + * @return void + */ + public function dontSeeRequest($request) + { + $file = app_path("Http/Requests/{$request}.php"); + + $this->filesystem->dontSeeFileFound($file); + } + + /** + * Assert a given pipe does exist. + * + * @author Andrea Marco Sartori + * + * @param string $pipe + * @param string $path + * + * @return void + */ + public function seePipe($pipe, $path = 'Workflows') + { + $file = app_path("{$path}/{$pipe}.php"); + + $this->filesystem->seeFileFound($file); + } + + /** + * Assert a given pipe does not exist. + * + * @author Andrea Marco Sartori + * + * @param string $pipe + * @param string $path + * + * @return void + */ + public function dontSeePipe($pipe, $path = 'Workflows') + { + $file = app_path("{$path}/{$pipe}.php"); + + $this->filesystem->dontSeeFileFound($file); + } + + /** + * Assert a given job does exist. + * + * @author Andrea Marco Sartori + * + * @param string $job + * @param string $path + * + * @return void + */ + public function seeJob($job, $path = 'Jobs') + { + $file = app_path("{$path}/{$job}.php"); + + $this->filesystem->seeFileFound($file); + } + + /** + * Assert a given job does not exist. + * + * @author Andrea Marco Sartori + * + * @param string $job + * @param string $path + * + * @return void + */ + public function dontSeeJob($job, $path = 'Jobs') + { + $file = app_path("{$path}/{$job}.php"); + + $this->filesystem->dontSeeFileFound($file); + } + + /** + * Assert a given request does exist. + * + * @author Andrea Marco Sartori + * + * @param string $request + * @param string $path + * + * @return void + */ + public function seeRequest($request, $path = 'Http/Requests') + { + $file = app_path("{$path}/{$request}.php"); + + $this->filesystem->seeFileFound($file); + } + + /** + * Check if a drawing is identical to a given stub. + * + * @author Andrea Marco Sartori + * + * @param string $stub + * + * @return void + */ + public function seeDrawingIs($stub) + { + $content = $this->getContentOfStub("Drawings/$stub"); + + $this->cli->seeInShellOutput($content); + } } diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index 8f9d5f2..0251435 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -2,7 +2,8 @@ /** - * Inherited Methods + * Inherited Methods. + * * @method void wantToTest($text) * @method void wantTo($text) * @method void execute($callable) @@ -15,12 +16,12 @@ * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null) * * @SuppressWarnings(PHPMD) -*/ + */ class FunctionalTester extends \Codeception\Actor { use _generated\FunctionalTesterActions; - /** + /* * Define custom actions here */ } diff --git a/tests/_support/UnitHelper.php b/tests/_support/UnitHelper.php index dcbc192..b836982 100644 --- a/tests/_support/UnitHelper.php +++ b/tests/_support/UnitHelper.php @@ -1,4 +1,5 @@ * ``` * - * @param string $name the name of the request header + * @param string $name the name of the request header * @param string $value the value to set it to for subsequent - * requests + * requests + * * @see \Codeception\Module\PhpBrowser::setHeader() */ - public function setHeader($name, $value) { + public function setHeader($name, $value) + { return $this->getScenario()->runStep(new \Codeception\Step\Action('setHeader', func_get_args())); } - /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -56,15 +57,16 @@ public function setHeader($name, $value) { * $I->amOnPage('some-other-page.php'); * ?> * ``` - * + * * @param string $name the name of the header to delete. + * * @see \Codeception\Module\PhpBrowser::deleteHeader() */ - public function deleteHeader($name) { + public function deleteHeader($name) + { return $this->getScenario()->runStep(new \Codeception\Step\Action('deleteHeader', func_get_args())); } - /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -72,13 +74,14 @@ public function deleteHeader($name) { * * @param $username * @param $password + * * @see \Codeception\Module\PhpBrowser::amHttpAuthenticated() */ - public function amHttpAuthenticated($username, $password) { + public function amHttpAuthenticated($username, $password) + { return $this->getScenario()->runStep(new \Codeception\Step\Condition('amHttpAuthenticated', func_get_args())); } - /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -90,13 +93,14 @@ public function amHttpAuthenticated($username, $password) { * $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart * ?> * ``` + * * @see \Codeception\Module\PhpBrowser::amOnUrl() */ - public function amOnUrl($url) { + public function amOnUrl($url) + { return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnUrl', func_get_args())); } - /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -118,13 +122,14 @@ public function amOnUrl($url) { * @param $subdomain * * @return mixed + * * @see \Codeception\Module\PhpBrowser::amOnSubdomain() */ - public function amOnSubdomain($subdomain) { + public function amOnSubdomain($subdomain) + { return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnSubdomain', func_get_args())); } - /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -145,13 +150,14 @@ public function amOnSubdomain($subdomain) { * If Codeception lacks important Guzzle Client methods, implement them and submit patches. * * @param callable $function + * * @see \Codeception\Module\PhpBrowser::executeInGuzzle() */ - public function executeInGuzzle($function) { + public function executeInGuzzle($function) + { return $this->getScenario()->runStep(new \Codeception\Step\Action('executeInGuzzle', func_get_args())); } - /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -166,13 +172,14 @@ public function executeInGuzzle($function) { * ``` * * @param $page + * * @see \Codeception\Lib\InnerBrowser::amOnPage() */ - public function amOnPage($page) { + public function amOnPage($page) + { return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnPage', func_get_args())); } - /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -205,19 +212,20 @@ public function amOnPage($page) { * * @param $link * @param $context + * * @see \Codeception\Lib\InnerBrowser::click() */ - public function click($link, $context = null) { + public function click($link, $context = null) + { return $this->getScenario()->runStep(new \Codeception\Step\Action('click', func_get_args())); } - /** * [!] Method is generated. Documentation taken from corresponding module. * * Checks that the current page contains the given string (case insensitive). - * - * You can specify a specific HTML element (via CSS or XPath) as the second + * + * You can specify a specific HTML element (via CSS or XPath) as the second * parameter to only search within that element. * * ``` php @@ -226,35 +234,38 @@ public function click($link, $context = null) { * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page * $I->see('Sign Up', '//body/h1'); // with XPath * ``` - * + * * Note that the search is done after stripping all HTML tags from the body, * so `$I->see('strong')` will return true for strings like: - * + * * - `
I am Stronger than thou
` * - `` - * + * * But will *not* be true for strings like: - * + * * - `Home` * - `I am Stronger than thou
` * - `` - * + * * But will *not* be true for strings like: - * + * * - `Home` * - `I am Stronger than thou
` * - `` - * + * * But will ignore strings like: - * + * * - `Home` * - `I am Stronger than thou
` * - `` - * + * * But will ignore strings like: - * + * * - `Home` * - `I am Stronger than thou
` * - `` - * + * * But will *not* be true for strings like: - * + * * - `Home` * - `I am Stronger than thou
` * - `` - * + * * But will *not* be true for strings like: - * + * * - `Home` * - `I am Stronger than thou
` * - `` - * + * * But will ignore strings like: - * + * * - `Home` * - `I am Stronger than thou
` * - `` - * + * * But will ignore strings like: - * + * * - `Home` * - `