diff --git a/doc/ref/corelib/uri.md b/doc/ref/corelib/uri.md index 54ad54e8d..ca78a79b9 100644 --- a/doc/ref/corelib/uri.md +++ b/doc/ref/corelib/uri.md @@ -80,8 +80,8 @@ Returns the decoded fragment part of this URI. jsoncons::string_view encoded_fragment() const noexcept; Returns the encoded fragment part of this URI. - uri resolve(const uri& base) const; -Resolves a uri reference against a base URI. + uri resolve(const uri& reference) const; +Resolve `reference` as a URI relative to this URI. const std::string& string() const; Returns a URI string. diff --git a/include/jsoncons/utility/uri.hpp b/include/jsoncons/utility/uri.hpp index 8bc89d93b..ad08ccb04 100644 --- a/include/jsoncons/utility/uri.hpp +++ b/include/jsoncons/utility/uri.hpp @@ -354,108 +354,113 @@ namespace jsoncons { return string_view(uri_string_.data()+fragment_.first,(fragment_.second-fragment_.first)); } - uri resolve(const uri& base) const + bool has_fragment() const + { + return !encoded_fragment().empty(); + } + + uri resolve(const uri& reference) const { // This implementation uses the psuedo-code given in // http://tools.ietf.org/html/rfc3986#section-5.2.2 - if (is_absolute() && !is_opaque()) + if (reference.is_absolute() && !reference.is_opaque()) { - return *this; + return reference; } - if (is_opaque()) + if (reference.is_opaque()) { - return *this; + return reference; } std::string userinfo, host, port, path, query, fragment; - if (!encoded_authority().empty()) + if (!reference.encoded_authority().empty()) { // g -> http://g - if (!this->encoded_userinfo().empty()) + if (!reference.encoded_userinfo().empty()) { - userinfo = std::string(this->encoded_userinfo()); + userinfo = std::string(reference.encoded_userinfo()); } - if (!this->host().empty()) + if (!reference.host().empty()) { - host = std::string(this->host()); + host = std::string(reference.host()); } - if (!this->port().empty()) + if (!reference.port().empty()) { - port = std::string(this->port()); + port = std::string(reference.port()); } - if (!this->encoded_path().empty()) + if (!reference.encoded_path().empty()) { - path = remove_dot_segments(std::string(this->encoded_path())); + path = remove_dot_segments(std::string(reference.encoded_path())); } - if (!this->encoded_query().empty()) + if (!reference.encoded_query().empty()) { - query = std::string(this->encoded_query()); + query = std::string(reference.encoded_query()); } } else { - if (this->encoded_path().empty()) + if (reference.encoded_path().empty()) { - if (!base.encoded_path().empty()) + if (!encoded_path().empty()) { - path = std::string(base.encoded_path()); + path = std::string(encoded_path()); } - if (!this->encoded_query().empty()) + if (!reference.encoded_query().empty()) { - query = std::string(this->encoded_query()); + query = std::string(reference.encoded_query()); } - else if (!base.encoded_query().empty()) + else if (!encoded_query().empty()) { - query = std::string(base.encoded_query()); + query = std::string(encoded_query()); } } else { - if (this->encoded_path().front() == '/') + if (reference.encoded_path().front() == '/') { - path = remove_dot_segments(std::string(this->encoded_path())); + path = remove_dot_segments(std::string(reference.encoded_path())); } else { - path = merge_paths(base, *this); + path = merge_paths(*this, reference); } - if (!this->encoded_query().empty()) + if (!reference.encoded_query().empty()) { - query = std::string(this->encoded_query()); + query = std::string(reference.encoded_query()); } } - if (!base.encoded_userinfo().empty()) + if (!encoded_userinfo().empty()) { - userinfo = std::string(base.encoded_userinfo()); + userinfo = std::string(encoded_userinfo()); } - if (!base.host().empty()) + if (!this->host().empty()) { - host = std::string(base.host()); + host = std::string(this->host()); } - if (!base.port().empty()) + if (!this->port().empty()) { - port = std::string(base.port()); + port = std::string(this->port()); } } - if (!this->encoded_fragment().empty()) + if (!reference.encoded_fragment().empty()) { - fragment = std::string(this->encoded_fragment()); + fragment = std::string(reference.encoded_fragment()); } - return uri(std::string(base.scheme()), userinfo, host, port, path, query, fragment); + return uri(std::string(scheme()), userinfo, host, port, path, query, fragment); } int compare(const uri& other) const diff --git a/include/jsoncons_ext/jsonschema/common/uri_wrapper.hpp b/include/jsoncons_ext/jsonschema/common/uri_wrapper.hpp index 8cc1a2fab..91f23c34b 100644 --- a/include/jsoncons_ext/jsonschema/common/uri_wrapper.hpp +++ b/include/jsoncons_ext/jsonschema/common/uri_wrapper.hpp @@ -95,11 +95,6 @@ namespace jsonschema { return identifier_; } - uri_wrapper resolve(const uri_wrapper& uri) const - { - return uri.uri_.is_absolute() ? uri_wrapper{uri_.resolve(uri.uri_)} : *this; - } - int compare(const uri_wrapper& other) const { int result = uri_.compare(other.uri_); diff --git a/include/jsoncons_ext/jsonschema/draft201909/schema_builder_201909.hpp b/include/jsoncons_ext/jsonschema/draft201909/schema_builder_201909.hpp index 9c1f62093..4e97654b1 100644 --- a/include/jsoncons_ext/jsonschema/draft201909/schema_builder_201909.hpp +++ b/include/jsoncons_ext/jsonschema/draft201909/schema_builder_201909.hpp @@ -288,19 +288,18 @@ namespace draft201909 { it = sch.find("$ref"); if (it != sch.object_range().end()) // this schema has a reference { - uri_wrapper relative(it->value().template as()); - auto resolved = relative.resolve(uri_wrapper{ context.get_base_uri() }); - validators.push_back(this->get_or_create_reference(sch, resolved)); + uri relative{it->value().template as()}; + auto resolved = context.get_base_uri().resolve(relative); + validators.push_back(this->get_or_create_reference(sch, uri_wrapper{resolved})); } it = sch.find("$recursiveRef"); if (it != sch.object_range().end()) // this schema has a reference { - uri_wrapper relative(it->value().template as()); - auto ref = relative.resolve(uri_wrapper - { context.get_base_uri()}); - auto orig = jsoncons::make_unique(sch, ref.uri().base()); - this->unresolved_refs_.emplace_back(ref.uri(), orig.get()); + uri relative(it->value().template as()); + auto ref = context.get_base_uri().resolve(relative); + auto orig = jsoncons::make_unique(sch, ref.base()); + this->unresolved_refs_.emplace_back(ref, orig.get()); validators.push_back(std::move(orig)); } @@ -500,13 +499,14 @@ namespace draft201909 { auto it = sch.find("$id"); // If $id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { - uri_wrapper relative(it->value().template as()); + uri relative(it->value().template as()); if (relative.has_fragment()) { JSONCONS_THROW(schema_error("Draft 2019-09 does not allow $id with fragment")); } - uri_wrapper new_uri = relative.resolve(uri_wrapper{ parent.get_base_uri() }); - id = new_uri.uri(); + auto resolved = parent.get_base_uri().resolve(relative); + id = resolved; + uri_wrapper new_uri{resolved}; //std::cout << "$id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) diff --git a/include/jsoncons_ext/jsonschema/draft202012/schema_builder_202012.hpp b/include/jsoncons_ext/jsonschema/draft202012/schema_builder_202012.hpp index 8a835a7fe..96b0efc30 100644 --- a/include/jsoncons_ext/jsonschema/draft202012/schema_builder_202012.hpp +++ b/include/jsoncons_ext/jsonschema/draft202012/schema_builder_202012.hpp @@ -288,19 +288,19 @@ namespace draft202012 { it = sch.find("$ref"); if (it != sch.object_range().end()) // this schema has a reference { - uri_wrapper relative(it->value().template as()); - auto ref = relative.resolve(uri_wrapper{ context.get_base_uri() }); - validators.push_back(this->get_or_create_reference(sch, ref)); + uri relative(it->value().template as()); + auto ref = context.get_base_uri().resolve(relative) ; + validators.push_back(this->get_or_create_reference(sch, uri_wrapper(ref))); } it = sch.find("$dynamicRef"); if (it != sch.object_range().end()) // this schema has a reference { std::string value = it->value().template as(); - uri_wrapper relative(value); - auto ref = relative.resolve(uri_wrapper{ context.get_base_uri() }); - auto orig = jsoncons::make_unique(sch, ref.uri().base(), ref); - this->unresolved_refs_.emplace_back(ref.uri(), orig.get()); + uri relative(value); + auto ref = context.get_base_uri().resolve(relative) ; + auto orig = jsoncons::make_unique(sch, ref.base(), uri_wrapper{ref}); + this->unresolved_refs_.emplace_back(ref, orig.get()); validators.push_back(std::move(orig)); } @@ -555,13 +555,14 @@ namespace draft202012 { if (it != sch.object_range().end()) { std::string str = it->value().template as(); - uri_wrapper relative(str); + uri relative(str); if (relative.has_fragment()) { JSONCONS_THROW(schema_error(str + ": Draft 2019-09 does not allow $id with fragment")); } - uri_wrapper new_uri = relative.resolve(uri_wrapper{ parent.get_base_uri() }); - id = new_uri.uri(); + auto resolved = parent.get_base_uri().resolve(relative); + id = resolved; + uri_wrapper new_uri{resolved}; //std::cout << "$id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) diff --git a/include/jsoncons_ext/jsonschema/draft4/schema_builder_4.hpp b/include/jsoncons_ext/jsonschema/draft4/schema_builder_4.hpp index 9ba997db4..0a58cc8fb 100644 --- a/include/jsoncons_ext/jsonschema/draft4/schema_builder_4.hpp +++ b/include/jsoncons_ext/jsonschema/draft4/schema_builder_4.hpp @@ -151,9 +151,9 @@ namespace draft4 { } Json default_value{ jsoncons::null_type() }; - uri_wrapper relative(it->value().template as()); - auto id = relative.resolve(uri_wrapper{ context.get_base_uri() }); - validators.push_back(this->get_or_create_reference(sch, id)); + uri relative(it->value().template as()); + auto id = context.get_base_uri().resolve(relative); + validators.push_back(this->get_or_create_reference(sch, uri_wrapper{id})); schema_validator_ptr = jsoncons::make_unique>( new_context.get_base_uri(), context.id(), std::move(validators), std::move(defs), std::move(default_value)); @@ -386,9 +386,10 @@ namespace draft4 { auto it = sch.find("id"); // If id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { - uri_wrapper relative(it->value().template as()); - uri_wrapper new_uri = relative.resolve(uri_wrapper{ parent.get_base_uri() }); - id = new_uri.uri(); + uri relative(it->value().template as()); + auto resolved = parent.get_base_uri().resolve(relative); + id = resolved; + uri_wrapper new_uri{ resolved }; //std::cout << "id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) diff --git a/include/jsoncons_ext/jsonschema/draft6/schema_builder_6.hpp b/include/jsoncons_ext/jsonschema/draft6/schema_builder_6.hpp index d7fcf85da..1f4b0c6cf 100644 --- a/include/jsoncons_ext/jsonschema/draft6/schema_builder_6.hpp +++ b/include/jsoncons_ext/jsonschema/draft6/schema_builder_6.hpp @@ -162,9 +162,9 @@ namespace draft6 { } Json default_value{ jsoncons::null_type() }; - uri_wrapper relative(it->value().template as()); - auto id = relative.resolve(uri_wrapper{ context.get_base_uri() }); - validators.push_back(this->get_or_create_reference(sch, id)); + uri relative(it->value().template as()); + auto id = context.get_base_uri().resolve(relative) ; + validators.push_back(this->get_or_create_reference(sch, uri_wrapper{id})); schema_validator_ptr = jsoncons::make_unique>( new_context.get_base_uri(), context.id(), std::move(validators), std::move(defs), std::move(default_value)); @@ -338,9 +338,11 @@ namespace draft6 { auto it = sch.find("$id"); // If $id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { - uri_wrapper relative(it->value().template as()); - uri_wrapper new_uri = relative.resolve(uri_wrapper{ parent.get_base_uri() }); - id = new_uri.uri(); + uri relative(it->value().template as()); + auto resolved = parent.get_base_uri().resolve(relative); + id = resolved; + uri_wrapper new_uri{resolved}; + //std::cout << "$id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) diff --git a/include/jsoncons_ext/jsonschema/draft7/schema_builder_7.hpp b/include/jsoncons_ext/jsonschema/draft7/schema_builder_7.hpp index b406d52e3..3fef8c368 100644 --- a/include/jsoncons_ext/jsonschema/draft7/schema_builder_7.hpp +++ b/include/jsoncons_ext/jsonschema/draft7/schema_builder_7.hpp @@ -164,9 +164,9 @@ namespace draft7 { } Json default_value{ jsoncons::null_type() }; - uri_wrapper relative(it->value().template as()); - auto id = relative.resolve(uri_wrapper{ context.get_base_uri() }); - validators.push_back(this->get_or_create_reference(sch, id)); + uri relative(it->value().template as()); + auto id = context.get_base_uri().resolve(relative); + validators.push_back(this->get_or_create_reference(sch, uri_wrapper{id})); schema_validator_ptr = jsoncons::make_unique>( new_context.get_base_uri(), context.id(), std::move(validators), std::move(defs), std::move(default_value)); @@ -371,11 +371,13 @@ namespace draft7 { auto it = sch.find("$id"); // If $id is found, this schema can be referenced by the id if (it != sch.object_range().end()) { - uri_wrapper relative(it->value().template as()); - uri_wrapper new_uri = relative.resolve(uri_wrapper{ parent.get_base_uri() }); - id = new_uri.uri(); + uri relative(it->value().template as()); + auto resolved = parent.get_base_uri().resolve(relative); + id = resolved; //std::cout << "$id: " << id << ", " << new_uri.string() << "\n"; // Add it to the list if it is not already there + + uri_wrapper new_uri{resolved}; if (std::find(new_uris.begin(), new_uris.end(), new_uri) == new_uris.end()) { new_uris.emplace_back(new_uri); diff --git a/test/corelib/src/utility/uri_tests.cpp b/test/corelib/src/utility/uri_tests.cpp index 767af5412..5259339fa 100644 --- a/test/corelib/src/utility/uri_tests.cpp +++ b/test/corelib/src/utility/uri_tests.cpp @@ -137,10 +137,6 @@ TEST_CASE("uri tests (https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) CHECK(uri.encoded_query() == jsoncons::string_view("+CCResolve:cc=uk")); CHECK(uri.encoded_fragment() == jsoncons::string_view("")); CHECK(uri.is_absolute()); - - jsoncons::uri relative("#/defs/bar"); - jsoncons::uri new_uri = relative.resolve(uri); - //std::cout << "new_uri: " << new_uri.string() << "\n"; } } @@ -218,20 +214,20 @@ TEST_CASE("uri base tests") TEST_CASE("uri resolve tests") { - SECTION("empty base") + /*SECTION("empty base") { jsoncons::uri base{ "" }; jsoncons::uri rel{"dir1/other.schema.json"}; jsoncons::uri uri = rel.resolve(base); CHECK(uri.base().string() == "dir1/other.schema.json"); CHECK(uri.path() == "dir1/other.schema.json"); - } + }*/ SECTION("base has no authority and no path") { jsoncons::uri base{ "https" }; jsoncons::uri rel{ "dir1/other.schema.json" }; - jsoncons::uri uri = rel.resolve(base); + jsoncons::uri uri = base.resolve(rel); CHECK(uri.base().string() == "dir1/other.schema.json"); CHECK(uri.path() == "dir1/other.schema.json"); } @@ -240,17 +236,16 @@ TEST_CASE("uri resolve tests") { jsoncons::uri base{ "https://root" }; jsoncons::uri rel{"dir1/other.schema.json"}; - jsoncons::uri uri = rel.resolve(base); + jsoncons::uri uri = base.resolve(rel); CHECK(uri.base().string() == "https://root/dir1/other.schema.json"); CHECK(uri.path() == "/dir1/other.schema.json"); - } - + } SECTION("folder/") { jsoncons::uri base_uri("http://localhost:1234/scope_change_defs2.json"); jsoncons::uri relative_uri("folder/"); - jsoncons::uri uri = relative_uri.resolve(base_uri); + jsoncons::uri uri = base_uri.resolve(relative_uri); CHECK(uri.scheme() == jsoncons::string_view("http")); CHECK(uri.encoded_authority() == jsoncons::string_view("localhost:1234")); @@ -262,12 +257,13 @@ TEST_CASE("uri resolve tests") CHECK(uri.encoded_fragment().empty()); CHECK(uri.is_absolute()); } + SECTION("folderInteger.json") { jsoncons::uri base_uri("http://localhost:1234/folder/"); jsoncons::uri relative_uri("folderInteger.json"); - jsoncons::uri uri = relative_uri.resolve(base_uri); + jsoncons::uri uri = base_uri.resolve(relative_uri); CHECK(uri.scheme() == jsoncons::string_view("http")); CHECK(uri.encoded_authority() == jsoncons::string_view("localhost:1234")); @@ -484,15 +480,14 @@ TEST_CASE("cpp-netib uri resolve tests") SECTION("is_absolute_uri__returns_other") { jsoncons::uri reference{"https://www.example.com/"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("https://www.example.com/" == uri.string()); } - SECTION("base_has_empty_path__path_is_ref_path_1") { jsoncons::uri reference{"g"}; jsoncons::uri base{"http://a/"}; - auto uri = reference.resolve(base); + auto uri = base.resolve(reference); CHECK("http://a/g" == uri.string()); } @@ -500,7 +495,7 @@ TEST_CASE("cpp-netib uri resolve tests") { jsoncons::uri reference{"g/x/y?q=1#s"}; jsoncons::uri base{"http://a/"}; - auto uri = reference.resolve(base); + auto uri = base.resolve(reference); CHECK(uri.encoded_query() == jsoncons::string_view("q=1")); CHECK("http://a/g/x/y?q=1#s" == uri.string()); } @@ -508,194 +503,195 @@ TEST_CASE("cpp-netib uri resolve tests") SECTION("remove_dot_segments1") { jsoncons::uri reference{"./g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g" == uri.string()); } SECTION("base_has_path__path_is_merged_1") { jsoncons::uri reference{"g/"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g/" == uri.string()); } SECTION("base_has_path__path_is_merged_2") { jsoncons::uri reference{"g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g" == uri.string()); } SECTION("path_starts_with_slash__path_is_ref_path") { jsoncons::uri reference{"/g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("path_starts_with_slash_with_query_fragment__path_is_ref_path") { jsoncons::uri reference{ "/g/x?y=z#s" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/g/x?y=z#s" == uri.string()); } SECTION("path_is_empty_but_has_query__returns_base_with_ref_query") { jsoncons::uri reference{ "?y=z" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/d;p?y=z" == uri.string()); } SECTION("path_is_empty_but_has_query_base_no_query__returns_base_with_ref_query") { jsoncons::uri reference{ "?y=z" }; - auto uri = reference.resolve(jsoncons::uri{"http://a/b/c/d"}); + jsoncons::uri base{"http://a/b/c/d"}; + auto uri = base.resolve(reference); CHECK("http://a/b/c/d?y=z" == uri.string()); } SECTION("merge_path_with_query") { jsoncons::uri reference{ "g?y=z" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g?y=z" == uri.string()); } SECTION("append_fragment") { jsoncons::uri reference{ "#s" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/d;p?q#s" == uri.string()); } SECTION("merge_paths_with_fragment") { jsoncons::uri reference{ "g#s" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g#s" == uri.string()); } SECTION("merge_paths_with_query_and_fragment") { jsoncons::uri reference{ "g?y=z#s" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g?y=z#s" == uri.string()); } SECTION("merge_paths_with_semicolon_1") { jsoncons::uri reference{ ";x" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/;x" == uri.string()); } SECTION("merge_paths_with_semicolon_2") { jsoncons::uri reference{ "g;x" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g;x" == uri.string()); } SECTION("merge_paths_with_semicolon_3") { jsoncons::uri reference{ "g;x?y=z#s" }; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g;x?y=z#s" == uri.string()); } SECTION("abnormal_example_1") { jsoncons::uri reference{"../../../g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("abnormal_example_2") { jsoncons::uri reference{"../../../../g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("abnormal_example_3") { jsoncons::uri reference{"/./g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("abnormal_example_4") { jsoncons::uri reference{"/../g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/g" == uri.string()); } SECTION("abnormal_example_5") { jsoncons::uri reference{"g."}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g." == uri.string()); } SECTION("abnormal_example_6") { jsoncons::uri reference{".g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/.g" == uri.string()); } SECTION("abnormal_example_7") { jsoncons::uri reference{"g.."}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g.." == uri.string()); } SECTION("abnormal_example_8") { jsoncons::uri reference{"..g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/g" == uri.string()); } SECTION("abnormal_example_9") { jsoncons::uri reference{"./../g"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/g" == uri.string()); } SECTION("abnormal_example_10") { jsoncons::uri reference{"./g/."}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g/" == uri.string()); } SECTION("abnormal_example_11") { jsoncons::uri reference{"g/./h"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g/h" == uri.string()); } SECTION("abnormal_example_12") { jsoncons::uri reference{"g/../h"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/h" == uri.string()); } SECTION("abnormal_example_13") { jsoncons::uri reference{"g;x=1/./y"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g;x=1/y" == uri.string()); } SECTION("abnormal_example_14") { jsoncons::uri reference{"g;x=1/../y"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/y" == uri.string()); } SECTION("abnormal_example_15") { jsoncons::uri reference{"g?y/./x"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g?y/./x" == uri.string()); } SECTION("abnormal_example_16") { jsoncons::uri reference{"g?y/../x"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g?y/../x" == uri.string()); } SECTION("abnormal_example_17") { jsoncons::uri reference{"g#s/./x"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g#s/./x" == uri.string()); } SECTION("abnormal_example_18") { jsoncons::uri reference{"g#s/../x"}; - auto uri = reference.resolve(base_uri); + auto uri = base_uri.resolve(reference); CHECK("http://a/b/c/g#s/../x" == uri.string()); } }