diff --git a/src/JsonSchema/Constraints/UndefinedConstraint.php b/src/JsonSchema/Constraints/UndefinedConstraint.php index 147e5bc3..171b6893 100644 --- a/src/JsonSchema/Constraints/UndefinedConstraint.php +++ b/src/JsonSchema/Constraints/UndefinedConstraint.php @@ -11,6 +11,7 @@ use JsonSchema\Constraints\TypeCheck\LooseTypeCheck; use JsonSchema\Entity\JsonPointer; +use JsonSchema\Exception\ValidationException; use JsonSchema\Uri\UriResolver; /** @@ -243,11 +244,16 @@ protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i if (isset($schema->anyOf)) { $isValid = false; $startErrors = $this->getErrors(); + $caughtException = null; foreach ($schema->anyOf as $anyOf) { $initErrors = $this->getErrors(); - $this->checkUndefined($value, $anyOf, $path, $i); - if ($isValid = (count($this->getErrors()) == count($initErrors))) { - break; + try { + $this->checkUndefined($value, $anyOf, $path, $i); + if ($isValid = (count($this->getErrors()) == count($initErrors))) { + break; + } + } catch (ValidationException $e) { + $isValid = false; } } if (!$isValid) { @@ -262,12 +268,17 @@ protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i $matchedSchemas = 0; $startErrors = $this->getErrors(); foreach ($schema->oneOf as $oneOf) { - $this->errors = array(); - $this->checkUndefined($value, $oneOf, $path, $i); - if (count($this->getErrors()) == 0) { - $matchedSchemas++; + try { + $this->errors = array(); + $this->checkUndefined($value, $oneOf, $path, $i); + if (count($this->getErrors()) == 0) { + $matchedSchemas++; + } + $allErrors = array_merge($allErrors, array_values($this->getErrors())); + } catch (ValidationException $e) { + // deliberately do nothing here - validation failed, but we want to check + // other schema options in the OneOf field. } - $allErrors = array_merge($allErrors, array_values($this->getErrors())); } if ($matchedSchemas !== 1) { $this->addErrors(array_merge($allErrors, $startErrors)); diff --git a/tests/Constraints/OfPropertiesTest.php b/tests/Constraints/OfPropertiesTest.php index c36ba29e..c6359800 100644 --- a/tests/Constraints/OfPropertiesTest.php +++ b/tests/Constraints/OfPropertiesTest.php @@ -8,6 +8,9 @@ namespace JsonSchema\Tests\Constraints; +use JsonSchema\Constraints\Constraint; +use JsonSchema\Validator; + /** * Class OfPropertiesTest */ @@ -208,4 +211,44 @@ public function getInvalidTests() ) ); } + + public function testNoPrematureAnyOfException() + { + $schema = json_decode('{ + "type": "object", + "properties": { + "propertyOne": { + "anyOf": [ + {"type": "number"}, + {"type": "string"} + ] + } + } + }'); + $data = json_decode('{"propertyOne":"ABC"}'); + + $v = new Validator(); + $v->validate($data, $schema, Constraint::CHECK_MODE_EXCEPTIONS); + $this->assertTrue($v->isValid()); + } + + public function testNoPrematureOneOfException() + { + $schema = json_decode('{ + "type": "object", + "properties": { + "propertyOne": { + "oneOf": [ + {"type": "number"}, + {"type": "string"} + ] + } + } + }'); + $data = json_decode('{"propertyOne":"ABC"}'); + + $v = new Validator(); + $v->validate($data, $schema, Constraint::CHECK_MODE_EXCEPTIONS); + $this->assertTrue($v->isValid()); + } }