From 9a66bf6ca3453892b923e536a96ce020092e5d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Mon, 21 Mar 2022 10:57:43 +0100 Subject: [PATCH] Enhancement: Implement Specification::anyOf() --- CHANGELOG.md | 12 ++++++++--- README.md | 18 +++++++++++++++++ infection.json | 2 +- src/Specification.php | 13 ++++++++++++ test/Unit/SpecificationTest.php | 35 +++++++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adbbebc4..3eba370d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased -For a full diff see [`2.1.0...main`][2.1.0...main]. +For a full diff see [`3.0.0...main`][3.0.0...main]. + +## [`3.0.0`][3.0.0] + +For a full diff see [`2.1.0...3.0.0`][2.1.0...3.0.0]. ## Added - Added `Specification` ([#50]), by [@localheinz] +- Added `Specification::anyOf()` ([#53]), by [@localheinz] ## Removed @@ -61,7 +66,8 @@ For a full diff see [`a5ba52c...1.0.0`][a5ba52c...1.0.0]. [a5ba52c...1.0.0]: https://github.com/ergebnis/json-pointer/compare/a5ba52c...1.0.0 [1.0.0...main]: https://github.com/ergebnis/json-pointer/compare/1.0.0...main [2.0.0...2.1.0]: https://github.com/ergebnis/json-pointer/compare/2.0.0...2.1.0 -[2.1.0...main]: https://github.com/ergebnis/json-pointer/compare/2.1.0...main +[2.1.0...3.0.0]: https://github.com/ergebnis/json-pointer/compare/2.1.0...3.0.0 +[3.0.0...main]: https://github.com/ergebnis/json-pointer/compare/3.0.0...main [#1]: https://github.com/ergebnis/json-pointer/pull/1 [#2]: https://github.com/ergebnis/json-pointer/pull/2 @@ -71,6 +77,6 @@ For a full diff see [`a5ba52c...1.0.0`][a5ba52c...1.0.0]. [#9]: https://github.com/ergebnis/json-pointer/pull/9 [#17]: https://github.com/ergebnis/json-pointer/pull/17 [#48]: https://github.com/ergebnis/json-pointer/pull/48 -[#50]: https://github.com/ergebnis/json-pointer/pull/50 +[#53]: https://github.com/ergebnis/json-pointer/pull/53 [@localheinz]: https://github.com/localheinz diff --git a/README.md b/README.md index e9032416..16cf5166 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,24 @@ $specification->isSatisfiedBy(Pointer\JsonPointer::fromJsonString('/foo')); $specification->isSatisfiedBy(Pointer\JsonPointer::fromJsonString('/foo/bar')); // true ``` +You can compose `Specification`s to find out if a `JsonPointer` satisfies any of them: + +```php +isSatisfiedBy(Pointer\JsonPointer::fromJsonString('/foo')); // false +$specification->isSatisfiedBy(Pointer\JsonPointer::fromJsonString('/foo/bar')); // true +$specification->isSatisfiedBy(Pointer\JsonPointer::fromJsonString('/foo/baz')); // true +``` ## Changelog Please have a look at [`CHANGELOG.md`](CHANGELOG.md). diff --git a/infection.json b/infection.json index 142833e1..270faa2f 100644 --- a/infection.json +++ b/infection.json @@ -4,7 +4,7 @@ "text": ".build/infection/infection-log.txt" }, "minCoveredMsi": 100, - "minMsi": 92, + "minMsi": 94, "phpUnit": { "configDir": "test\/Unit" }, diff --git a/src/Specification.php b/src/Specification.php index 59c6c154..3394a304 100644 --- a/src/Specification.php +++ b/src/Specification.php @@ -35,6 +35,19 @@ public function isSatisfiedBy(JsonPointer $jsonPointer): bool return $closure($jsonPointer); } + public static function anyOf(self ...$specifications): self + { + return new self(static function (JsonPointer $jsonPointer) use ($specifications): bool { + foreach ($specifications as $specification) { + if ($specification->isSatisfiedBy($jsonPointer)) { + return true; + } + } + + return false; + }); + } + public static function equals(JsonPointer $other): self { return new self(static function (JsonPointer $jsonPointer) use ($other) { diff --git a/test/Unit/SpecificationTest.php b/test/Unit/SpecificationTest.php index b9f9ebd2..375e49db 100644 --- a/test/Unit/SpecificationTest.php +++ b/test/Unit/SpecificationTest.php @@ -51,4 +51,39 @@ public function testEqualsIsSatisifedByJsonPointerWhenJsonPointerEqualsOther(): self::assertTrue($specification->isSatisfiedBy($jsonPointer)); } + + public function testAnyOfIsNotSatisfiedByJsonPointerWhenEmpty(): void + { + $jsonPointer = JsonPointer::fromJsonString('/foo/bar/baz'); + + $specification = Specification::anyOf(); + + self::assertFalse($specification->isSatisfiedBy($jsonPointer)); + } + + public function testAnyOfIsNotSatisfiedByJsonPointerWhenNoneOfTheSpecificationsAreSatisfiedByJsonPointer(): void + { + $jsonPointer = JsonPointer::fromJsonString('/foo/bar/baz'); + + $specification = Specification::anyOf( + Specification::equals(JsonPointer::fromJsonString('/foo/bar')), + Specification::equals(JsonPointer::fromJsonString('/foo/baz')), + Specification::equals(JsonPointer::fromJsonString('/foo/qux')), + ); + + self::assertFalse($specification->isSatisfiedBy($jsonPointer)); + } + + public function testAnyOfIsNotSatisfiedByJsonPointerWhenAnyOfTheSpecificationsIsSatisfiedByJsonPointer(): void + { + $jsonPointer = JsonPointer::fromJsonString('/foo/baz'); + + $specification = Specification::anyOf( + Specification::equals(JsonPointer::fromJsonString('/foo/bar')), + Specification::equals(JsonPointer::fromJsonString('/foo/baz')), + Specification::equals(JsonPointer::fromJsonString('/foo/qux')), + ); + + self::assertTrue($specification->isSatisfiedBy($jsonPointer)); + } }