diff --git a/src/Constraint/JsonValueMatchesManyDeep.php b/src/Constraint/JsonValueMatchesManyDeep.php new file mode 100644 index 0000000..ce2a133 --- /dev/null +++ b/src/Constraint/JsonValueMatchesManyDeep.php @@ -0,0 +1,90 @@ + $constraint) { + if (is_array($constraint)) { + $constraint = new JsonValueMatchesManyDeep($constraint); + } elseif (!$constraint instanceof Constraint) { + $constraint = new IsEqual($constraint); + } + + $this->constraints[] = new JsonValueMatches($key, $constraint); + } + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString(): string + { + return implode( + ' and ', + array_map( + function (Constraint $constraint) { + return $constraint->toString(); + }, + $this->constraints + ) + ); + } + + /** + * @inheritdoc + */ + protected function matches($other): bool + { + foreach ($this->constraints as $constraint) { + if (!$constraint->evaluate($other, '', true)) { + return false; + } + } + return true; + } + + /** + * Returns a string representation of matches that evaluate to false. + * + * @return string + */ + protected function additionalFailureDescription($other): string + { + /** @var string[] */ + $failedConstraints = array(); + + foreach ($this->constraints as $constraint) { + if (!$constraint->evaluate($other, '', true)) { + $failedConstraints[] = $constraint->toString(); + } + } + + return "\n" . implode("\n", $failedConstraints); + } +} diff --git a/src/JsonAssertions.php b/src/JsonAssertions.php index 0cf3692..5454b8d 100644 --- a/src/JsonAssertions.php +++ b/src/JsonAssertions.php @@ -3,6 +3,7 @@ use Helmich\JsonAssert\Constraint\JsonValueMatches; use Helmich\JsonAssert\Constraint\JsonValueMatchesMany; +use Helmich\JsonAssert\Constraint\JsonValueMatchesManyDeep; use Helmich\JsonAssert\Constraint\JsonValueMatchesSchema; use PHPUnit\Framework\Assert; use PHPUnit\Framework\Constraint\Constraint; @@ -111,6 +112,22 @@ public static function assertJsonDocumentMatches($jsonDocument, array $constrain Assert::assertThat($jsonDocument, new JsonValueMatchesMany($constraints)); } + /** + * Asserts that a JSON document matches an entire set of constraints, recursively expanding arrays. + * + * @param mixed $jsonDocument A JSON document. If this is a string, it will + * be assumed to be an encoded JSON document + * @param array $constraints A set of constraints. This is a key-value map + * where each key is a JSON path expression, + * associated with a constraint that all values + * matched by that expression must fulfill. + * @return void + */ + public static function assertJsonDocumentMatchesDeep($jsonDocument, array $constraints) + { + Assert::assertThat($jsonDocument, new JsonValueMatchesManyDeep($constraints)); + } + /** * Assert that a JSON document matches a given JSON schema. *