Add copy on write tests
Signed-off-by: Nicholas Van Sickle <nvsickle@amazon.com>
This commit is contained in:
@@ -476,7 +476,7 @@ namespace AZ::Dom
|
||||
return FindMember(AZ::Name(name));
|
||||
}
|
||||
|
||||
Object::Iterator Value::FindMember(KeyType name)
|
||||
Object::Iterator Value::FindMutableMember(KeyType name)
|
||||
{
|
||||
Object::ContainerType& object = GetObjectInternal();
|
||||
return AZStd::find_if(
|
||||
@@ -487,9 +487,9 @@ namespace AZ::Dom
|
||||
});
|
||||
}
|
||||
|
||||
Object::Iterator Value::FindMember(AZStd::string_view name)
|
||||
Object::Iterator Value::FindMutableMember(AZStd::string_view name)
|
||||
{
|
||||
return FindMember(AZ::Name(name));
|
||||
return FindMutableMember(AZ::Name(name));
|
||||
}
|
||||
|
||||
Value& Value::MemberReserve(size_t newCapacity)
|
||||
@@ -511,7 +511,7 @@ namespace AZ::Dom
|
||||
Value& Value::AddMember(KeyType name, const Value& value)
|
||||
{
|
||||
Object::ContainerType& object = GetObjectInternal();
|
||||
if (auto memberIt = FindMember(name); memberIt != object.end())
|
||||
if (auto memberIt = FindMutableMember(name); memberIt != object.end())
|
||||
{
|
||||
memberIt->second = value;
|
||||
}
|
||||
@@ -530,7 +530,7 @@ namespace AZ::Dom
|
||||
Value& Value::AddMember(AZ::Name name, Value&& value)
|
||||
{
|
||||
Object::ContainerType& object = GetObjectInternal();
|
||||
if (auto memberIt = FindMember(name); memberIt != object.end())
|
||||
if (auto memberIt = FindMutableMember(name); memberIt != object.end())
|
||||
{
|
||||
memberIt->second = value;
|
||||
}
|
||||
@@ -601,7 +601,7 @@ namespace AZ::Dom
|
||||
return EraseMember(AZ::Name(name));
|
||||
}
|
||||
|
||||
Object::ContainerType& Value::GetObject()
|
||||
Object::ContainerType& Value::GetMutableObject()
|
||||
{
|
||||
return GetObjectInternal();
|
||||
}
|
||||
@@ -647,6 +647,16 @@ namespace AZ::Dom
|
||||
return GetArrayInternal()[index];
|
||||
}
|
||||
|
||||
Value& Value::MutableAt(size_t index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
const Value& Value::At(size_t index) const
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
Array::ConstIterator Value::Begin() const
|
||||
{
|
||||
return GetArrayInternal().begin();
|
||||
@@ -695,7 +705,7 @@ namespace AZ::Dom
|
||||
return GetArrayInternal().erase(first, last);
|
||||
}
|
||||
|
||||
Array::ContainerType& Value::GetArray()
|
||||
Array::ContainerType& Value::GetMutableArray()
|
||||
{
|
||||
return GetArrayInternal();
|
||||
}
|
||||
@@ -766,6 +776,16 @@ namespace AZ::Dom
|
||||
return Value();
|
||||
}
|
||||
|
||||
Node& Value::GetMutableNode()
|
||||
{
|
||||
return GetNodeInternal();
|
||||
}
|
||||
|
||||
const Node& Value::GetNode() const
|
||||
{
|
||||
return GetNodeInternal();
|
||||
}
|
||||
|
||||
int64_t Value::GetInt64() const
|
||||
{
|
||||
switch (m_value.index())
|
||||
|
||||
@@ -162,10 +162,10 @@ namespace AZ::Dom
|
||||
Object::Iterator MemberBegin();
|
||||
Object::Iterator MemberEnd();
|
||||
|
||||
Object::Iterator FindMutableMember(KeyType name);
|
||||
Object::Iterator FindMutableMember(AZStd::string_view name);
|
||||
Object::ConstIterator FindMember(KeyType name) const;
|
||||
Object::ConstIterator FindMember(AZStd::string_view name) const;
|
||||
Object::Iterator FindMember(KeyType name);
|
||||
Object::Iterator FindMember(AZStd::string_view name);
|
||||
|
||||
Value& MemberReserve(size_t newCapacity);
|
||||
bool HasMember(KeyType name) const;
|
||||
@@ -185,7 +185,7 @@ namespace AZ::Dom
|
||||
Object::Iterator EraseMember(KeyType name);
|
||||
Object::Iterator EraseMember(AZStd::string_view name);
|
||||
|
||||
Object::ContainerType& GetObject();
|
||||
Object::ContainerType& GetMutableObject();
|
||||
const Object::ContainerType& GetObject() const;
|
||||
|
||||
// Array API (also used by Node)...
|
||||
@@ -199,6 +199,9 @@ namespace AZ::Dom
|
||||
Value& operator[](size_t index);
|
||||
const Value& operator[](size_t index) const;
|
||||
|
||||
Value& MutableAt(size_t index);
|
||||
const Value& At(size_t index) const;
|
||||
|
||||
Array::ConstIterator Begin() const;
|
||||
Array::ConstIterator End() const;
|
||||
Array::Iterator Begin();
|
||||
@@ -211,7 +214,7 @@ namespace AZ::Dom
|
||||
Array::Iterator Erase(Array::ConstIterator pos);
|
||||
Array::Iterator Erase(Array::ConstIterator first, Array::ConstIterator last);
|
||||
|
||||
Array::ContainerType& GetArray();
|
||||
Array::ContainerType& GetMutableArray();
|
||||
const Array::ContainerType& GetArray() const;
|
||||
|
||||
// Node API (supports both object + array API, plus a dedicated NodeName)...
|
||||
@@ -230,6 +233,9 @@ namespace AZ::Dom
|
||||
//! Convenience method, gets the first non-node element of a Node.
|
||||
Value GetNodeValue() const;
|
||||
|
||||
Node& GetMutableNode();
|
||||
const Node& GetNode() const;
|
||||
|
||||
// int API...
|
||||
int64_t GetInt64() const;
|
||||
void SetInt64(int64_t);
|
||||
|
||||
@@ -295,4 +295,90 @@ namespace AZ::Dom::Tests
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, CopyOnWrite_Object)
|
||||
{
|
||||
Value v1(Type::ObjectType);
|
||||
v1["foo"] = 5;
|
||||
|
||||
Value nestedObject(Type::ObjectType);
|
||||
v1["obj"] = nestedObject;
|
||||
|
||||
Value v2 = v1;
|
||||
EXPECT_EQ(&v1.GetObject(), &v2.GetObject());
|
||||
EXPECT_EQ(&v1.FindMember("obj")->second.GetObject(), &v2.FindMember("obj")->second.GetObject());
|
||||
|
||||
v2["foo"] = 0;
|
||||
|
||||
EXPECT_NE(&v1.GetObject(), &v2.GetObject());
|
||||
EXPECT_EQ(&v1.FindMember("obj")->second.GetObject(), &v2.FindMember("obj")->second.GetObject());
|
||||
|
||||
v2["obj"]["key"] = true;
|
||||
|
||||
EXPECT_NE(&v1.GetObject(), &v2.GetObject());
|
||||
EXPECT_NE(&v1.FindMember("obj")->second.GetObject(), &v2.FindMember("obj")->second.GetObject());
|
||||
|
||||
v2 = v1;
|
||||
|
||||
EXPECT_EQ(&v1.GetObject(), &v2.GetObject());
|
||||
EXPECT_EQ(&v1.FindMember("obj")->second.GetObject(), &v2.FindMember("obj")->second.GetObject());
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, CopyOnWrite_Array)
|
||||
{
|
||||
Value v1(Type::ArrayType);
|
||||
v1.PushBack(1);
|
||||
v1.PushBack(2);
|
||||
|
||||
Value nestedArray(Type::ArrayType);
|
||||
v1.PushBack(nestedArray);
|
||||
Value v2 = v1;
|
||||
|
||||
EXPECT_EQ(&v1.GetArray(), &v2.GetArray());
|
||||
EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray());
|
||||
|
||||
v2[0] = 0;
|
||||
|
||||
EXPECT_NE(&v1.GetArray(), &v2.GetArray());
|
||||
EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray());
|
||||
|
||||
v2[2].PushBack(42);
|
||||
|
||||
EXPECT_NE(&v1.GetArray(), &v2.GetArray());
|
||||
EXPECT_NE(&v1.At(2).GetArray(), &v2.At(2).GetArray());
|
||||
|
||||
v2 = v1;
|
||||
|
||||
EXPECT_EQ(&v1.GetArray(), &v2.GetArray());
|
||||
EXPECT_EQ(&v1.At(2).GetArray(), &v2.At(2).GetArray());
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, CopyOnWrite_Node)
|
||||
{
|
||||
Value v1;
|
||||
v1.SetNode("TopLevel");
|
||||
|
||||
v1.PushBack(1);
|
||||
v1.PushBack(2);
|
||||
v1["obj"].SetNode("Nested");
|
||||
Value v2 = v1;
|
||||
|
||||
EXPECT_EQ(&v1.GetNode(), &v2.GetNode());
|
||||
EXPECT_EQ(&v1["obj"].GetNode(), &v2["obj"].GetNode());
|
||||
|
||||
v2[0] = 0;
|
||||
|
||||
EXPECT_NE(&v1.GetNode(), &v2.GetNode());
|
||||
EXPECT_EQ(&v1["obj"].GetNode(), &v2["obj"].GetNode());
|
||||
|
||||
v2["obj"].PushBack(42);
|
||||
|
||||
EXPECT_NE(&v1.GetNode(), &v2.GetNode());
|
||||
EXPECT_NE(&v1["obj"].GetNode(), &v2["obj"].GetNode());
|
||||
|
||||
v2 = v1;
|
||||
|
||||
EXPECT_EQ(&v1.GetNode(), &v2.GetNode());
|
||||
EXPECT_EQ(&v1["obj"].GetNode(), &v2["obj"].GetNode());
|
||||
}
|
||||
} // namespace AZ::Dom::Tests
|
||||
|
||||
Reference in New Issue
Block a user