fix coverage, unit test allocators and equality

This commit is contained in:
Steve Hanson 2021-06-09 10:31:09 +01:00
parent 18ab3b16bc
commit 3df804c128
5 changed files with 579 additions and 544 deletions

View File

@ -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<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
@ -575,13 +577,13 @@ public:
// Error: unresolved token
if (unresolvedTokenIndex)
*unresolvedTokenIndex = static_cast<size_t>(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<ValueType&>(root), rootUri, unresolvedTokenIndex);
UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
}

View File

@ -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());

View File

@ -29,9 +29,9 @@ RAPIDJSON_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// GenericUri
template <typename ValueType, typename Allocator=CrtAllocator>
class GenericUri {
public:
template <typename ValueType, typename Allocator=CrtAllocator>
class GenericUri {
public:
typedef typename ValueType::Ch Ch;
#if RAPIDJSON_HAS_STDSTRING
typedef std::basic_string<Ch> 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<Value> Uri;
typedef GenericUri<Value> Uri;
RAPIDJSON_NAMESPACE_END

View File

@ -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 } };

File diff suppressed because it is too large Load Diff