First implementation of sub-schema-validation on request.
#149 and #135
This commit is contained in:
parent
b4733c50c1
commit
89ed13d76b
@ -102,7 +102,7 @@ namespace nlohmann
|
|||||||
namespace json_schema
|
namespace json_schema
|
||||||
{
|
{
|
||||||
|
|
||||||
class root_schema : public schema
|
class root_schema
|
||||||
{
|
{
|
||||||
schema_loader loader_;
|
schema_loader loader_;
|
||||||
format_checker format_check_;
|
format_checker format_check_;
|
||||||
@ -133,8 +133,7 @@ public:
|
|||||||
format_checker &&format,
|
format_checker &&format,
|
||||||
content_checker &&content)
|
content_checker &&content)
|
||||||
|
|
||||||
: schema(this),
|
: loader_(std::move(loader)),
|
||||||
loader_(std::move(loader)),
|
|
||||||
format_check_(std::move(format)),
|
format_check_(std::move(format)),
|
||||||
content_check_(std::move(content))
|
content_check_(std::move(content))
|
||||||
{
|
{
|
||||||
@ -280,22 +279,31 @@ public:
|
|||||||
"' has still undefined references.");
|
"' has still undefined references.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
|
void validate(const json::json_pointer &ptr,
|
||||||
|
const json &instance,
|
||||||
|
json_patch &patch,
|
||||||
|
error_handler &e,
|
||||||
|
const json_uri &initial) const
|
||||||
{
|
{
|
||||||
if (root_)
|
if (!root_) {
|
||||||
root_->validate(ptr, instance, patch, e);
|
|
||||||
else
|
|
||||||
e.error(ptr, "", "no root schema has yet been set for validating an instance");
|
e.error(ptr, "", "no root schema has yet been set for validating an instance");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const json &defaultValue(const json::json_pointer &ptr, const json &instance, error_handler &e) const override
|
auto file_entry = files_.find(initial.location());
|
||||||
{
|
if (file_entry == files_.end()) {
|
||||||
if (root_)
|
e.error(ptr, "", "no file found serving requested root-URI. " + initial.location());
|
||||||
return root_->defaultValue(ptr, instance, e);
|
return;
|
||||||
else
|
}
|
||||||
e.error(ptr, "", "no root schema has yet been set for validating an instance");
|
|
||||||
|
|
||||||
return EmptyDefault;
|
auto &file = file_entry->second;
|
||||||
|
auto sch = file.schemas.find(initial.fragment());
|
||||||
|
if (sch == file.schemas.end()) {
|
||||||
|
e.error(ptr, "", "no schema find for request initial URI: " + initial.to_string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sch->second->validate(ptr, instance, patch, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1356,11 +1364,11 @@ json json_validator::validate(const json &instance) const
|
|||||||
return validate(instance, err);
|
return validate(instance, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
json json_validator::validate(const json &instance, error_handler &err) const
|
json json_validator::validate(const json &instance, error_handler &err, const json_uri &initial_uri) const
|
||||||
{
|
{
|
||||||
json::json_pointer ptr;
|
json::json_pointer ptr;
|
||||||
json_patch patch;
|
json_patch patch;
|
||||||
root_->validate(ptr, instance, patch, err);
|
root_->validate(ptr, instance, patch, err, initial_uri);
|
||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -189,7 +189,7 @@ public:
|
|||||||
json validate(const json &) const;
|
json validate(const json &) const;
|
||||||
|
|
||||||
// validate a json-document based on the root-schema with a custom error-handler
|
// validate a json-document based on the root-schema with a custom error-handler
|
||||||
json validate(const json &, error_handler &) const;
|
json validate(const json &, error_handler &, const json_uri &initial_uri = json_uri("#")) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace json_schema
|
} // namespace json_schema
|
||||||
|
|||||||
@ -65,3 +65,7 @@ add_executable(binary-validation binary-validation.cpp)
|
|||||||
target_include_directories(binary-validation PRIVATE ${PROJECT_SOURCE_DIR}/src)
|
target_include_directories(binary-validation PRIVATE ${PROJECT_SOURCE_DIR}/src)
|
||||||
target_link_libraries(binary-validation PRIVATE nlohmann_json_schema_validator)
|
target_link_libraries(binary-validation PRIVATE nlohmann_json_schema_validator)
|
||||||
add_test(NAME binary-validation COMMAND binary-validation)
|
add_test(NAME binary-validation COMMAND binary-validation)
|
||||||
|
|
||||||
|
add_executable(issue-149-entry-selection issue-149-entry-selection.cpp)
|
||||||
|
target_link_libraries(issue-149-entry-selection PRIVATE nlohmann_json_schema_validator)
|
||||||
|
add_test(NAME issue-149-entry-selection COMMAND issue-149-entry-selection)
|
||||||
|
|||||||
93
test/issue-149-entry-selection.cpp
Normal file
93
test/issue-149-entry-selection.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include <nlohmann/json-schema.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using nlohmann::json;
|
||||||
|
using nlohmann::json_uri;
|
||||||
|
using nlohmann::json_schema::json_validator;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
static int error_count;
|
||||||
|
#define EXPECT_EQ(a, b) \
|
||||||
|
do { \
|
||||||
|
if (a != b) { \
|
||||||
|
std::cerr << "Failed: '" << a << "' != '" << b << "'\n"; \
|
||||||
|
error_count++; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
// The schema is defined based upon a string literal
|
||||||
|
static json person_schema = R"(
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"type": "integer",
|
||||||
|
"definitions": {
|
||||||
|
"A": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"$ref": "#/definitions/B"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"B": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"_json;
|
||||||
|
|
||||||
|
class store_err_handler : public nlohmann::json_schema::basic_error_handler
|
||||||
|
{
|
||||||
|
void error(const nlohmann::json::json_pointer &ptr, const json &instance, const std::string &message) override
|
||||||
|
{
|
||||||
|
nlohmann::json_schema::basic_error_handler::error(ptr, instance, message);
|
||||||
|
std::cerr << "ERROR: '" << ptr << "' - '" << instance << "': " << message << "\n";
|
||||||
|
failed.push_back(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::vector<nlohmann::json::json_pointer> failed;
|
||||||
|
|
||||||
|
void reset() override
|
||||||
|
{
|
||||||
|
nlohmann::json_schema::basic_error_handler::reset();
|
||||||
|
failed.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
static json_validator validator(person_schema);
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
store_err_handler err;
|
||||||
|
|
||||||
|
validator.validate(1, err); // OK
|
||||||
|
EXPECT_EQ(err.failed.size(), 0);
|
||||||
|
err.reset();
|
||||||
|
|
||||||
|
validator.validate("1", err); // no name
|
||||||
|
EXPECT_EQ(err.failed.size(), 1);
|
||||||
|
err.reset();
|
||||||
|
|
||||||
|
validator.validate(1, err, json_uri("#/definitions/B"));
|
||||||
|
EXPECT_EQ(err.failed.size(), 0);
|
||||||
|
err.reset();
|
||||||
|
|
||||||
|
validator.validate("1", err, json_uri("#/definitions/B"));
|
||||||
|
EXPECT_EQ(err.failed.size(), 1);
|
||||||
|
err.reset();
|
||||||
|
|
||||||
|
validator.validate({{"b", 1}}, err, json_uri("#/definitions/A"));
|
||||||
|
EXPECT_EQ(err.failed.size(), 0);
|
||||||
|
err.reset();
|
||||||
|
|
||||||
|
validator.validate({{"b", "1"}}, err, json_uri("#/definitions/A"));
|
||||||
|
EXPECT_EQ(err.failed.size(), 1);
|
||||||
|
err.reset();
|
||||||
|
|
||||||
|
return error_count;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user