diff --git a/src/jse/jse.cpp b/src/jse/jse.cpp index 78c86a2..8a17315 100644 --- a/src/jse/jse.cpp +++ b/src/jse/jse.cpp @@ -100,13 +100,31 @@ namespace jse enriched.push_back(rule); } // if the rule is an include, expand the node with a copy of the included file + // include an embedded rule + else if (embedded_rules.find(rule.at("spec_file")) != embedded_rules.end()) + { + json embed_include_rules = embedded_rules[rule.at("spec_file")]; + // loop over all rules to add the prefix + for (auto &i_rule : embed_include_rules) + { + string prefix = rule.at("pointer"); + string pointer = i_rule.at("pointer"); + string new_pointer = prepend_pointer(pointer, prefix); + i_rule.at("pointer") = new_pointer; + } + + // save modified rules + for (const auto &i_rule : embed_include_rules) + enriched.push_back(i_rule); + } + // include an rule from a file else { bool replaced = false; // the include file could be in any of the include directories + string spec_file = rule.at("spec_file"); for (const auto &dir : dirs) { - string spec_file = rule.at("spec_file"); string f = dir + "/" + spec_file; // check if the file exists if (std::filesystem::is_regular_file(f)) @@ -367,7 +385,7 @@ namespace jse { assert(rule.at("type") == "float"); - if (!input.is_number() && !input.is_null()) + if (!input.is_number()) return false; if (rule.contains("min") && input < rule["min"]) @@ -383,7 +401,7 @@ namespace jse { assert(rule.at("type") == "int"); - if (!input.is_number_integer() && !input.is_null()) + if (!input.is_number_integer()) return false; if (rule.contains("min") && input < rule["min"]) diff --git a/src/jse/jse.h b/src/jse/jse.h index 4dccfa2..350cd62 100644 --- a/src/jse/jse.h +++ b/src/jse/jse.h @@ -36,6 +36,9 @@ namespace jse // additional directories which can be used for relative paths std::vector include_directories; + // additional rules that can be used + std::unordered_map embedded_rules; + // automatic boxing for primitive types // if all rules fail for a basic type, try boxing it once and try again bool boxing_primitive = true; diff --git a/tests/test_validator.cpp b/tests/test_validator.cpp index beb7ed6..04193d7 100644 --- a/tests/test_validator.cpp +++ b/tests/test_validator.cpp @@ -250,6 +250,7 @@ TEST_CASE("include_rule", "[validator]") REQUIRE(new_rules == matching); } + TEST_CASE("file_01", "[validator]") { std::ifstream ifs1(root_path + "/input_01.json"); @@ -610,49 +611,3 @@ TEST_CASE("polymorphism", "[inject]") INFO(return_json); REQUIRE(return_json == output); } - -TEST_CASE("null_as_nan", "[validator][inject]") -{ - nlohmann::json rules = R"( - [ - { - "pointer": "/", - "type": "object", - "required": ["f1"], - "optional": ["f2"] - }, - { - "pointer": "/f1", - "type": "float" - }, - { - "pointer": "/f2", - "type": "int", - "default": null - } - ] - )"_json; - - nlohmann::json input = R"( - { - "f1": null, - "f2": null - } - )"_json; - - JSE jse; - jse.strict = true; - - bool r = jse.verify_json(input, rules); - REQUIRE(r); - - input.erase("f2"); - r = jse.verify_json(input, rules); - REQUIRE(r); - - const json return_json = jse.inject_defaults(input, rules); - CHECK(return_json["f1"].is_null()); - CHECK(return_json["f2"].is_null()); - - input["f2"] = std::nan(""); -} \ No newline at end of file