From 68bf8a2d26a71d9f3e0a5a9080082a73d02cc88f Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Tue, 13 Dec 2022 15:27:22 +0000 Subject: [PATCH] feat: adds arch related expectations --- composer.json | 1 + src/Expectation.php | 45 ++++++++++++++++++++++-- src/Expectations/OppositeExpectation.php | 44 ++++++++++++++++++++++- src/Mixins/Expectation.php | 4 +++ 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 425ed877..320b58f1 100644 --- a/composer.json +++ b/composer.json @@ -51,6 +51,7 @@ }, "require-dev": { "pestphp/pest-dev-tools": "^2.1.0", + "pestphp/pest-plugin-arch": "^2.0.0", "symfony/process": "^6.2.0" }, "minimum-stability": "dev", diff --git a/src/Expectation.php b/src/Expectation.php index 2da24e75..21e2ee0e 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -6,6 +6,10 @@ namespace Pest; use BadMethodCallException; use Closure; +use Pest\Arch\ArchExpectation; +use Pest\Arch\Expectations\ToDependOn; +use Pest\Arch\Expectations\ToDependOnNothing; +use Pest\Arch\Expectations\ToOnlyDependOn; use Pest\Concerns\Extendable; use Pest\Concerns\Pipeable; use Pest\Concerns\Retrievable; @@ -24,7 +28,7 @@ use PHPUnit\Framework\ExpectationFailedException; * * @template TValue * - * @property Expectation $not Creates the opposite expectation. + * @property OppositeExpectation $not Creates the opposite expectation. * @property EachExpectation $each Creates an expectation on each element on the traversable value. * * @mixin Mixins\Expectation @@ -286,11 +290,15 @@ final class Expectation return new HigherOrderExpectation($this, call_user_func_array($this->value->$method(...), $parameters)); } - ExpectationPipeline::for($this->getExpectationClosure($method)) + $result = ExpectationPipeline::for($this->getExpectationClosure($method)) ->send(...$parameters) ->through($this->pipes($method, $this, Expectation::class)) ->run(); + if ($result !== null) { + return $result; + } + return $this; } @@ -350,4 +358,37 @@ final class Expectation { return new Any(); } + + /** + * Asserts that the layer depends (not exclusively) on the given layers. + * + * @param array|string $targets + * @return ArchExpectation + */ + public function toDependOn(array|string $targets): ArchExpectation + { + return ToDependOn::make($this, $targets); + } + + /** + * Asserts that the layer only depends on the given layers. + * + * @param array|string $targets + * @return ArchExpectation + */ + public function toOnlyDependOn(array|string $targets): ArchExpectation + { + return ToOnlyDependOn::make($this, $targets); + } + + /** + * Asserts that the layer is not allowed to depend on any other layer. + * + * @param array|string $targets + * @return ArchExpectation + */ + public function toDependOnNothing(): ArchExpectation + { + return ToDependOnNothing::make($this); + } } diff --git a/src/Expectations/OppositeExpectation.php b/src/Expectations/OppositeExpectation.php index 9a8fefbe..4780a8a2 100644 --- a/src/Expectations/OppositeExpectation.php +++ b/src/Expectations/OppositeExpectation.php @@ -4,6 +4,10 @@ declare(strict_types=1); namespace Pest\Expectations; +use Pest\Arch\ArchExpectation; +use Pest\Arch\Expectations\ToDependOn; +use Pest\Arch\Expectations\ToDependOnNothing; +use Pest\Arch\Expectations\ToOnlyDependOn; use Pest\Expectation; use Pest\Support\Arr; use PHPUnit\Framework\ExpectationFailedException; @@ -52,6 +56,44 @@ final class OppositeExpectation return $this->original; } + /** + * Asserts that the layer does not depend on the given layers. + * + * @param array|string $targets + * @return ArchExpectation + */ + public function toDependOn(array|string $targets): ArchExpectation + { + return ToDependOn::make($this->original, $targets)->opposite( + fn () => $this->throwExpectationFailedException('toDependOn', $targets), + ); + } + + /** + * Asserts that the layer does not only depends on the given layers. + * + * @param array|string $targets + * @return ArchExpectation + */ + public function toOnlyDependOn(array|string $targets): ArchExpectation + { + return ToOnlyDependOn::make($this->original, $targets)->opposite( + fn () => $this->throwExpectationFailedException('toOnlyDependOn', $targets), + ); + } + + /** + * Asserts that the layer is depends on at least one layer. + * + * @return ArchExpectation + */ + public function toDependOnNothing(): ArchExpectation + { + return ToDependOnNothing::make($this->original)->opposite( + fn () => $this->throwExpectationFailedException('toDependOnNothing'), + ); + } + /** * Handle dynamic method calls into the original expectation. * @@ -91,7 +133,7 @@ final class OppositeExpectation * * @param array $arguments */ - private function throwExpectationFailedException(string $name, array $arguments = []): never + public function throwExpectationFailedException(string $name, array $arguments = []): never { $exporter = new Exporter(); diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index 886ffab2..3c444591 100644 --- a/src/Mixins/Expectation.php +++ b/src/Mixins/Expectation.php @@ -8,6 +8,10 @@ use BadMethodCallException; use Closure; use Error; use InvalidArgumentException; +use Pest\Arch\ArchExpectation; +use Pest\Arch\Expectations\ToDependOn; +use Pest\Arch\Expectations\ToDependOnNothing; +use Pest\Arch\Expectations\ToOnlyDependOn; use Pest\Exceptions\InvalidExpectationValue; use Pest\Matchers\Any; use Pest\Support\Arr;