From 12db9ed6a2f3192522da17b01dd88054b460336f Mon Sep 17 00:00:00 2001 From: Damiano Petrungaro Date: Sat, 25 Nov 2017 20:03:49 +0100 Subject: [PATCH 1/2] Added author prefix to autoloader --- composer.json | 4 ++-- src/Pipelines/Exceptions/MissingImplementException.php | 2 +- src/Pipelines/Interfaces/PipelineInterface.php | 6 ++++-- src/Pipelines/Interfaces/StageInterface.php | 2 +- src/Pipelines/Interfaces/StateInterface.php | 2 +- src/Pipelines/Pipeline.php | 8 ++++---- src/Pipelines/RequestResponseState.php | 7 ++++--- src/Pipelines/SimpleState.php | 6 +++--- tests/Functionals/Pipelines/PipelineTest.php | 8 ++++---- tests/TestCase.php | 8 ++++---- tests/Unit/Pipelines/PipelineTest.php | 10 +++++----- tests/Unit/Pipelines/StateTest.php | 6 +++--- 12 files changed, 36 insertions(+), 33 deletions(-) diff --git a/composer.json b/composer.json index e339b27..e45ce97 100644 --- a/composer.json +++ b/composer.json @@ -12,12 +12,12 @@ "minimum-stability": "stable", "autoload": { "psr-4": { - "Remix\\": "src/" + "AlexManno\\Remix\\": "src/" } }, "autoload-dev": { "psr-4": { - "Tests\\": "tests/" + "AlexManno\\Remix\\Tests\\": "tests/" } }, "require": { diff --git a/src/Pipelines/Exceptions/MissingImplementException.php b/src/Pipelines/Exceptions/MissingImplementException.php index f327af9..d6fda7e 100644 --- a/src/Pipelines/Exceptions/MissingImplementException.php +++ b/src/Pipelines/Exceptions/MissingImplementException.php @@ -1,6 +1,6 @@ prophet = new \Prophecy\Prophet(); + $this->prophet = new Prophet(); } protected function tearDown() diff --git a/tests/Unit/Pipelines/PipelineTest.php b/tests/Unit/Pipelines/PipelineTest.php index 0aeaf4f..83e7d10 100644 --- a/tests/Unit/Pipelines/PipelineTest.php +++ b/tests/Unit/Pipelines/PipelineTest.php @@ -1,11 +1,11 @@ Date: Sat, 25 Nov 2017 20:49:30 +0100 Subject: [PATCH 2/2] Refactored State to Payload, removed empty interface, method names more declerative --- README.md | 37 ++++----- examples/example-00.php | 53 ++++++------- examples/example-01.php | 46 ----------- src/Pipelines/Interfaces/PayloadInterface.php | 18 +++++ .../Interfaces/PipelineInterface.php | 6 +- src/Pipelines/Interfaces/StageInterface.php | 2 +- src/Pipelines/Interfaces/StateInterface.php | 7 -- src/Pipelines/Pipeline.php | 8 +- src/Pipelines/RequestResponseState.php | 79 ------------------- src/Pipelines/SimplePayload.php | 26 ++++++ src/Pipelines/SimpleState.php | 30 ------- tests/Functionals/Pipelines/PipelineTest.php | 51 +++++++----- tests/TestCase.php | 8 +- tests/Unit/Pipelines/PipelineTest.php | 12 +-- tests/Unit/Pipelines/StateTest.php | 51 ------------ 15 files changed, 136 insertions(+), 298 deletions(-) delete mode 100644 examples/example-01.php create mode 100644 src/Pipelines/Interfaces/PayloadInterface.php delete mode 100644 src/Pipelines/Interfaces/StateInterface.php delete mode 100644 src/Pipelines/RequestResponseState.php create mode 100644 src/Pipelines/SimplePayload.php delete mode 100644 src/Pipelines/SimpleState.php delete mode 100644 tests/Unit/Pipelines/StateTest.php diff --git a/README.md b/README.md index 7d05746..b2727a7 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,13 @@ To use this package, use Composer: A Pipeline is a simple SplQueue of Stage. -You can initialize it in this way: `$pipeline = new Remix\Pipelines\Pipeline();` +You can initialize it in this way: `$pipeline = new AlexManno\Remix\Pipelines\Pipeline();` You can add Stage to Pipeline using `$pipeline->pipe($stage)` ### Stage -A Stage is an object that implements `Remix\Pipelines\Interfaces\StageInterface` and has an `__invoke()` method. +A Stage is an object that implements `AlexManno\Remix\Pipelines\Interfaces\StageInterface` and has an `__invoke()` method. This object is the smallest part of the pipeline and it should be a single operation. @@ -48,28 +48,28 @@ You can create a class that implements that interface. Ex. ```php - class MyCoolStage implements Remix\Pipelines\Interfaces\StageInterface + class MyCoolStage implements AlexManno\Remix\Pipelines\Interfaces\StageInterface { /** - * @param State $state + * @param Payload $payload */ - public function __invoke(State $state) + public function __invoke(Payload $payload) { - $state->append('Hello!'); + $payload->setData('Hello!'); - return $state; + return $payload; } } ``` -### State +### Payload -State is an object that implements `StateInterface` and can store any kind of data. +Payload is an object that implements `PayloadInterface` and can store any kind of data. For example in a web application it can store `Request` and `Response`. Ex. ```php -class State implements Remix\Pipelines\Interfaces\StateInterface +class Payload implements Remix\Pipelines\Interfaces\PayloadInterface { /** @var RequestInterface */ public $request; @@ -80,31 +80,32 @@ class State implements Remix\Pipelines\Interfaces\StateInterface ## Compose and run your pipeline -If you have already initialized State object and Stages objects you can compose your pipeline. +If you have already initialized Payload object and Stages objects you can compose your pipeline. Ex. ```php -// -- Initialized objects: $state, $pipeline, $stage1, $stage2 -- +// -- Initialized objects: $payload, $pipeline, $stage1, $stage2 -- -$state = $pipeline +$pipeline ->pipe($stage1) // Add $stage1 to queue - ->pipe($stage2) // Add $stage2 to queue - ->run($state); // Run pipeline: invoke $stage1 and then $stage2 with state from $stage1 + ->pipe($stage2); // Add $stage2 to queue + +$pipeline($payload); // Run pipeline: invoke $stage1 and then $stage2 with payload from $stage1 ``` -You can also compose two or more pipelines togheter using method `add()` +You can also compose two or more pipelines together using method `add()` Ex. ```php -// -- Initialized objects: $state, $pipeline1, $pipeline2, $stage1, $stage2 -- +// -- Initialized objects: $payload, $pipeline1, $pipeline2, $stage1, $stage2 -- $pipeline1->pipe($stage1); // Add $stage1 to $pipeline1 $pipeline2->pipe($stage2); // Add $stage2 to $pipeline2 $pipeline1->add($pipeline2); // Add stages from $pipeline2 -$state = $pipeline1->run($state); // Run pipeline: invoke $stage1 (from $pipeline1) and then $stage2 (from $pipeline2) with state from $stage1 +$payload = $pipeline1($payload); // Run pipeline: invoke $stage1 (from $pipeline1) and then $stage2 (from $pipeline2) with payload from $stage1 ``` diff --git a/examples/example-00.php b/examples/example-00.php index f20de8c..7e2d81d 100644 --- a/examples/example-00.php +++ b/examples/example-00.php @@ -2,54 +2,51 @@ namespace Examples; -use Remix\Pipelines\Interfaces\StageInterface; -use Remix\Pipelines\Pipeline; -use Remix\Pipelines\SimpleState; +use AlexManno\Remix\Pipelines\Interfaces\PayloadInterface; +use AlexManno\Remix\Pipelines\Interfaces\StageInterface; +use AlexManno\Remix\Pipelines\Pipeline; +use AlexManno\Remix\Pipelines\SimplePayload; require_once __DIR__ . '/../vendor/autoload.php'; -class TextState extends SimpleState -{ - - public $data = ''; - - public function append(string $paragraph) - { - $this->data .= $paragraph . " "; - - return $this; - } -} - class SayHello implements StageInterface { /** - * @param TextState $state + * @param PayloadInterface $payload + * + * @return PayloadInterface */ - public function __invoke($state) + public function __invoke(PayloadInterface $payload): PayloadInterface { - return $state->append('Hello!'); + $payload->setData('Hello!'); + + return $payload; } } class SayMyNameIsAlessandro implements StageInterface { /** - * @param TextState $state + * @param PayloadInterface $payload + * + * @return PayloadInterface */ - public function __invoke($state) + public function __invoke(PayloadInterface $payload): PayloadInterface { - return $state->append('My name is Alessandro!'); + $data = $payload->getData(); + $payload->setData($data . ' My name is Alessandro'); + + return $payload; } } $pipeline = new Pipeline(); +$payload = new SimplePayload(); -/** @var TextState $state */ -$state = $pipeline - ->pipe(new SayHello) // Append "Hello!" to TextState - ->pipe(new SayMyNameIsAlessandro) // Append "My name is Alessandro" to TextState - ->run(new TextState); // Pass an initial State +$pipeline + ->pipe(new SayHello) // Append "Hello!" to TextState + ->pipe(new SayMyNameIsAlessandro); // Append "My name is Alessandro" to TextState +$payload = $pipeline($payload); // Pass an initial State -echo $state->get(); // Print: Hello! My name is Alessandro! \ No newline at end of file +echo $payload->getData(); // Print: Hello! My name is Alessandro! diff --git a/examples/example-01.php b/examples/example-01.php deleted file mode 100644 index 578ee91..0000000 --- a/examples/example-01.php +++ /dev/null @@ -1,46 +0,0 @@ -data .= $paragraph . " "; - - return $this; - } -}; - -$sayHello = new class implements StageInterface -{ - public function __invoke($state) - { - return $state->append('Hello!'); - } -}; - -$sayMyNameIsAlessandro = new class implements StageInterface -{ - public function __invoke($state) - { - return $state->append('My name is Alessandro!'); - } -}; - -$pipeline = new Pipeline(); - -$state = $pipeline - ->pipe($sayHello) // Append "Hello!" to TextState - ->pipe($sayMyNameIsAlessandro) // Append "My name is Alessandro" to TextState - ->run($state); // Pass an initial State - -echo $state->get(); // Print: Hello! My name is Alessandro! \ No newline at end of file diff --git a/src/Pipelines/Interfaces/PayloadInterface.php b/src/Pipelines/Interfaces/PayloadInterface.php new file mode 100644 index 0000000..ef6dcb3 --- /dev/null +++ b/src/Pipelines/Interfaces/PayloadInterface.php @@ -0,0 +1,18 @@ +stages->count(); } - public function run(StateInterface $state): StateInterface + public function __invoke(PayloadInterface $payload): PayloadInterface { $this->stages->rewind(); while ($this->stages->valid()) { - $state = $this->stages->current()($state); + $payload = $this->stages->current()($payload); $this->stages->next(); } - return $state; + return $payload; } } diff --git a/src/Pipelines/RequestResponseState.php b/src/Pipelines/RequestResponseState.php deleted file mode 100644 index 8b358bf..0000000 --- a/src/Pipelines/RequestResponseState.php +++ /dev/null @@ -1,79 +0,0 @@ -request = $request; - $this->response = $response; - } - - /** - * @param RequestInterface $request - * @param ResponseInterface $response - * - * @return RequestResponseState - */ - public static function create(RequestInterface $request, ResponseInterface $response): self - { - return new self($request, $response); - } - - /** - * @return RequestInterface - */ - public function getRequest(): RequestInterface - { - return $this->request; - } - - /** - * @param RequestInterface $request - * - * @return RequestResponseState - */ - public function setRequest(RequestInterface $request): self - { - $this->request = $request; - - return $this; - } - - /** - * @return ResponseInterface - */ - public function getResponse(): ResponseInterface - { - return $this->response; - } - - /** - * @param ResponseInterface $response - * - * @return RequestResponseState - */ - public function setResponse(ResponseInterface $response): self - { - $this->response = $response; - - return $this; - } -} diff --git a/src/Pipelines/SimplePayload.php b/src/Pipelines/SimplePayload.php new file mode 100644 index 0000000..e7e111b --- /dev/null +++ b/src/Pipelines/SimplePayload.php @@ -0,0 +1,26 @@ +data; + } + + /** + * {@inheritdoc} + */ + public function setData($data): void + { + $this->data = $data; + } +} diff --git a/src/Pipelines/SimpleState.php b/src/Pipelines/SimpleState.php deleted file mode 100644 index 7422c89..0000000 --- a/src/Pipelines/SimpleState.php +++ /dev/null @@ -1,30 +0,0 @@ -data; - } - - /** - * @param mixed $data - * - * @return SimpleState - */ - public function set($data) - { - $this->data = $data; - - return $this; - } -} diff --git a/tests/Functionals/Pipelines/PipelineTest.php b/tests/Functionals/Pipelines/PipelineTest.php index 9dada4d..92bbe48 100644 --- a/tests/Functionals/Pipelines/PipelineTest.php +++ b/tests/Functionals/Pipelines/PipelineTest.php @@ -2,6 +2,7 @@ namespace AlexManno\Remix\Tests\Functionals\Pipelines; +use AlexManno\Remix\Pipelines\Interfaces\PayloadInterface; use AlexManno\Remix\Pipelines\Interfaces\StageInterface; use AlexManno\Remix\Pipelines\Pipeline; use AlexManno\Remix\Tests\TestCase; @@ -15,14 +16,17 @@ public function testPipeOneStage() $pipeline = new Pipeline(); $pipeline->pipe($addTwo); // Add 2 - $state = $this->createState()->set(2); - $this->assertEquals(4, $pipeline->run($state)->get()); + $payload = $this->createPayload(); + $payload->setData(2); + $this->assertEquals(4, $pipeline($payload)->getData()); - $state = $this->createState()->set(6); - $this->assertEquals(8, $pipeline->run($state)->get()); + $payload = $this->createPayload(); + $payload->setData(6); + $this->assertEquals(8, $pipeline($payload)->getData()); - $state = $this->createState()->set(-2); - $this->assertEquals(0, $pipeline->run($state)->get()); + $payload = $this->createPayload(); + $payload->setData(-2); + $this->assertEquals(0, $pipeline($payload)->getData()); } public function testPipeTwoStage() @@ -35,18 +39,22 @@ public function testPipeTwoStage() ->pipe($addTwo)// Add 2 ->pipe($factorial); // Get factorial - $state = $this->createState()->set(4); // Set state = 4 + $payload = $this->createPayload(); + $payload->setData(4); // Set payload = 4 - $this->assertEquals(720, $pipeline->run($state)->get()); + $this->assertEquals(720, $pipeline($payload)->getData()); } protected function getAddTwoStage() { return - new class() implements StageInterface { - public function __invoke($state) + new class() implements StageInterface + { + public function __invoke(PayloadInterface $payload): PayloadInterface { - return $state->set($state->get() + 2); // Add two + $payload->setData($payload->getData() + 2); // Add two + + return $payload; } }; } @@ -54,21 +62,24 @@ public function __invoke($state) protected function getFactorialStage() { return - new class() implements StageInterface { - public function __invoke($state) + new class() implements StageInterface + { + public function __invoke(PayloadInterface $payload): PayloadInterface { - $number = $state->get(); + $number = $payload->getData(); if ($number < 2) { - return $state->set(1); + $payload->setData(1); + + return $payload; } - return $state->set( - $number * - $this( - $state->set($number - 1) - )->get() + $payload->setData($number - 1); + $payload->setData( + $number * $this($payload)->getData() ); + + return $payload; } }; } diff --git a/tests/TestCase.php b/tests/TestCase.php index 262a921..7d7cc11 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,7 +5,7 @@ use PHPUnit\Framework\TestCase as PHPUnitTestCase; use Prophecy\Prophet; use AlexManno\Remix\Pipelines\Interfaces\StageInterface; -use AlexManno\Remix\Pipelines\SimpleState; +use AlexManno\Remix\Pipelines\SimplePayload; class TestCase extends PHPUnitTestCase { @@ -34,10 +34,10 @@ protected function getStage() } /** - * @return SimpleState + * @return SimplePayload */ - protected function createState(): SimpleState + protected function createPayload(): SimplePayload { - return new SimpleState(); + return new SimplePayload(); } } diff --git a/tests/Unit/Pipelines/PipelineTest.php b/tests/Unit/Pipelines/PipelineTest.php index 83e7d10..579a843 100644 --- a/tests/Unit/Pipelines/PipelineTest.php +++ b/tests/Unit/Pipelines/PipelineTest.php @@ -3,7 +3,7 @@ namespace AlexManno\Remix\Tests\Pipelines\Unit; use AlexManno\Remix\Pipelines\Interfaces\StageInterface; -use AlexManno\Remix\Pipelines\Interfaces\StateInterface; +use AlexManno\Remix\Pipelines\Interfaces\PayloadInterface; use AlexManno\Remix\Pipelines\Pipeline; use AlexManno\Remix\Tests\TestCase; @@ -43,21 +43,21 @@ public function testAdd() public function testRun() { $phropecy = $this->prophesize(); - $phropecy->willImplement(StateInterface::class); + $phropecy->willImplement(PayloadInterface::class); - $state = $phropecy->reveal(); + $payload = $phropecy->reveal(); $phropecy = $this->prophesize(); $phropecy->willImplement(StageInterface::class); - $phropecy->__invoke($state)->willReturn($state); + $phropecy->__invoke($payload)->willReturn($payload); $stage = $phropecy->reveal(); $pipeline = new Pipeline(); $pipeline->pipe($stage); $pipeline->pipe($stage); - $returnState = $pipeline->run($state); + $returnpayload = $pipeline($payload); - $this->assertSame($state, $returnState); + $this->assertSame($payload, $returnpayload); } } diff --git a/tests/Unit/Pipelines/StateTest.php b/tests/Unit/Pipelines/StateTest.php deleted file mode 100644 index e85f670..0000000 --- a/tests/Unit/Pipelines/StateTest.php +++ /dev/null @@ -1,51 +0,0 @@ -prophesize()->willImplement(RequestInterface::class)->reveal(); - $response = $this->prophesize()->willImplement(ResponseInterface::class)->reveal(); - - $state = new RequestResponseState($request, $response); - - $this->assertSame($request, $state->getRequest()); - $this->assertSame($response, $state->getResponse()); - } - - public function testCreate() - { - $request = $this->prophesize()->willImplement(RequestInterface::class)->reveal(); - $response = $this->prophesize()->willImplement(ResponseInterface::class)->reveal(); - - $state = RequestResponseState::create($request, $response); - - $this->assertSame($request, $state->getRequest()); - $this->assertSame($response, $state->getResponse()); - } - - public function testSetters() - { - $request = $this->prophesize()->willImplement(RequestInterface::class)->reveal(); - $request2 = $this->prophesize()->willImplement(RequestInterface::class)->reveal(); - $response = $this->prophesize()->willImplement(ResponseInterface::class)->reveal(); - $response2 = $this->prophesize()->willImplement(ResponseInterface::class)->reveal(); - - $state = new RequestResponseState($request, $response); - - $state->setRequest($request2); - $state->setResponse($response2); - - $this->assertNotSame($request, $state->getRequest()); - $this->assertNotSame($response, $state->getResponse()); - $this->assertSame($request2, $state->getRequest()); - $this->assertSame($response2, $state->getResponse()); - } -}