diff --git a/src/json-schema.hpp b/src/json-schema.hpp index df088da..3bd319a 100644 --- a/src/json-schema.hpp +++ b/src/json-schema.hpp @@ -150,6 +150,7 @@ class JSON_SCHEMA_VALIDATOR_API json_validator public: json_validator(schema_loader = nullptr, format_checker = nullptr); json_validator(json_validator &&); + json_validator(const json &, schema_loader = nullptr, format_checker = nullptr); ~json_validator(); json_validator &operator=(json_validator &&); diff --git a/src/json-validator.cpp b/src/json-validator.cpp index 8f6526b..b28d326 100644 --- a/src/json-validator.cpp +++ b/src/json-validator.cpp @@ -1123,6 +1123,12 @@ json_validator::json_validator(schema_loader loader, { } +json_validator::json_validator(const json &schema, schema_loader loader, format_checker format) + : json_validator(loader, format) +{ + set_root_schema(schema); +} + // move constructor, destructor and move assignment operator can be defaulted here // where root_schema is a complete type json_validator::json_validator(json_validator &&) = default; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b0ef6f5..5c0d805 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,3 +30,7 @@ add_test(NAME errors COMMAND errors) add_executable(issue-70 issue-70.cpp) target_link_libraries(issue-70 json-schema-validator) add_test(NAME issue-70 COMMAND issue-70) + +add_executable(issue-70-root-schema-constructor issue-70-root-schema-constructor.cpp) +target_link_libraries(issue-70-root-schema-constructor json-schema-validator) +add_test(NAME issue-70-root-schema-constructor COMMAND issue-70-root-schema-constructor) diff --git a/test/issue-70-root-schema-constructor.cpp b/test/issue-70-root-schema-constructor.cpp new file mode 100644 index 0000000..02dc94f --- /dev/null +++ b/test/issue-70-root-schema-constructor.cpp @@ -0,0 +1,123 @@ +#include + +#include + +static int error_count; + +#define EXPECT_EQ(a, b) \ + do { \ + if (a != b) { \ + std::cerr << "Failed: '" << a << "' != '" << b << "'\n"; \ + error_count++; \ + } \ + } while (0) + +using nlohmann::json; +using nlohmann::json_schema::json_validator; + +namespace +{ + +// The schema is defined based upon a string literal +static json person_schema = R"( +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A person", + "properties": { + "name": { + "description": "Name", + "type": "string" + }, + "age": { + "description": "Age of the person", + "type": "number", + "minimum": 2, + "maximum": 200 + }, + "phones": { + "type": "array", + "items": { + "type": "number" + } + } + }, + "required": [ + "name", + "age" + ], + "additionalProperties": false, + "type": "object" +})"_json; + +class store_ptr_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_pointers.push_back(ptr); + } + +public: + std::vector failed_pointers; + + void reset() override + { + nlohmann::json_schema::basic_error_handler::reset(); + failed_pointers.clear(); + } +}; + +} // namespace + +static json_validator validator(person_schema); + +int main(void) +{ + store_ptr_err_handler err; + + validator.validate({{"age", 42}, {"name", "John"}}, err); // OK + EXPECT_EQ(err.failed_pointers.size(), 0); + err.reset(); + + validator.validate({{"age", 42}}, err); // no name + + EXPECT_EQ(err.failed_pointers.size(), 1); + EXPECT_EQ(err.failed_pointers[0].to_string(), ""); + err.reset(); + + validator.validate({{"street", "Boulevard"}}, err); // no name and no age + EXPECT_EQ(err.failed_pointers.size(), 3); + EXPECT_EQ(err.failed_pointers[0].to_string(), ""); + EXPECT_EQ(err.failed_pointers[1].to_string(), ""); + EXPECT_EQ(err.failed_pointers[2].to_string(), ""); + err.reset(); + + validator.validate({{"age", 42}, {"name", 12}}, err); // name must be a string + EXPECT_EQ(err.failed_pointers.size(), 1); + EXPECT_EQ(err.failed_pointers[0].to_string(), "/name"); + err.reset(); + + validator.validate({ + {"age", 42}, + {"name", "John"}, + {"phones", {1234, "223"}}, + }, + err); // name must be a string + EXPECT_EQ(err.failed_pointers.size(), 1); + EXPECT_EQ(err.failed_pointers[0].to_string(), "/phones/1"); + err.reset(); + + validator.validate({ + {"age", 42}, + {"name", "John"}, + {"phones", {0}}, + {"post-code", 12345}, + }, + err); // name must be a string + EXPECT_EQ(err.failed_pointers.size(), 1); + EXPECT_EQ(err.failed_pointers[0].to_string(), ""); + err.reset(); + + return error_count; +}