From 55376d32e54ef1d3a3f9016e4cfd97045100544c Mon Sep 17 00:00:00 2001 From: Fabio Ivona Date: Sat, 9 Oct 2021 10:22:24 +0200 Subject: [PATCH] moved decorate implementation to dedicated intercept and pipe calls --- src/Concerns/Extendable.php | 46 +++++++++++++++---- src/Expectation.php | 2 +- src/Support/Extendable.php | 12 ++++- src/Support/Pipeline.php | 4 +- .../{HigherOrder/decorate.php => pipe.php} | 13 ++---- 5 files changed, 54 insertions(+), 23 deletions(-) rename tests/Features/Expect/{HigherOrder/decorate.php => pipe.php} (71%) diff --git a/src/Concerns/Extendable.php b/src/Concerns/Extendable.php index 860f2c4e..389f0cf9 100644 --- a/src/Concerns/Extendable.php +++ b/src/Concerns/Extendable.php @@ -6,6 +6,7 @@ namespace Pest\Concerns; use BadMethodCallException; use Closure; +use Pest\Expectation; /** * @internal @@ -18,7 +19,7 @@ trait Extendable private static $extends = []; /** @var array> */ - private static $decorators = []; + private static $pipes = []; /** * Register a custom extend. @@ -28,9 +29,36 @@ trait Extendable static::$extends[$name] = $extend; } - public static function decorate(string $name, Closure $decorator): void + public static function pipe(string $name, Closure $pipe): void { - static::$decorators[$name][] = $decorator; + self::$pipes[$name][] = $pipe; + } + + /** + * @param string|Closure $filter + */ + public static function intercept(string $name, $filter, Closure $handler): void + { + if (is_string($filter)) { + $filter = function ($value) use ($filter): bool { + return $value instanceof $filter; + }; + } + + //@phpstan-ignore-next-line + self::pipe($name, function (...$arguments) use ($handler, $filter) { + $next = array_pop($arguments); + + //@phpstan-ignore-next-line + if ($filter($this->value)) { + //@phpstan-ignore-next-line + $handler->bindTo($this, get_class($this))(...$arguments); + + return; + } + + $next(...$arguments); + }); } /** @@ -42,24 +70,24 @@ trait Extendable } /** - * Checks if decorator are registered. + * Checks if pipes are registered for a given expectation. */ - public static function hasDecorators(string $name): bool + public static function hasPipes(string $name): bool { - return array_key_exists($name, static::$decorators); + return array_key_exists($name, static::$pipes); } /** * @return array */ - public function decorators(string $name, object $context, string $scope): array + public function pipes(string $name, object $context, string $scope): array { - if (!self::hasDecorators($name)) { + if (!self::hasPipes($name)) { return []; } $decorators = []; - foreach (self::$decorators[$name] as $decorator) { + foreach (self::$pipes[$name] as $decorator) { $decorators[] = $decorator->bindTo($context, $scope); } diff --git a/src/Expectation.php b/src/Expectation.php index aa6b3efc..fbd8af2d 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -261,7 +261,7 @@ final class Expectation } Pipeline::send(...$parameters) - ->through($this->decorators($method, $this, Expectation::class)) + ->through($this->pipes($method, $this, Expectation::class)) ->finally(function ($parameters) use ($method): void { $this->callExpectation($method, $parameters); }); diff --git a/src/Support/Extendable.php b/src/Support/Extendable.php index 341bea02..e62c0e5d 100644 --- a/src/Support/Extendable.php +++ b/src/Support/Extendable.php @@ -31,8 +31,16 @@ final class Extendable $this->extendableClass::extend($name, $extend); } - public function decorate(string $name, Closure $extend): void + public function pipe(string $name, Closure $pipe): void { - $this->extendableClass::decorate($name, $extend); + $this->extendableClass::pipe($name, $pipe); + } + + /** + * @param string|Closure $filter + */ + public function intercept(string $name, $filter, Closure $handler): void + { + $this->extendableClass::intercept($name, $filter, $handler); } } diff --git a/src/Support/Pipeline.php b/src/Support/Pipeline.php index 2fd7121b..4501f278 100644 --- a/src/Support/Pipeline.php +++ b/src/Support/Pipeline.php @@ -55,7 +55,9 @@ final class Pipeline { return function ($stack, $pipe): Closure { return function (...$passable) use ($stack, $pipe) { - return $pipe($stack, ...$passable); + $passable[] = $stack; + + return $pipe(...$passable); }; }; } diff --git a/tests/Features/Expect/HigherOrder/decorate.php b/tests/Features/Expect/pipe.php similarity index 71% rename from tests/Features/Expect/HigherOrder/decorate.php rename to tests/Features/Expect/pipe.php index cb1602f7..e2c6ac98 100644 --- a/tests/Features/Expect/HigherOrder/decorate.php +++ b/tests/Features/Expect/pipe.php @@ -23,7 +23,7 @@ class Character } } -expect()->decorate('toBe', function ($next, $expected) { +expect()->pipe('toBe', function ($expected, $next) { if ($this->value instanceof Character) { assertInstanceOf(Character::class, $expected); assertEquals($this->value->value, $expected->value); @@ -34,15 +34,8 @@ expect()->decorate('toBe', function ($next, $expected) { $next($expected); }); -expect()->decorate('toBe', function ($next, $expected) { - if ($this->value instanceof Number) { - assertInstanceOf(Number::class, $expected); - assertEquals($this->value->value, $expected->value); - - return; - } - - $next($expected); +expect()->intercept('toBe', Number::class, function ($expected) { + assertEquals($this->value->value, $expected->value); }); test('pass', function () {