From 3df804c1282c17afe899d97280be0812daed707c Mon Sep 17 00:00:00 2001 From: Steve Hanson Date: Wed, 9 Jun 2021 10:31:09 +0100 Subject: [PATCH] fix coverage, unit test allocators and equality --- include/rapidjson/pointer.h | 14 +- include/rapidjson/schema.h | 14 +- include/rapidjson/uri.h | 10 +- test/unittest/pointertest.cpp | 12 +- test/unittest/uritest.cpp | 1073 +++++++++++++++++---------------- 5 files changed, 579 insertions(+), 544 deletions(-) diff --git a/include/rapidjson/pointer.h b/include/rapidjson/pointer.h index 96f33fa..a55e7cc 100644 --- a/include/rapidjson/pointer.h +++ b/include/rapidjson/pointer.h @@ -530,7 +530,9 @@ public: // For use with JSON pointers into JSON schema documents. /*! \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param rootUri Root URI \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. + \param allocator Allocator for Uris \return Uri if it can be resolved. Otherwise null. \note @@ -541,10 +543,10 @@ public: Use unresolvedTokenIndex to retrieve the token index. */ - UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0) const { + UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const { static const Ch kIdString[] = { 'i', 'd', '\0' }; static const ValueType kIdValue(kIdString, 2); - UriType base = rootUri; + UriType base = UriType(rootUri, allocator); RAPIDJSON_ASSERT(IsValid()); ValueType* v = &root; for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { @@ -554,7 +556,7 @@ public: // See if we have an id, and if so resolve with the current base typename ValueType::MemberIterator m = v->FindMember(kIdValue); if (m != v->MemberEnd() && (m->value).IsString()) { - UriType here = UriType(m->value, allocator_).Resolve(base, allocator_); + UriType here = UriType(m->value, allocator).Resolve(base, allocator); base = here; } m = v->FindMember(GenericValue(GenericStringRef(t->name, t->length))); @@ -575,13 +577,13 @@ public: // Error: unresolved token if (unresolvedTokenIndex) *unresolvedTokenIndex = static_cast(t - tokens_); - return UriType(allocator_); + return UriType(allocator); } return base; } - UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0) const { - return GetUri(const_cast(root), rootUri, unresolvedTokenIndex); + UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const { + return GetUri(const_cast(root), rootUri, unresolvedTokenIndex, allocator); } diff --git a/include/rapidjson/schema.h b/include/rapidjson/schema.h index a48288b..f0759ff 100644 --- a/include/rapidjson/schema.h +++ b/include/rapidjson/schema.h @@ -1741,7 +1741,7 @@ private: // Changed by PR #1393 void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document, const UriType& id) { if (v.GetType() == kObjectType) { - UriType newid = CreateSchema(schema, pointer, v, document, id); + UriType newid = UriType(CreateSchema(schema, pointer, v, document, id), allocator_); for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document, newid); @@ -1790,7 +1790,7 @@ private: SizeType len = itr->value.GetStringLength(); if (len > 0) { // First resolve $ref against the in-scope id - UriType scopeId = id; + UriType scopeId = UriType(id, allocator_); UriType ref = UriType(itr->value, allocator_).Resolve(scopeId, allocator_); // See if the resolved $ref minus the fragment matches a resolved id in this document // Search from the root. Returns the subschema in the document and its absolute JSON pointer. @@ -1838,7 +1838,8 @@ private: if (pointer.IsValid() && !IsCyclicRef(pointer)) { // Call CreateSchema recursively, but first compute the in-scope id for the $ref target as we have jumped there // TODO: cache pointer <-> id mapping - scopeId = pointer.GetUri(document, docId_); + size_t unresolvedTokenIndex; + scopeId = pointer.GetUri(document, docId_, &unresolvedTokenIndex, allocator_); CreateSchema(schema, pointer, *pv, document, scopeId); return true; } @@ -1855,7 +1856,8 @@ private: //pointer.StringifyUriFragment(sb); // Call CreateSchema recursively, but first compute the in-scope id for the $ref target as we have jumped there // TODO: cache pointer <-> id mapping - scopeId = pointer.GetUri(document, docId_); + size_t unresolvedTokenIndex; + scopeId = pointer.GetUri(document, docId_, &unresolvedTokenIndex, allocator_); CreateSchema(schema, pointer, *pv, document, scopeId); return true; } @@ -1879,8 +1881,8 @@ private: ValueType* FindId(const ValueType& doc, const UriType& finduri, PointerType& resptr, const UriType& baseuri, bool full, const PointerType& here = PointerType()) const { SizeType i = 0; ValueType* resval = 0; - UriType tempuri = finduri; - UriType localuri = baseuri; + UriType tempuri = UriType(finduri, allocator_); + UriType localuri = UriType(baseuri, allocator_); if (doc.GetType() == kObjectType) { // Establish the base URI of this object typename ValueType::ConstMemberIterator m = doc.FindMember(SchemaType::GetIdString()); diff --git a/include/rapidjson/uri.h b/include/rapidjson/uri.h index 15be29a..f70c388 100644 --- a/include/rapidjson/uri.h +++ b/include/rapidjson/uri.h @@ -29,9 +29,9 @@ RAPIDJSON_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////// // GenericUri - template - class GenericUri { - public: +template +class GenericUri { +public: typedef typename ValueType::Ch Ch; #if RAPIDJSON_HAS_STDSTRING typedef std::basic_string String; @@ -462,10 +462,10 @@ private: Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. Allocator* ownAllocator_; //!< Allocator owned by this Uri. - }; +}; //! GenericUri for Value (UTF-8, default allocator). - typedef GenericUri Uri; +typedef GenericUri Uri; RAPIDJSON_NAMESPACE_END diff --git a/test/unittest/pointertest.cpp b/test/unittest/pointertest.cpp index c00658c..31aebec 100644 --- a/test/unittest/pointertest.cpp +++ b/test/unittest/pointertest.cpp @@ -659,6 +659,7 @@ static const char kJsonIds[] = "{\n" TEST(Pointer, GetUri) { + CrtAllocator allocator; Document d; d.Parse(kJsonIds); Pointer::UriType doc("http://doc"); @@ -677,15 +678,16 @@ TEST(Pointer, GetUri) { EXPECT_TRUE(Pointer("/jbo").GetUri(d, doc) == root); EXPECT_TRUE(Pointer("/jbo/child").GetUri(d, doc) == root); // id not string - EXPECT_TRUE(Pointer("/abc").GetUri(d, doc) == empty); // Out of boundary size_t unresolvedTokenIndex; - EXPECT_TRUE(Pointer("/foo/3").GetUri(d, doc, &unresolvedTokenIndex) == empty); // Out of boundary + EXPECT_TRUE(Pointer("/abc").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // Out of boundary + EXPECT_EQ(0u, unresolvedTokenIndex); + EXPECT_TRUE(Pointer("/foo/3").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // Out of boundary EXPECT_EQ(1u, unresolvedTokenIndex); - EXPECT_TRUE(Pointer("/foo/a").GetUri(d, doc, &unresolvedTokenIndex) == empty); // "/foo" is an array, cannot query by "a" + EXPECT_TRUE(Pointer("/foo/a").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // "/foo" is an array, cannot query by "a" EXPECT_EQ(1u, unresolvedTokenIndex); - EXPECT_TRUE(Pointer("/foo/0/0").GetUri(d, doc, &unresolvedTokenIndex) == empty); // "/foo/0" is an string, cannot further query + EXPECT_TRUE(Pointer("/foo/0/0").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // "/foo/0" is an string, cannot further query EXPECT_EQ(2u, unresolvedTokenIndex); - EXPECT_TRUE(Pointer("/foo/0/a").GetUri(d, doc, &unresolvedTokenIndex) == empty); // "/foo/0" is an string, cannot further query + EXPECT_TRUE(Pointer("/foo/0/a").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // "/foo/0" is an string, cannot further query EXPECT_EQ(2u, unresolvedTokenIndex); Pointer::Token tokens[] = { { "foo ...", 3, kPointerInvalidIndex } }; diff --git a/test/unittest/uritest.cpp b/test/unittest/uritest.cpp index fcedcb1..7fa7b93 100644 --- a/test/unittest/uritest.cpp +++ b/test/unittest/uritest.cpp @@ -30,593 +30,622 @@ RAPIDJSON_DIAG_OFF(4822) // local class member function does not have a body using namespace rapidjson; TEST(Uri, Parse) { -typedef GenericUri > UriType; -MemoryPoolAllocator allocator; -Value v; -Value w; + typedef GenericUri > UriType; + MemoryPoolAllocator allocator; + Value v; + Value w; -v.SetString("http://auth/path/xxx?query#frag", allocator); -UriType u = UriType(v, &allocator); -EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0); -EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), "/path/xxx") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth/path/xxx?query") == 0); -EXPECT_TRUE(StrCmp(u.GetQueryString(), "?query") == 0); -EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag") == 0); -u.Get(w, allocator); -EXPECT_TRUE(*w.GetString() == *v.GetString()); + v.SetString("http://auth/path/xxx?query#frag", allocator); + UriType u = UriType(v, &allocator); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0); + EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), "/path/xxx") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth/path/xxx?query") == 0); + EXPECT_TRUE(StrCmp(u.GetQueryString(), "?query") == 0); + EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag") == 0); + u.Get(w, allocator); + EXPECT_TRUE(*w.GetString() == *v.GetString()); #if RAPIDJSON_HAS_STDSTRING -typedef std::basic_string String; -String str = "http://auth/path/xxx?query#frag"; -const UriType uri = UriType(str); -EXPECT_TRUE(UriType::GetScheme(uri) == "http:"); -EXPECT_TRUE(UriType::GetAuth(uri) == "//auth"); -EXPECT_TRUE(UriType::GetPath(uri) == "/path/xxx"); -EXPECT_TRUE(UriType::GetBase(uri) == "http://auth/path/xxx?query"); -EXPECT_TRUE(UriType::GetQuery(uri) == "?query"); -EXPECT_TRUE(UriType::GetFrag(uri) == "#frag"); -EXPECT_TRUE(UriType::Get(uri) == str); + typedef std::basic_string String; + String str = "http://auth/path/xxx?query#frag"; + const UriType uri = UriType(str); + EXPECT_TRUE(UriType::GetScheme(uri) == "http:"); + EXPECT_TRUE(UriType::GetAuth(uri) == "//auth"); + EXPECT_TRUE(UriType::GetPath(uri) == "/path/xxx"); + EXPECT_TRUE(UriType::GetBase(uri) == "http://auth/path/xxx?query"); + EXPECT_TRUE(UriType::GetQuery(uri) == "?query"); + EXPECT_TRUE(UriType::GetFrag(uri) == "#frag"); + EXPECT_TRUE(UriType::Get(uri) == str); #endif -v.SetString("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator); -u = UriType(v); -EXPECT_TRUE(StrCmp(u.GetSchemeString(), "urn:") == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), "uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); -u.Get(w, allocator); -EXPECT_TRUE(*w.GetString() == *v.GetString()); + v.SetString("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator); + u = UriType(v); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), "urn:") == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), "uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); + u.Get(w, allocator); + EXPECT_TRUE(*w.GetString() == *v.GetString()); -v.SetString("", allocator); -u = UriType(v); -EXPECT_TRUE(u.GetSchemeStringLength() == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(u.GetPathStringLength() == 0); -EXPECT_TRUE(u.GetBaseStringLength() == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + v.SetString("", allocator); + u = UriType(v); + EXPECT_TRUE(u.GetSchemeStringLength() == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(u.GetPathStringLength() == 0); + EXPECT_TRUE(u.GetBaseStringLength() == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -v.SetString("http://auth/", allocator); -u = UriType(v); -EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0); -EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), "/") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth/") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + v.SetString("http://auth/", allocator); + u = UriType(v); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0); + EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), "/") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth/") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -u = UriType("/path/sub"); -EXPECT_TRUE(u.GetSchemeStringLength() == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), "/path/sub") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "/path/sub") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + u = UriType("/path/sub"); + EXPECT_TRUE(u.GetSchemeStringLength() == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), "/path/sub") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "/path/sub") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -// absolute path gets normalized -u = UriType("/path/../sub/"); -EXPECT_TRUE(u.GetSchemeStringLength() == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), "/sub/") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "/sub/") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + // absolute path gets normalized + u = UriType("/path/../sub/"); + EXPECT_TRUE(u.GetSchemeStringLength() == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), "/sub/") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "/sub/") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -// relative path does not -u = UriType("path/../sub"); -EXPECT_TRUE(u.GetSchemeStringLength() == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), "path/../sub") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "path/../sub") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + // relative path does not + u = UriType("path/../sub"); + EXPECT_TRUE(u.GetSchemeStringLength() == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), "path/../sub") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "path/../sub") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -u = UriType("http://auth#frag/stuff"); -EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0); -EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0); -EXPECT_TRUE(u.GetPathStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0); -EXPECT_TRUE(StrCmp(u.GetString(), "http://auth#frag/stuff") == 0); + u = UriType("http://auth#frag/stuff"); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0); + EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0); + EXPECT_TRUE(u.GetPathStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0); + EXPECT_TRUE(StrCmp(u.GetString(), "http://auth#frag/stuff") == 0); -const Value::Ch c[] = { '#', 'f', 'r', 'a', 'g', '/', 's', 't', 'u', 'f', 'f', '\0'}; -SizeType len = internal::StrLen(c); -u = UriType(c, len); -EXPECT_TRUE(StrCmp(u.GetString(), "#frag/stuff") == 0); -EXPECT_TRUE(u.GetStringLength() == len); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "") == 0); -EXPECT_TRUE(u.GetBaseStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0); -EXPECT_TRUE(u.GetFragStringLength() == len); + const Value::Ch c[] = { '#', 'f', 'r', 'a', 'g', '/', 's', 't', 'u', 'f', 'f', '\0'}; + SizeType len = internal::StrLen(c); + u = UriType(c, len); + EXPECT_TRUE(StrCmp(u.GetString(), "#frag/stuff") == 0); + EXPECT_TRUE(u.GetStringLength() == len); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "") == 0); + EXPECT_TRUE(u.GetBaseStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0); + EXPECT_TRUE(u.GetFragStringLength() == len); -u = UriType(c); -EXPECT_TRUE(StrCmp(u.GetString(), "#frag/stuff") == 0); -EXPECT_TRUE(u.GetStringLength() == len); -EXPECT_TRUE(StrCmp(u.GetBaseString(), "") == 0); -EXPECT_TRUE(u.GetBaseStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0); -EXPECT_TRUE(u.GetFragStringLength() == len); + u = UriType(c); + EXPECT_TRUE(StrCmp(u.GetString(), "#frag/stuff") == 0); + EXPECT_TRUE(u.GetStringLength() == len); + EXPECT_TRUE(StrCmp(u.GetBaseString(), "") == 0); + EXPECT_TRUE(u.GetBaseStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0); + EXPECT_TRUE(u.GetFragStringLength() == len); } TEST(Uri, Parse_UTF16) { -typedef GenericValue > Value16; -typedef GenericUri > UriType; -MemoryPoolAllocator allocator; -Value16 v; -Value16 w; + typedef GenericValue > Value16; + typedef GenericUri > UriType; + MemoryPoolAllocator allocator; + Value16 v; + Value16 w; -v.SetString(L"http://auth/path/xxx?query#frag", allocator); -UriType u = UriType(v, &allocator); -EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0); -EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), L"/path/xxx") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth/path/xxx?query") == 0); -EXPECT_TRUE(StrCmp(u.GetQueryString(), L"?query") == 0); -EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag") == 0); -u.Get(w, allocator); -EXPECT_TRUE(*w.GetString() == *v.GetString()); + v.SetString(L"http://auth/path/xxx?query#frag", allocator); + UriType u = UriType(v, &allocator); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0); + EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), L"/path/xxx") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth/path/xxx?query") == 0); + EXPECT_TRUE(StrCmp(u.GetQueryString(), L"?query") == 0); + EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag") == 0); + u.Get(w, allocator); + EXPECT_TRUE(*w.GetString() == *v.GetString()); #if RAPIDJSON_HAS_STDSTRING -typedef std::basic_string String; -String str = L"http://auth/path/xxx?query#frag"; -const UriType uri = UriType(str); -EXPECT_TRUE(UriType::GetScheme(uri) == L"http:"); -EXPECT_TRUE(UriType::GetAuth(uri) == L"//auth"); -EXPECT_TRUE(UriType::GetPath(uri) == L"/path/xxx"); -EXPECT_TRUE(UriType::GetBase(uri) == L"http://auth/path/xxx?query"); -EXPECT_TRUE(UriType::GetQuery(uri) == L"?query"); -EXPECT_TRUE(UriType::GetFrag(uri) == L"#frag"); -EXPECT_TRUE(UriType::Get(uri) == str); + typedef std::basic_string String; + String str = L"http://auth/path/xxx?query#frag"; + const UriType uri = UriType(str); + EXPECT_TRUE(UriType::GetScheme(uri) == L"http:"); + EXPECT_TRUE(UriType::GetAuth(uri) == L"//auth"); + EXPECT_TRUE(UriType::GetPath(uri) == L"/path/xxx"); + EXPECT_TRUE(UriType::GetBase(uri) == L"http://auth/path/xxx?query"); + EXPECT_TRUE(UriType::GetQuery(uri) == L"?query"); + EXPECT_TRUE(UriType::GetFrag(uri) == L"#frag"); + EXPECT_TRUE(UriType::Get(uri) == str); #endif -v.SetString(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator); -u = UriType(v); -EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"urn:") == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), L"uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); -u.Get(w, allocator); -EXPECT_TRUE(*w.GetString() == *v.GetString()); + v.SetString(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator); + u = UriType(v); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"urn:") == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), L"uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); + u.Get(w, allocator); + EXPECT_TRUE(*w.GetString() == *v.GetString()); -v.SetString(L"", allocator); -u = UriType(v); -EXPECT_TRUE(u.GetSchemeStringLength() == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(u.GetPathStringLength() == 0); -EXPECT_TRUE(u.GetBaseStringLength() == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + v.SetString(L"", allocator); + u = UriType(v); + EXPECT_TRUE(u.GetSchemeStringLength() == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(u.GetPathStringLength() == 0); + EXPECT_TRUE(u.GetBaseStringLength() == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -v.SetString(L"http://auth/", allocator); -u = UriType(v); -EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0); -EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), L"/") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth/") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + v.SetString(L"http://auth/", allocator); + u = UriType(v); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0); + EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), L"/") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth/") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -u = UriType(L"/path/sub"); -EXPECT_TRUE(u.GetSchemeStringLength() == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), L"/path/sub") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"/path/sub") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + u = UriType(L"/path/sub"); + EXPECT_TRUE(u.GetSchemeStringLength() == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), L"/path/sub") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"/path/sub") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -// absolute path gets normalized -u = UriType(L"/path/../sub/"); -EXPECT_TRUE(u.GetSchemeStringLength() == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), L"/sub/") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"/sub/") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + // absolute path gets normalized + u = UriType(L"/path/../sub/"); + EXPECT_TRUE(u.GetSchemeStringLength() == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), L"/sub/") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"/sub/") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -// relative path does not -u = UriType(L"path/../sub"); -EXPECT_TRUE(u.GetSchemeStringLength() == 0); -EXPECT_TRUE(u.GetAuthStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetPathString(), L"path/../sub") == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"path/../sub") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(u.GetFragStringLength() == 0); + // relative path does not + u = UriType(L"path/../sub"); + EXPECT_TRUE(u.GetSchemeStringLength() == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), L"path/../sub") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"path/../sub") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(u.GetFragStringLength() == 0); -u = UriType(L"http://auth#frag/stuff"); -EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0); -EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0); -EXPECT_TRUE(u.GetPathStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth") == 0); -EXPECT_TRUE(u.GetQueryStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0); -EXPECT_TRUE(StrCmp(u.GetString(), L"http://auth#frag/stuff") == 0); + u = UriType(L"http://auth#frag/stuff"); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0); + EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0); + EXPECT_TRUE(u.GetPathStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth") == 0); + EXPECT_TRUE(u.GetQueryStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0); + EXPECT_TRUE(StrCmp(u.GetString(), L"http://auth#frag/stuff") == 0); -const Value16::Ch c[] = { '#', 'f', 'r', 'a', 'g', '/', 's', 't', 'u', 'f', 'f', '\0'}; -SizeType len = internal::StrLen(c); -u = UriType(c, len); -EXPECT_TRUE(StrCmp(u.GetString(), L"#frag/stuff") == 0); -EXPECT_TRUE(u.GetStringLength() == len); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"") == 0); -EXPECT_TRUE(u.GetBaseStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0); -EXPECT_TRUE(u.GetFragStringLength() == len); + const Value16::Ch c[] = { '#', 'f', 'r', 'a', 'g', '/', 's', 't', 'u', 'f', 'f', '\0'}; + SizeType len = internal::StrLen(c); + u = UriType(c, len); + EXPECT_TRUE(StrCmp(u.GetString(), L"#frag/stuff") == 0); + EXPECT_TRUE(u.GetStringLength() == len); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"") == 0); + EXPECT_TRUE(u.GetBaseStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0); + EXPECT_TRUE(u.GetFragStringLength() == len); -u = UriType(c); -EXPECT_TRUE(StrCmp(u.GetString(), L"#frag/stuff") == 0); -EXPECT_TRUE(u.GetStringLength() == len); -EXPECT_TRUE(StrCmp(u.GetBaseString(), L"") == 0); -EXPECT_TRUE(u.GetBaseStringLength() == 0); -EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0); -EXPECT_TRUE(u.GetFragStringLength() == len); + u = UriType(c); + EXPECT_TRUE(StrCmp(u.GetString(), L"#frag/stuff") == 0); + EXPECT_TRUE(u.GetStringLength() == len); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"") == 0); + EXPECT_TRUE(u.GetBaseStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0); + EXPECT_TRUE(u.GetFragStringLength() == len); } TEST(Uri, Resolve) { -typedef GenericUri UriType; -CrtAllocator allocator; + typedef GenericUri UriType; + CrtAllocator allocator; -// ref is full uri -UriType base = UriType("http://auth/path/#frag"); -UriType ref = UriType("http://newauth/newpath#newfrag"); -UriType res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://newauth/newpath#newfrag") == 0); + // ref is full uri + UriType base = UriType("http://auth/path/#frag"); + UriType ref = UriType("http://newauth/newpath#newfrag"); + UriType res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://newauth/newpath#newfrag") == 0); -base = UriType("/path/#frag", &allocator); -ref = UriType("http://newauth/newpath#newfrag", &allocator); -res = ref.Resolve(base, &allocator); -EXPECT_TRUE(StrCmp(res.GetString(), "http://newauth/newpath#newfrag") == 0); + base = UriType("/path/#frag", &allocator); + ref = UriType("http://newauth/newpath#newfrag", &allocator); + res = ref.Resolve(base, &allocator); + EXPECT_TRUE(StrCmp(res.GetString(), "http://newauth/newpath#newfrag") == 0); -// ref is alternate uri -base = UriType("http://auth/path/#frag"); -ref = UriType("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); + // ref is alternate uri + base = UriType("http://auth/path/#frag"); + ref = UriType("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); -// ref is absolute path -base = UriType("http://auth/path/#"); -ref = UriType("/newpath#newfrag"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/newpath#newfrag") == 0); + // ref is absolute path + base = UriType("http://auth/path/#"); + ref = UriType("/newpath#newfrag"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/newpath#newfrag") == 0); -// ref is relative path -base = UriType("http://auth/path/file.json#frag"); -ref = UriType("newfile.json#"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/path/newfile.json#") == 0); + // ref is relative path + base = UriType("http://auth/path/file.json#frag"); + ref = UriType("newfile.json#"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/path/newfile.json#") == 0); -base = UriType("http://auth/path/file.json#frag/stuff"); -ref = UriType("newfile.json#newfrag/newstuff"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/path/newfile.json#newfrag/newstuff") == 0); + base = UriType("http://auth/path/file.json#frag/stuff"); + ref = UriType("newfile.json#newfrag/newstuff"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/path/newfile.json#newfrag/newstuff") == 0); -base = UriType("file.json", &allocator); -ref = UriType("newfile.json", &base.GetAllocator()); -res = ref.Resolve(base, &ref.GetAllocator()); -EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0); + base = UriType("file.json", &allocator); + ref = UriType("newfile.json", &base.GetAllocator()); + res = ref.Resolve(base, &ref.GetAllocator()); + EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0); -base = UriType("file.json", &allocator); -ref = UriType("./newfile.json", &allocator); -res = ref.Resolve(base, &allocator); -EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0); + base = UriType("file.json", &allocator); + ref = UriType("./newfile.json", &allocator); + res = ref.Resolve(base, &allocator); + EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0); -base = UriType("file.json"); -ref = UriType("parent/../newfile.json"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0); + base = UriType("file.json"); + ref = UriType("parent/../newfile.json"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0); -base = UriType("file.json"); -ref = UriType("parent/./newfile.json"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "parent/newfile.json") == 0); + base = UriType("file.json"); + ref = UriType("parent/./newfile.json"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "parent/newfile.json") == 0); -base = UriType("file.json"); -ref = UriType("../../parent/.././newfile.json"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0); + base = UriType("file.json"); + ref = UriType("../../parent/.././newfile.json"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0); -// This adds a joining slash so resolved length is base length + ref length + 1 -base = UriType("http://auth"); -ref = UriType("newfile.json"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/newfile.json") == 0); + // This adds a joining slash so resolved length is base length + ref length + 1 + base = UriType("http://auth"); + ref = UriType("newfile.json"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/newfile.json") == 0); -// ref is fragment -base = UriType("#frag/stuff"); -ref = UriType("#newfrag/newstuff"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "#newfrag/newstuff") == 0); + // ref is fragment + base = UriType("#frag/stuff"); + ref = UriType("#newfrag/newstuff"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "#newfrag/newstuff") == 0); -// test ref fragment always wins -base = UriType("/path#frag"); -ref = UriType(""); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "/path") == 0); + // test ref fragment always wins + base = UriType("/path#frag"); + ref = UriType(""); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "/path") == 0); -// Examples from RFC3896 -base = UriType("http://a/b/c/d;p?q"); -ref = UriType("g:h"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "g:h") == 0); -ref = UriType("g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g") == 0); -ref = UriType("./g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g") == 0); -ref = UriType("g/"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g/") == 0); -ref = UriType("/g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); -ref = UriType("//g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://g") == 0); -ref = UriType("?y"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?y") == 0); -ref = UriType("g?y"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g?y") == 0); -ref = UriType("#s"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?q#s") == 0); -ref = UriType("g#s"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g#s") == 0); -ref = UriType("g?y#s"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g?y#s") == 0); -ref = UriType(";x"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/;x") == 0); -ref = UriType("g;x"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g;x") == 0); -ref = UriType("g;x?y#s"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g;x?y#s") == 0); -ref = UriType(""); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?q") == 0); -ref = UriType("."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/") == 0); -ref = UriType("./"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/") == 0); -ref = UriType(".."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/") == 0); -ref = UriType("../"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/") == 0); -ref = UriType("../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/g") == 0); -ref = UriType("../.."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/") == 0); -ref = UriType("../../"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/") == 0); -ref = UriType("../../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); -ref = UriType("../../../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); -ref = UriType("../../../../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); -ref = UriType("/./g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); -ref = UriType("/../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); -ref = UriType("g."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g.") == 0); -ref = UriType(".g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/.g") == 0); -ref = UriType("g.."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g..") == 0); -ref = UriType("..g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/..g") == 0); -ref = UriType("g#s/../x"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g#s/../x") == 0); + // Examples from RFC3896 + base = UriType("http://a/b/c/d;p?q"); + ref = UriType("g:h"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "g:h") == 0); + ref = UriType("g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g") == 0); + ref = UriType("./g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g") == 0); + ref = UriType("g/"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g/") == 0); + ref = UriType("/g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); + ref = UriType("//g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://g") == 0); + ref = UriType("?y"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?y") == 0); + ref = UriType("g?y"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g?y") == 0); + ref = UriType("#s"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?q#s") == 0); + ref = UriType("g#s"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g#s") == 0); + ref = UriType("g?y#s"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g?y#s") == 0); + ref = UriType(";x"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/;x") == 0); + ref = UriType("g;x"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g;x") == 0); + ref = UriType("g;x?y#s"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g;x?y#s") == 0); + ref = UriType(""); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?q") == 0); + ref = UriType("."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/") == 0); + ref = UriType("./"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/") == 0); + ref = UriType(".."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/") == 0); + ref = UriType("../"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/") == 0); + ref = UriType("../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/g") == 0); + ref = UriType("../.."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/") == 0); + ref = UriType("../../"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/") == 0); + ref = UriType("../../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); + ref = UriType("../../../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); + ref = UriType("../../../../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); + ref = UriType("/./g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); + ref = UriType("/../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0); + ref = UriType("g."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g.") == 0); + ref = UriType(".g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/.g") == 0); + ref = UriType("g.."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g..") == 0); + ref = UriType("..g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/..g") == 0); + ref = UriType("g#s/../x"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g#s/../x") == 0); } TEST(Uri, Resolve_UTF16) { -typedef GenericValue > Value16; -typedef GenericUri UriType; -CrtAllocator allocator; + typedef GenericValue > Value16; + typedef GenericUri UriType; + CrtAllocator allocator; -// ref is full uri -UriType base = UriType(L"http://auth/path/#frag"); -UriType ref = UriType(L"http://newauth/newpath#newfrag"); -UriType res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://newauth/newpath#newfrag") == 0); + // ref is full uri + UriType base = UriType(L"http://auth/path/#frag"); + UriType ref = UriType(L"http://newauth/newpath#newfrag"); + UriType res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://newauth/newpath#newfrag") == 0); -base = UriType(L"/path/#frag"); -ref = UriType(L"http://newauth/newpath#newfrag"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://newauth/newpath#newfrag") == 0); + base = UriType(L"/path/#frag"); + ref = UriType(L"http://newauth/newpath#newfrag"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://newauth/newpath#newfrag") == 0); -// ref is alternate uri -base = UriType(L"http://auth/path/#frag"); -ref = UriType(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); + // ref is alternate uri + base = UriType(L"http://auth/path/#frag"); + ref = UriType(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0); -// ref is absolute path -base = UriType(L"http://auth/path/#"); -ref = UriType(L"/newpath#newfrag"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/newpath#newfrag") == 0); + // ref is absolute path + base = UriType(L"http://auth/path/#"); + ref = UriType(L"/newpath#newfrag"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/newpath#newfrag") == 0); -// ref is relative path -base = UriType(L"http://auth/path/file.json#frag"); -ref = UriType(L"newfile.json#"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/path/newfile.json#") == 0); + // ref is relative path + base = UriType(L"http://auth/path/file.json#frag"); + ref = UriType(L"newfile.json#"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/path/newfile.json#") == 0); -base = UriType(L"http://auth/path/file.json#frag/stuff"); -ref = UriType(L"newfile.json#newfrag/newstuff"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/path/newfile.json#newfrag/newstuff") == 0); + base = UriType(L"http://auth/path/file.json#frag/stuff"); + ref = UriType(L"newfile.json#newfrag/newstuff"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/path/newfile.json#newfrag/newstuff") == 0); -base = UriType(L"file.json", &allocator); -ref = UriType(L"newfile.json", &base.GetAllocator()); -res = ref.Resolve(base, &ref.GetAllocator()); -EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0); + base = UriType(L"file.json", &allocator); + ref = UriType(L"newfile.json", &base.GetAllocator()); + res = ref.Resolve(base, &ref.GetAllocator()); + EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0); -base = UriType(L"file.json", &allocator); -ref = UriType(L"./newfile.json", &allocator); -res = ref.Resolve(base, &allocator); -EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0); + base = UriType(L"file.json", &allocator); + ref = UriType(L"./newfile.json", &allocator); + res = ref.Resolve(base, &allocator); + EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0); -base = UriType(L"file.json"); -ref = UriType(L"parent/../newfile.json"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0); + base = UriType(L"file.json"); + ref = UriType(L"parent/../newfile.json"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0); -base = UriType(L"file.json"); -ref = UriType(L"parent/./newfile.json"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"parent/newfile.json") == 0); + base = UriType(L"file.json"); + ref = UriType(L"parent/./newfile.json"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"parent/newfile.json") == 0); -base = UriType(L"file.json"); -ref = UriType(L"../../parent/.././newfile.json"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0); + base = UriType(L"file.json"); + ref = UriType(L"../../parent/.././newfile.json"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0); -// This adds a joining slash so resolved length is base length + ref length + 1 -base = UriType(L"http://auth"); -ref = UriType(L"newfile.json"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/newfile.json") == 0); + // This adds a joining slash so resolved length is base length + ref length + 1 + base = UriType(L"http://auth"); + ref = UriType(L"newfile.json"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/newfile.json") == 0); -// ref is fragment -base = UriType(L"#frag/stuff"); -ref = UriType(L"#newfrag/newstuff"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"#newfrag/newstuff") == 0); + // ref is fragment + base = UriType(L"#frag/stuff"); + ref = UriType(L"#newfrag/newstuff"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"#newfrag/newstuff") == 0); -// test ref fragment always wins -base = UriType(L"/path#frag"); -ref = UriType(L""); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"/path") == 0); + // test ref fragment always wins + base = UriType(L"/path#frag"); + ref = UriType(L""); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"/path") == 0); -// Examples from RFC3896 -base = UriType(L"http://a/b/c/d;p?q"); -ref = UriType(L"g:h"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"g:h") == 0); -ref = UriType(L"g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g") == 0); -ref = UriType(L"./g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g") == 0); -ref = UriType(L"g/"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g/") == 0); -ref = UriType(L"/g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); -ref = UriType(L"//g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://g") == 0); -ref = UriType(L"?y"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?y") == 0); -ref = UriType(L"g?y"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g?y") == 0); -ref = UriType(L"#s"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?q#s") == 0); -ref = UriType(L"g#s"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g#s") == 0); -ref = UriType(L"g?y#s"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g?y#s") == 0); -ref = UriType(L";x"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/;x") == 0); -ref = UriType(L"g;x"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g;x") == 0); -ref = UriType(L"g;x?y#s"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g;x?y#s") == 0); -ref = UriType(L""); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?q") == 0); -ref = UriType(L"."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/") == 0); -ref = UriType(L"./"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/") == 0); -ref = UriType(L".."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/") == 0); -ref = UriType(L"../"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/") == 0); -ref = UriType(L"../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/g") == 0); -ref = UriType(L"../.."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/") == 0); -ref = UriType(L"../../"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/") == 0); -ref = UriType(L"../../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); -ref = UriType(L"../../../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); -ref = UriType(L"../../../../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); -ref = UriType(L"/./g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); -ref = UriType(L"/../g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); -ref = UriType(L"g."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g.") == 0); -ref = UriType(L".g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/.g") == 0); -ref = UriType(L"g.."); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g..") == 0); -ref = UriType(L"..g"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/..g") == 0); -ref = UriType(L"g#s/../x"); -res = ref.Resolve(base); -EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g#s/../x") == 0); + // Examples from RFC3896 + base = UriType(L"http://a/b/c/d;p?q"); + ref = UriType(L"g:h"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"g:h") == 0); + ref = UriType(L"g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g") == 0); + ref = UriType(L"./g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g") == 0); + ref = UriType(L"g/"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g/") == 0); + ref = UriType(L"/g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); + ref = UriType(L"//g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://g") == 0); + ref = UriType(L"?y"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?y") == 0); + ref = UriType(L"g?y"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g?y") == 0); + ref = UriType(L"#s"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?q#s") == 0); + ref = UriType(L"g#s"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g#s") == 0); + ref = UriType(L"g?y#s"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g?y#s") == 0); + ref = UriType(L";x"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/;x") == 0); + ref = UriType(L"g;x"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g;x") == 0); + ref = UriType(L"g;x?y#s"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g;x?y#s") == 0); + ref = UriType(L""); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?q") == 0); + ref = UriType(L"."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/") == 0); + ref = UriType(L"./"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/") == 0); + ref = UriType(L".."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/") == 0); + ref = UriType(L"../"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/") == 0); + ref = UriType(L"../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/g") == 0); + ref = UriType(L"../.."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/") == 0); + ref = UriType(L"../../"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/") == 0); + ref = UriType(L"../../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); + ref = UriType(L"../../../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); + ref = UriType(L"../../../../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); + ref = UriType(L"/./g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); + ref = UriType(L"/../g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0); + ref = UriType(L"g."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g.") == 0); + ref = UriType(L".g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/.g") == 0); + ref = UriType(L"g.."); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g..") == 0); + ref = UriType(L"..g"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/..g") == 0); + ref = UriType(L"g#s/../x"); + res = ref.Resolve(base); + EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g#s/../x") == 0); +} + +TEST(Uri, Equals) { + typedef GenericUri UriType; + + UriType a = UriType("http://a/a#a"); + UriType b = UriType("http://a/a#b"); + UriType c = a; + + EXPECT_TRUE(a == a); + EXPECT_TRUE(a == c); + EXPECT_TRUE(a != b); +} + +TEST(Uri, Match) { + typedef GenericUri UriType; + + UriType a = UriType("http://a/a#a"); + UriType b = UriType("http://a/a#b"); + UriType c = a; + UriType d; + + EXPECT_TRUE(a.Match(a)); + EXPECT_TRUE(a.Match(c)); + EXPECT_FALSE(a.Match(b)); + EXPECT_FALSE(a.Match(b, true)); + EXPECT_TRUE(a.Match(b, false)); // Base Uri same + EXPECT_FALSE(a.Match(d)); + EXPECT_FALSE(d.Match(a)); } #if defined(_MSC_VER) || defined(__clang__)