Prechádzať zdrojové kódy

test/fix: add tests for draft4 and draft6, fix $id vs id

Sam Jaffe 1 rok pred
rodič
commit
fe84c0f776

+ 16 - 13
include/jvalidate/reference_handler.h

@@ -24,8 +24,9 @@ private:
   std::map<detail::RootReference, detail::Reference, std::greater<>> canonical_to_absolute_;
 
 public:
-  ReferenceManager(A const & root, Keywords const & keywords) : roots_{{{}, root}} {
-    prime_impl(root, {}, keywords);
+  ReferenceManager(A const & root, schema::Version version, Keywords const & keywords)
+      : roots_{{{}, root}} {
+    prime_impl(root, {}, version, keywords);
   }
 
   std::optional<A> root(detail::RootReference const & root) const {
@@ -84,18 +85,19 @@ public:
   }
 
   void prime(Adapter auto const & json, detail::RootReference const & where,
-             Keywords const & keywords) {
+             schema::Version version, Keywords const & keywords) {
     canonical_to_absolute_.emplace(where, detail::Reference(where));
-    prime_impl(json, detail::Reference(where), keywords);
+    prime_impl(json, detail::Reference(where), version, keywords);
   }
 
 private:
-  void prime_impl(Adapter auto const & json, detail::Reference where, Keywords const & keywords) {
+  void prime_impl(Adapter auto const & json, detail::Reference where, schema::Version version,
+                  Keywords const & keywords) {
     if (json.type() != adapter::Type::Object) {
       return;
     }
 
-    canonicalize(where, json);
+    canonicalize(where, version, json);
 
     for (auto const & [key, value] : json.as_object()) {
       auto vit = keywords.find(key);
@@ -106,26 +108,27 @@ private:
       if (vit->second.contains(schema::Wraps::Array) && value.type() == adapter::Type::Array) {
         size_t index = 0;
         for (auto const & elem : value.as_array()) {
-          prime_impl(elem, where / key / index, keywords);
+          prime_impl(elem, where / key / index, version, keywords);
           ++index;
         }
       } else if (vit->second.contains(schema::Wraps::Object) &&
                  value.type() == adapter::Type::Object) {
         for (auto const & [prop, elem] : value.as_object()) {
-          prime_impl(elem, where / key / prop, keywords);
+          prime_impl(elem, where / key / prop, version, keywords);
         }
       } else if (vit->second.contains(schema::Wraps::Schema)) {
-        prime_impl(value, where / key, keywords);
+        prime_impl(value, where / key, version, keywords);
       }
     }
   }
 
-  void canonicalize(detail::Reference & where, A const & json) {
+  void canonicalize(detail::Reference & where, schema::Version version, A const & json) {
+    std::string const id = version <= schema::Version::Draft04 ? "id" : "$id";
     auto const schema = json.as_object();
 
     detail::RootReference root = where.root();
-    if (schema.contains("$id")) {
-      root = detail::RootReference(schema["$id"].as_string());
+    if (schema.contains(id)) {
+      root = detail::RootReference(schema[id].as_string());
       if (root.uri().empty()) {
         root = detail::RootReference(where.uri(), root.anchor());
       } else if (root.uri().is_rootless() && not where.uri().empty()) {
@@ -136,7 +139,7 @@ private:
       cache(root, where, json);
     }
 
-    if (not schema.contains("$anchor")) {
+    if (not schema.contains("$anchor") || version < schema::Version::Draft2019_09) {
       return;
     }
 

+ 3 - 2
include/jvalidate/schema.h

@@ -172,7 +172,7 @@ public:
       return;
     }
 
-    ReferenceManager<A> ref(json, factory.keywords(version));
+    ReferenceManager<A> ref(json, version, factory.keywords(version));
     detail::ParserContext<A> root{*this, json, version, factory, external, ref};
     construct(root);
   }
@@ -273,7 +273,8 @@ private:
       return alias(ref, &cache_.try_emplace(ref, error).first->second);
     }
 
-    context.ref.prime(*schema, ref.root(), context.factory.keywords(context.version));
+    context.ref.prime(*schema, ref.root(), context.version,
+                      context.factory.keywords(context.version));
     ref = context.ref.canonicalize(ref, context.where);
     return fetch_schema(context.rebind(ref.pointer().walk(*schema), ref));
   }

+ 2 - 0
tests/selfvalidate_test.cxx

@@ -156,6 +156,8 @@ TEST_P(JsonSchema, TestSuite) {
   }
 }
 
+INSTANTIATE_TEST_SUITE_P(Draft4, JsonSchema, SchemaTests(Version::Draft04), SchemaTestName);
+INSTANTIATE_TEST_SUITE_P(Draft6, JsonSchema, SchemaTests(Version::Draft06), SchemaTestName);
 INSTANTIATE_TEST_SUITE_P(Draft7, JsonSchema, SchemaTests(Version::Draft07), SchemaTestName);
 
 int main(int argc, char ** argv) {