From 49131a8713862727fea3f6a6149b98aeaac0c998 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Wed, 27 Nov 2019 13:48:54 +0100 Subject: [PATCH] fix #75: unknown keywords may contain sub-schemas Now when an unknown keyword appears and its value is an object, sub-unknown-keywords are inserted as possible sub-schemas. --- src/json-validator.cpp | 9 +++++++-- test/issue-75/CMakeLists.txt | 3 +++ test/issue-75/TypeId.json | 10 ++++++++++ test/issue-75/instance.json | 1 + test/issue-75/schema.json | 6 ++++++ 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/issue-75/CMakeLists.txt create mode 100644 test/issue-75/TypeId.json create mode 100644 test/issue-75/instance.json create mode 100644 test/issue-75/schema.json diff --git a/src/json-validator.cpp b/src/json-validator.cpp index c321dfa..680d63a 100644 --- a/src/json-validator.cpp +++ b/src/json-validator.cpp @@ -130,7 +130,7 @@ public: { auto &file = get_or_create_file(uri.location()); auto new_uri = uri.append(key); - auto fragment = new_uri.fragment(); + auto fragment = new_uri.pointer(); // is there a reference looking for this unknown-keyword, which is thus no longer a unknown keyword but a schema auto unresolved = file.unresolved.find(fragment); @@ -138,6 +138,11 @@ public: schema::make(value, this, {}, {{new_uri}}); else // no, nothing ref'd it, keep for later file.unknown_keywords[fragment] = value; + + // recursively add possible subschemas of unknown keywords + if (value.type() == json::value_t::object) + for (auto &subsch : value.items()) + insert_unknown_keyword(new_uri, subsch.key(), subsch.value()); } std::shared_ptr get_or_create_ref(const json_uri &uri) @@ -151,7 +156,7 @@ public: // referencing an unknown keyword, turn it into schema try { - auto &subschema = file.unknown_keywords.at(uri.fragment()); + auto &subschema = file.unknown_keywords.at(uri.pointer()); auto s = schema::make(subschema, this, {}, {{uri}}); file.unknown_keywords.erase(uri.fragment()); return s; diff --git a/test/issue-75/CMakeLists.txt b/test/issue-75/CMakeLists.txt new file mode 100644 index 0000000..02639dd --- /dev/null +++ b/test/issue-75/CMakeLists.txt @@ -0,0 +1,3 @@ +add_test_simple_schema(Issue::75 + ${CMAKE_CURRENT_SOURCE_DIR}/schema.json + ${CMAKE_CURRENT_SOURCE_DIR}/instance.json) diff --git a/test/issue-75/TypeId.json b/test/issue-75/TypeId.json new file mode 100644 index 0000000..5e50a0d --- /dev/null +++ b/test/issue-75/TypeId.json @@ -0,0 +1,10 @@ +{ + "data" : { + "TypeId" : { + "type" : "string", + "description" : "POD type of data matching bmf::data::TypeId enum", + "enum" : [ "CHAR", "UCHAR", "SHORT", "USHORT", "INT", "UINT", + "LONG", "ULONG", "FLOAT", "DOUBLE" ] + } + } +} diff --git a/test/issue-75/instance.json b/test/issue-75/instance.json new file mode 100644 index 0000000..585c79a --- /dev/null +++ b/test/issue-75/instance.json @@ -0,0 +1 @@ +["INT", "LONG"] diff --git a/test/issue-75/schema.json b/test/issue-75/schema.json new file mode 100644 index 0000000..d98b507 --- /dev/null +++ b/test/issue-75/schema.json @@ -0,0 +1,6 @@ +{ + "type" : "array", + "items": { + "$ref": "TypeId.json#/data/TypeId" + } +}