Skip to content

Commit

Permalink
Account for orphaned anchors in framing
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti committed Feb 7, 2025
1 parent f451b12 commit ec84ea3
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 22 deletions.
22 changes: 12 additions & 10 deletions src/core/jsonschema/frame.cc
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,11 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
const auto bases{
find_nearest_bases(base_uris, entry.common.pointer, entry.id)};

std::vector<sourcemeta::core::PointerTemplate> instance_locations;
if (!entry.common.orphan) {
instance_locations.push_back(entry.common.instance_location);
}

if (bases.first.empty()) {
const auto anchor_uri{sourcemeta::core::URI::from_fragment(name)};
const auto relative_anchor_uri{anchor_uri.recompose()};
Expand All @@ -432,7 +437,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
"", entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(), entry.common.base_dialect.value(),
{entry.common.instance_location});
instance_locations);
}

if (type == AnchorType::Dynamic || type == AnchorType::All) {
Expand All @@ -441,7 +446,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
"", entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(), entry.common.base_dialect.value(),
{entry.common.instance_location});
instance_locations);

// Register a dynamic anchor as a static anchor if possible too
if (entry.common.vocabularies.contains(
Expand All @@ -451,8 +456,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
root_id, "", entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(),
entry.common.base_dialect.value(),
{entry.common.instance_location}, true);
entry.common.base_dialect.value(), instance_locations, true);
}
}
} else {
Expand Down Expand Up @@ -481,8 +485,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
base_string, entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(),
entry.common.base_dialect.value(),
{entry.common.instance_location});
entry.common.base_dialect.value(), instance_locations);
}

if (type == AnchorType::Dynamic || type == AnchorType::All) {
Expand All @@ -491,8 +494,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
base_string, entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(),
entry.common.base_dialect.value(),
{entry.common.instance_location});
entry.common.base_dialect.value(), instance_locations);

// Register a dynamic anchor as a static anchor if possible too
if (entry.common.vocabularies.contains(
Expand All @@ -502,8 +504,8 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
base_string, entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(),
entry.common.base_dialect.value(),
{entry.common.instance_location}, true);
entry.common.base_dialect.value(), instance_locations,
true);
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/jsonschema/jsonschema_frame_2019_09_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1981,7 +1981,7 @@ TEST(JSONSchema_frame_2019_09, relative_base_uri_with_ref) {

// Anchors
EXPECT_FRAME_STATIC_2019_09_ANCHOR(frame, "common#foo", "common",
"/$defs/foo", "common", "/$defs/foo", {""},
"/$defs/foo", "common", "/$defs/foo", {},
0);

// JSON Pointers
Expand Down
10 changes: 5 additions & 5 deletions test/jsonschema/jsonschema_frame_2020_12_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1226,11 +1226,11 @@ TEST(JSONSchema_frame_2020_12,
EXPECT_ANONYMOUS_FRAME_DYNAMIC_ANCHOR(
frame, "#test", "/$defs/test",
"https://json-schema.org/draft/2020-12/schema",
"https://json-schema.org/draft/2020-12/schema", {""}, 0);
"https://json-schema.org/draft/2020-12/schema", {}, 0);
EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR(
frame, "#test", "/$defs/test",
"https://json-schema.org/draft/2020-12/schema",
"https://json-schema.org/draft/2020-12/schema", {""}, 0);
"https://json-schema.org/draft/2020-12/schema", {}, 0);

// Static frames

Expand Down Expand Up @@ -1293,11 +1293,11 @@ TEST(JSONSchema_frame_2020_12, dynamic_ref_to_single_dynamic_anchor_external) {
EXPECT_ANONYMOUS_FRAME_DYNAMIC_ANCHOR(
frame, "#test", "/$defs/test",
"https://json-schema.org/draft/2020-12/schema",
"https://json-schema.org/draft/2020-12/schema", {""}, 0);
"https://json-schema.org/draft/2020-12/schema", {}, 0);
EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR(
frame, "#test", "/$defs/test",
"https://json-schema.org/draft/2020-12/schema",
"https://json-schema.org/draft/2020-12/schema", {""}, 0);
"https://json-schema.org/draft/2020-12/schema", {}, 0);

// Static frames

Expand Down Expand Up @@ -1651,7 +1651,7 @@ TEST(JSONSchema_frame_2020_12, relative_base_uri_with_ref) {

// Anchors
EXPECT_FRAME_STATIC_2020_12_ANCHOR(frame, "common#foo", "common",
"/$defs/foo", "common", "/$defs/foo", {""},
"/$defs/foo", "common", "/$defs/foo", {},
0);

// JSON Pointers
Expand Down
4 changes: 2 additions & 2 deletions test/jsonschema/jsonschema_frame_draft4_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ TEST(JSONSchema_frame_draft4, location_independent_identifier_anonymous) {
EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR(
frame, "#foo", "/definitions/foo",
"http://json-schema.org/draft-04/schema#",
"http://json-schema.org/draft-04/schema#", {""}, 0);
"http://json-schema.org/draft-04/schema#", {}, 0);

// References

Expand Down Expand Up @@ -704,7 +704,7 @@ TEST(JSONSchema_frame_draft4, relative_base_uri_with_ref) {
// Anchors
EXPECT_FRAME_STATIC_DRAFT4_ANCHOR(frame, "common#foo", "common",
"/definitions/foo", "common",
"/definitions/foo", {""}, 0);
"/definitions/foo", {}, 0);

// JSON Pointers

Expand Down
4 changes: 2 additions & 2 deletions test/jsonschema/jsonschema_frame_draft6_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ TEST(JSONSchema_frame_draft6, location_independent_identifier_anonymous) {
EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR(
frame, "#foo", "/definitions/foo",
"http://json-schema.org/draft-06/schema#",
"http://json-schema.org/draft-06/schema#", {""}, 0);
"http://json-schema.org/draft-06/schema#", {}, 0);

// References

Expand Down Expand Up @@ -704,7 +704,7 @@ TEST(JSONSchema_frame_draft6, relative_base_uri_with_ref) {
// Anchors
EXPECT_FRAME_STATIC_DRAFT6_ANCHOR(frame, "common#foo", "common",
"/definitions/foo", "common",
"/definitions/foo", {""}, 0);
"/definitions/foo", {}, 0);

// JSON Pointers

Expand Down
4 changes: 2 additions & 2 deletions test/jsonschema/jsonschema_frame_draft7_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ TEST(JSONSchema_frame_draft7, location_independent_identifier_anonymous) {
EXPECT_ANONYMOUS_FRAME_STATIC_ANCHOR(
frame, "#foo", "/definitions/foo",
"http://json-schema.org/draft-07/schema#",
"http://json-schema.org/draft-07/schema#", {""}, 0);
"http://json-schema.org/draft-07/schema#", {}, 0);

// References

Expand Down Expand Up @@ -704,7 +704,7 @@ TEST(JSONSchema_frame_draft7, relative_base_uri_with_ref) {
// Anchors
EXPECT_FRAME_STATIC_DRAFT7_ANCHOR(frame, "common#foo", "common",
"/definitions/foo", "common",
"/definitions/foo", {""}, 0);
"/definitions/foo", {}, 0);

// JSON Pointers

Expand Down
26 changes: 26 additions & 0 deletions test/jsonschema/jsonschema_official_walker_2020_12_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1698,3 +1698,29 @@ TEST(JSONSchema_official_walker_2020_12, instance_locations_nested) {
EXPECT_OFFICIAL_WALKER_ENTRY_2020_12(
entries, 3, "/additionalProperties/properties/foo/allOf/0", "/~P~/foo");
}

TEST(JSONSchema_official_walker_2020_12, instance_locations_defs_with_ref) {
const sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "common",
"allOf": [ { "$ref": "#foo" } ],
"$defs": {
"foo": {
"$anchor": "foo"
}
}
})JSON");

std::vector<sourcemeta::core::SchemaIteratorEntry> entries;
for (const auto &entry : sourcemeta::core::SchemaIterator(
document, sourcemeta::core::schema_official_walker,
sourcemeta::core::schema_official_resolver)) {
entries.push_back(entry);
}

EXPECT_EQ(entries.size(), 3);

EXPECT_OFFICIAL_WALKER_ENTRY_2020_12(entries, 0, "", "");
EXPECT_OFFICIAL_WALKER_ENTRY_2020_12(entries, 1, "/allOf/0", "");
EXPECT_OFFICIAL_WALKER_ENTRY_2020_12_ORPHAN(entries, 2, "/$defs/foo", "");
}

0 comments on commit ec84ea3

Please sign in to comment.