Skip to content

Commit

Permalink
Don't throw exceptions until after checking anyOf / oneOf
Browse files Browse the repository at this point in the history
Fixes #393
  • Loading branch information
erayd committed Mar 17, 2017
1 parent cf8e886 commit e67aa7a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
27 changes: 19 additions & 8 deletions src/JsonSchema/Constraints/UndefinedConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use JsonSchema\ConstraintError;
use JsonSchema\Constraints\TypeCheck\LooseTypeCheck;
use JsonSchema\Entity\JsonPointer;
use JsonSchema\Exception\ValidationException;
use JsonSchema\Uri\UriResolver;

/**
Expand Down Expand Up @@ -245,11 +246,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) {
Expand All @@ -264,12 +270,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));
Expand Down
43 changes: 43 additions & 0 deletions tests/Constraints/OfPropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

namespace JsonSchema\Tests\Constraints;

use JsonSchema\Constraints\Constraint;
use JsonSchema\Validator;

/**
* Class OfPropertiesTest
*/
Expand Down Expand Up @@ -223,4 +226,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": {
"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());
}
}

0 comments on commit e67aa7a

Please sign in to comment.