From ff0bca99fda7372e0f54336efca5ed5f90431a1c Mon Sep 17 00:00:00 2001
From: Patrick Boettcher
Date: Fri, 5 Jun 2020 16:25:24 +0200
Subject: [PATCH] errors for logical combination sub-schema are now reported if
validation has failed
---
src/json-validator.cpp | 79 +++++++++++++++++++++++++++++++++---------
1 file changed, 63 insertions(+), 16 deletions(-)
diff --git a/src/json-validator.cpp b/src/json-validator.cpp
index 7f34553..9aff5b7 100644
--- a/src/json-validator.cpp
+++ b/src/json-validator.cpp
@@ -430,29 +430,60 @@ class logical_combination : public schema
{
std::vector> subschemata_;
+ enum validation_state {
+ undecided,
+ valid,
+ invalid
+ };
+
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
{
- size_t count = 0;
+ size_t count = 0, index = 0;
+ std::vector errors;
+
+ validation_state state = undecided;
for (auto &s : subschemata_) {
first_error_handler esub;
- s->validate(ptr, instance, patch, esub);
- if (!esub)
- count++;
- if (is_validate_complete(instance, ptr, e, esub, count))
- return;
+ s->validate(ptr, instance, patch, esub);
+
+ if (!esub) {
+ errors.push_back("combination-sub-schema " + std::to_string(index) + " validated instance.");
+ count++;
+ } else
+ errors.push_back("combination-sub-schema " + std::to_string(index) + " did not validate: " +
+ std::string("At ") + esub.ptr_.to_string() + " of " + esub.instance_.dump() + " - " + esub.message_);
+
+ state = is_validate_complete(instance, ptr, e, esub, count);
+ if (state != undecided)
+ goto done;
+
+ index++;
}
// could accumulate esub details for anyOf and oneOf, but not clear how to select which subschema failure to report
// or how to report multiple such failures
- if (count == 0)
+ if (count == 0) {
+ state = invalid;
e.error(ptr, instance, "no subschema has succeeded, but one of them is required to validate");
+ } else
+ state = valid;
+
+ done:
+ if (state == invalid)
+ for (auto &err : errors)
+ e.error(ptr, instance, " " + err);
}
// specialized for each of the logical_combination_types
static const std::string key;
- static bool is_validate_complete(const json &, const json::json_pointer &, error_handler &, const first_error_handler &, size_t);
+
+ static enum validation_state is_validate_complete(const json &,
+ const json::json_pointer &,
+ error_handler &,
+ const first_error_handler &,
+ size_t);
public:
logical_combination(json &sch,
@@ -477,25 +508,41 @@ template <>
const std::string logical_combination::key = "oneOf";
template <>
-bool logical_combination::is_validate_complete(const json &, const json::json_pointer &, error_handler &e, const first_error_handler &esub, size_t)
+enum logical_combination::validation_state logical_combination::is_validate_complete(const json &,
+ const json::json_pointer &,
+ error_handler &e,
+ const first_error_handler &esub,
+ size_t)
{
- if (esub)
+ if (esub) {
e.error(esub.ptr_, esub.instance_, "at least one subschema has failed, but all of them are required to validate - " + esub.message_);
- return esub;
+ return invalid;
+ }
+ return undecided;
}
template <>
-bool logical_combination::is_validate_complete(const json &, const json::json_pointer &, error_handler &, const first_error_handler &, size_t count)
+enum logical_combination::validation_state logical_combination::is_validate_complete(const json &,
+ const json::json_pointer &,
+ error_handler &,
+ const first_error_handler &,
+ size_t count)
{
- return count == 1;
+ return count == 1 ? valid : undecided;
}
template <>
-bool logical_combination::is_validate_complete(const json &instance, const json::json_pointer &ptr, error_handler &e, const first_error_handler &, size_t count)
+enum logical_combination::validation_state logical_combination::is_validate_complete(const json &instance,
+ const json::json_pointer &ptr,
+ error_handler &e,
+ const first_error_handler &,
+ size_t count)
{
- if (count > 1)
+ if (count > 1) {
e.error(ptr, instance, "more than one subschema has succeeded, but exactly one of them is required to validate");
- return count > 1;
+ return invalid;
+ } else
+ return undecided;
}
class type_schema : public schema