From 6e59fc9040401a4f673412419821a539198ea957 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Thu, 2 Jan 2025 15:57:00 -0400 Subject: [PATCH] Return found identifiers in `FlatFileSchemaResolver` Signed-off-by: Juan Cruz Viotti --- .../jsontoolkit/jsonschema_resolver.h | 6 ++- src/jsonschema/resolver.cc | 4 +- .../jsonschema_flat_file_resolver_test.cc | 40 +++++++++++++------ 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_resolver.h b/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_resolver.h index df40ed640..6bc3951f9 100644 --- a/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_resolver.h +++ b/src/jsonschema/include/sourcemeta/jsontoolkit/jsonschema_resolver.h @@ -121,10 +121,12 @@ class SOURCEMETA_JSONTOOLKIT_JSONSCHEMA_EXPORT FlatFileSchemaResolver { /// Construct an empty resolver that has another schema resolver as a fallback FlatFileSchemaResolver(const SchemaResolver &resolver); - /// Register a schema to the flat file resolver + /// Register a schema to the flat file resolver, returning the detected + /// identifier for the schema auto add(const std::filesystem::path &path, const std::optional &default_dialect = std::nullopt, - const std::optional &default_id = std::nullopt) -> void; + const std::optional &default_id = std::nullopt) + -> const std::string &; /// Attempt to resolve a schema auto operator()(std::string_view identifier) const -> std::optional; diff --git a/src/jsonschema/resolver.cc b/src/jsonschema/resolver.cc index 3e18a8bc7..d19207ddb 100644 --- a/src/jsonschema/resolver.cc +++ b/src/jsonschema/resolver.cc @@ -82,7 +82,7 @@ FlatFileSchemaResolver::FlatFileSchemaResolver(const SchemaResolver &resolver) auto FlatFileSchemaResolver::add( const std::filesystem::path &path, const std::optional &default_dialect, - const std::optional &default_id) -> void { + const std::optional &default_id) -> const std::string & { const auto canonical{std::filesystem::canonical(path)}; const auto schema{sourcemeta::jsontoolkit::from_file(canonical)}; assert(sourcemeta::jsontoolkit::is_schema(schema)); @@ -103,6 +103,8 @@ auto FlatFileSchemaResolver::add( << identifier.value(); throw SchemaError(error.str()); } + + return result.first->first; } auto FlatFileSchemaResolver::operator()(std::string_view identifier) const diff --git a/test/jsonschema/jsonschema_flat_file_resolver_test.cc b/test/jsonschema/jsonschema_flat_file_resolver_test.cc index 18872c752..f303666d7 100644 --- a/test/jsonschema/jsonschema_flat_file_resolver_test.cc +++ b/test/jsonschema/jsonschema_flat_file_resolver_test.cc @@ -22,7 +22,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema) { sourcemeta::jsontoolkit::FlatFileSchemaResolver resolver; const auto schema_path{std::filesystem::path{SCHEMAS_PATH} / "2020-12-id.json"}; - resolver.add(schema_path); + const auto &identifier{resolver.add(schema_path)}; + EXPECT_EQ(identifier, "https://www.sourcemeta.com/2020-12-id.json"); EXPECT_TRUE( resolver("https://www.sourcemeta.com/2020-12-id.json").has_value()); EXPECT_EQ(resolver("https://www.sourcemeta.com/2020-12-id.json").value(), @@ -39,8 +40,9 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema_with_default_dialect) { "$schema": "https://json-schema.org/draft/2020-12/schema" })JSON"); - resolver.add(schema_path, "https://json-schema.org/draft/2020-12/schema"); - + const auto &identifier{resolver.add( + schema_path, "https://json-schema.org/draft/2020-12/schema")}; + EXPECT_EQ(identifier, "https://www.sourcemeta.com/only-id.json"); EXPECT_TRUE(resolver("https://www.sourcemeta.com/only-id.json").has_value()); EXPECT_EQ(resolver("https://www.sourcemeta.com/only-id.json").value(), expected); @@ -57,8 +59,9 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema_anonymous_with_default) { "$schema": "https://json-schema.org/draft/2020-12/schema" })JSON"); - resolver.add(schema_path, std::nullopt, "https://www.sourcemeta.com/test"); - + const auto &identifier{resolver.add(schema_path, std::nullopt, + "https://www.sourcemeta.com/test")}; + EXPECT_EQ(identifier, "https://www.sourcemeta.com/test"); EXPECT_TRUE(resolver("https://www.sourcemeta.com/test").has_value()); EXPECT_EQ(resolver("https://www.sourcemeta.com/test").value(), expected); } @@ -68,9 +71,13 @@ TEST(JSONSchema_FlatFileSchemaResolver, single_schema_idempotent) { const auto schema_path{std::filesystem::path{SCHEMAS_PATH} / "2020-12-id.json"}; - resolver.add(schema_path); - resolver.add(schema_path); - resolver.add(schema_path); + const auto &identifier_1{resolver.add(schema_path)}; + const auto &identifier_2{resolver.add(schema_path)}; + const auto &identifier_3{resolver.add(schema_path)}; + + EXPECT_EQ(identifier_1, "https://www.sourcemeta.com/2020-12-id.json"); + EXPECT_EQ(identifier_2, "https://www.sourcemeta.com/2020-12-id.json"); + EXPECT_EQ(identifier_3, "https://www.sourcemeta.com/2020-12-id.json"); EXPECT_TRUE( resolver("https://www.sourcemeta.com/2020-12-id.json").has_value()); @@ -86,7 +93,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, duplicate_ids) { const auto schema_path_2{std::filesystem::path{SCHEMAS_PATH} / "2020-12-id-duplicate.json"}; - resolver.add(schema_path_1); + const auto &identifier{resolver.add(schema_path_1)}; + EXPECT_EQ(identifier, "https://www.sourcemeta.com/2020-12-id.json"); EXPECT_THROW(resolver.add(schema_path_2), sourcemeta::jsontoolkit::SchemaError); } @@ -96,7 +104,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, no_embedded_resource) { const auto schema_path{std::filesystem::path{SCHEMAS_PATH} / "2020-12-embedded.json"}; - resolver.add(schema_path); + const auto &identifier{resolver.add(schema_path)}; + EXPECT_EQ(identifier, "https://www.sourcemeta.com/2020-12-embedded.json"); EXPECT_TRUE( resolver("https://www.sourcemeta.com/2020-12-embedded.json").has_value()); @@ -113,7 +122,9 @@ TEST(JSONSchema_FlatFileSchemaResolver, metaschema_out_of_order) { const auto metaschema_path{std::filesystem::path{SCHEMAS_PATH} / "2020-12-meta-1.json"}; - resolver.add(schema_path); + const auto &identifier{resolver.add(schema_path)}; + EXPECT_EQ(identifier, + "https://www.sourcemeta.com/2020-12-meta-1-schema.json"); // We can't resolve it yet until eventually satisfying the metaschema EXPECT_THROW( @@ -121,7 +132,9 @@ TEST(JSONSchema_FlatFileSchemaResolver, metaschema_out_of_order) { sourcemeta::jsontoolkit::SchemaResolutionError); // Note we add the metaschema AFTER the schema - resolver.add(metaschema_path); + const auto &metaschema_identifier{resolver.add(metaschema_path)}; + EXPECT_EQ(metaschema_identifier, + "https://www.sourcemeta.com/2020-12-meta-1.json"); EXPECT_TRUE( resolver("https://www.sourcemeta.com/2020-12-meta-1.json").has_value()); @@ -139,7 +152,8 @@ TEST(JSONSchema_FlatFileSchemaResolver, iterators) { sourcemeta::jsontoolkit::FlatFileSchemaResolver resolver; const auto schema_path{std::filesystem::path{SCHEMAS_PATH} / "2020-12-id.json"}; - resolver.add(schema_path); + const auto &identifier{resolver.add(schema_path)}; + EXPECT_EQ(identifier, "https://www.sourcemeta.com/2020-12-id.json"); std::vector identifiers; std::vector entries;