Closed
Description
Validation in version 1.x return sub errors for keyword oneOf
, but version 2.x return only The data should match exactly one schema
. Keyword anyOf
works correctly with sub errors in both versions. I think both keywords oneOf
and anyOf
should work similarly.
See examples bellow.
Details
Examples for reproduce:
Example to reproduce issue in version 1.1.0
use Opis\JsonSchema\{
Validator, ValidationResult, ValidationError, Schema
};
$dataJson = <<<'JSON'
{
"case1A": "foo"
}
JSON;
$schemaJson = <<<'JSON'
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"oneOf": [
{
"$comment": "Case 1",
"additionalProperties": false,
"properties": {
"case1A": {
"type": "string"
},
"case1B": {
"type": "string"
}
},
"required": [
"case1A",
"case1B"
]
},
{
"$comment": "Case 2",
"additionalProperties": false,
"properties": {
"case2A": {
"type": "string"
},
"case2B": {
"type": "string"
}
},
"required": [
"case2A",
"case2B"
]
},
{
"$comment": "Case 3",
"additionalProperties": false,
"properties": {
"case3A": {
"type": "string"
},
"case3B": {
"type": "string"
}
},
"required": [
"case3A",
"case3B"
]
}
]
}
JSON;
$data = json_decode($dataJson);
$schema = Schema::fromJsonString($schemaJson);
$validator = new Validator();
/** @var ValidationResult $result */
$result = $validator->schemaValidation($data, $schema);
if ($result->isValid()) {
echo '$data is valid', PHP_EOL;
} else {
/** @var ValidationError $error */
$error = $result->getFirstError();
echo '$data is invalid', PHP_EOL;
echo "Error: ", $error->keyword(), PHP_EOL;
echo json_encode($error->keywordArgs(), JSON_PRETTY_PRINT), PHP_EOL;
foreach ($error->subErrors() as $subError) {
echo "Sub Error: ", $subError->keyword(), PHP_EOL;
echo json_encode($subError->keywordArgs(), JSON_PRETTY_PRINT), PHP_EOL;
}
}
Example to reproduce issue in version 2.2.0
use Opis\JsonSchema\{
Validator, ValidationResult, Errors\ErrorFormatter,
};
$dataJson = <<<'JSON'
{
"case1A": "foo"
}
JSON;
$schemaJson = <<<'JSON'
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"oneOf": [
{
"$comment": "Case 1",
"additionalProperties": false,
"properties": {
"case1A": {
"type": "string"
},
"case1B": {
"type": "string"
}
},
"required": [
"case1A",
"case1B"
]
},
{
"$comment": "Case 2",
"additionalProperties": false,
"properties": {
"case2A": {
"type": "string"
},
"case2B": {
"type": "string"
}
},
"required": [
"case2A",
"case2B"
]
},
{
"$comment": "Case 3",
"additionalProperties": false,
"properties": {
"case3A": {
"type": "string"
},
"case3B": {
"type": "string"
}
},
"required": [
"case3A",
"case3B"
]
}
]
}
JSON;
$validator = new Validator();
$data = json_decode($dataJson);
$schema = $validator->loader()->loadObjectSchema(json_decode($schemaJson));
/** @var ValidationResult $result */
$result = $validator->validate($data, $schema);
if ($result->isValid()) {
echo "Valid", PHP_EOL;
} else {
// Print errors
echo "Error: ";
print_r((new ErrorFormatter())->format($result->error()));
foreach ($result->error()->subErrors() as $subError) {
echo "Sub Error: ";
/** @var \Opis\JsonSchema\Errors\ValidationError $subError */
print_r((new ErrorFormatter())->format($subError));
}
}
Output in version 1.1.0:
$data is invalid
Error: oneOf
{
"matched": 0
}
Sub Error: required
{
"missing": "case1B"
}
Sub Error: required
{
"missing": "case2A"
}
Sub Error: required
{
"missing": "case3A"
}
Wrong output without sub errors in version 2.2.0:
Error: Array
(
[/] => Array
(
[0] => The data should match exactly one schema
)
)
If I try it in with anyOf
keyword in version 2.x output is correct:
Example with anyOf in version 2.2.0
use Opis\JsonSchema\{
Validator, ValidationResult, Errors\ErrorFormatter,
};
$dataJson = <<<'JSON'
{
"case1A": "foo"
}
JSON;
$schemaJson = <<<'JSON'
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"anyOf": [
{
"$comment": "Case 1",
"additionalProperties": false,
"properties": {
"case1A": {
"type": "string"
},
"case1B": {
"type": "string"
}
},
"required": [
"case1A",
"case1B"
]
},
{
"$comment": "Case 2",
"additionalProperties": false,
"properties": {
"case2A": {
"type": "string"
},
"case2B": {
"type": "string"
}
},
"required": [
"case2A",
"case2B"
]
},
{
"$comment": "Case 3",
"additionalProperties": false,
"properties": {
"case3A": {
"type": "string"
},
"case3B": {
"type": "string"
}
},
"required": [
"case3A",
"case3B"
]
}
]
}
JSON;
$validator = new Validator();
$data = json_decode($dataJson);
$schema = $validator->loader()->loadObjectSchema(json_decode($schemaJson));
/** @var ValidationResult $result */
$result = $validator->validate($data, $schema);
if ($result->isValid()) {
echo "Valid", PHP_EOL;
} else {
// Print errors
echo "Error: ";
print_r((new ErrorFormatter())->format($result->error()));
foreach ($result->error()->subErrors() as $subError) {
echo "Sub Error: ";
/** @var \Opis\JsonSchema\Errors\ValidationError $subError */
print_r((new ErrorFormatter())->format($subError));
}
}
Output in version 2.2.0 for anyOf
:
Error: Array
(
[/] => Array
(
[0] => The required properties (case1B) are missing
[1] => The required properties (case2A) are missing
[2] => The required properties (case3A) are missing
)
)
Sub Error: Array
(
[/] => Array
(
[0] => The required properties (case1B) are missing
)
)
Sub Error: Array
(
[/] => Array
(
[0] => The required properties (case2A) are missing
)
)
Sub Error: Array
(
[/] => Array
(
[0] => The required properties (case3A) are missing
)
)
Metadata
Metadata
Assignees
Labels
No labels