Add some intial tests
Signed-off-by: Nicholas Van Sickle <nvsickle@amazon.com>
This commit is contained in:
@@ -97,6 +97,16 @@ namespace AZ::Dom
|
||||
return Value(&value);
|
||||
}
|
||||
|
||||
Value::Value(int32_t value)
|
||||
: m_value(aznumeric_cast<int64_t>(value))
|
||||
{
|
||||
}
|
||||
|
||||
Value::Value(uint32_t value)
|
||||
: m_value(aznumeric_cast<uint64_t>(value))
|
||||
{
|
||||
}
|
||||
|
||||
Value::Value(int64_t value)
|
||||
: m_value(value)
|
||||
{
|
||||
@@ -107,6 +117,11 @@ namespace AZ::Dom
|
||||
{
|
||||
}
|
||||
|
||||
Value::Value(float value)
|
||||
: m_value(aznumeric_cast<double>(value))
|
||||
{
|
||||
}
|
||||
|
||||
Value::Value(double value)
|
||||
: m_value(value)
|
||||
{
|
||||
@@ -117,6 +132,40 @@ namespace AZ::Dom
|
||||
{
|
||||
}
|
||||
|
||||
Value::Value(Type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Type::NullType:
|
||||
// Null is the default initialized value
|
||||
break;
|
||||
case Type::FalseType:
|
||||
m_value = false;
|
||||
break;
|
||||
case Type::TrueType:
|
||||
m_value = true;
|
||||
break;
|
||||
case Type::ObjectType:
|
||||
SetObject();
|
||||
break;
|
||||
case Type::ArrayType:
|
||||
SetArray();
|
||||
break;
|
||||
case Type::StringType:
|
||||
SetString("");
|
||||
break;
|
||||
case Type::NumberType:
|
||||
m_value = 0.0;
|
||||
break;
|
||||
case Type::NodeType:
|
||||
SetNode("");
|
||||
break;
|
||||
case Type::OpaqueType:
|
||||
AZ_Assert(false, "AZ::Dom::Value may not be constructed with an empty opaque type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Value& Value::operator=(const Value& other)
|
||||
{
|
||||
m_value = other.m_value;
|
||||
@@ -139,11 +188,11 @@ namespace AZ::Dom
|
||||
{
|
||||
if (IsInt())
|
||||
{
|
||||
return GetInt() == rhs.GetInt();
|
||||
return GetInt64() == rhs.GetInt64();
|
||||
}
|
||||
else if (IsUint())
|
||||
{
|
||||
return GetUint() == rhs.GetUint();
|
||||
return GetUint64() == rhs.GetUint64();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -315,7 +364,7 @@ namespace AZ::Dom
|
||||
AZ_Assert(
|
||||
type == Type::ArrayType || type == Type::NodeType,
|
||||
"AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or a node");
|
||||
if (type == Type::ObjectType)
|
||||
if (type == Type::ArrayType)
|
||||
{
|
||||
return AZStd::get<ArrayPtr>(m_value)->m_values;
|
||||
}
|
||||
@@ -331,7 +380,7 @@ namespace AZ::Dom
|
||||
AZ_Assert(
|
||||
type == Type::ArrayType || type == Type::NodeType,
|
||||
"AZ::Dom::Value: attempted to retrieve an array from a value that isn't an array or node");
|
||||
if (type == Type::ObjectType)
|
||||
if (type == Type::ArrayType)
|
||||
{
|
||||
return CheckCopyOnWrite(AZStd::get<ArrayPtr>(m_value))->m_values;
|
||||
}
|
||||
@@ -702,7 +751,7 @@ namespace AZ::Dom
|
||||
return Value();
|
||||
}
|
||||
|
||||
int64_t Value::GetInt() const
|
||||
int64_t Value::GetInt64() const
|
||||
{
|
||||
switch (m_value.index())
|
||||
{
|
||||
@@ -717,12 +766,22 @@ namespace AZ::Dom
|
||||
return {};
|
||||
}
|
||||
|
||||
void Value::SetInt(int64_t value)
|
||||
void Value::SetInt64(int64_t value)
|
||||
{
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
uint64_t Value::GetUint() const
|
||||
int32_t Value::GetInt32() const
|
||||
{
|
||||
return aznumeric_cast<int32_t>(GetInt64());
|
||||
}
|
||||
|
||||
void Value::SetInt32(int32_t value)
|
||||
{
|
||||
m_value = aznumeric_cast<int64_t>(value);
|
||||
}
|
||||
|
||||
uint64_t Value::GetUint64() const
|
||||
{
|
||||
switch (m_value.index())
|
||||
{
|
||||
@@ -737,11 +796,21 @@ namespace AZ::Dom
|
||||
return {};
|
||||
}
|
||||
|
||||
void Value::SetUint(uint64_t value)
|
||||
void Value::SetUint64(uint64_t value)
|
||||
{
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
uint32_t Value::GetUint32() const
|
||||
{
|
||||
return aznumeric_cast<uint32_t>(GetUint64());
|
||||
}
|
||||
|
||||
void Value::SetUint32(uint32_t value)
|
||||
{
|
||||
m_value = aznumeric_cast<uint64_t>(value);
|
||||
}
|
||||
|
||||
bool Value::GetBool() const
|
||||
{
|
||||
if (IsBool())
|
||||
@@ -777,6 +846,16 @@ namespace AZ::Dom
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
float Value::GetFloat() const
|
||||
{
|
||||
return aznumeric_cast<float>(GetDouble());
|
||||
}
|
||||
|
||||
void Value::SetFloat(float value)
|
||||
{
|
||||
m_value = aznumeric_cast<double>(value);
|
||||
}
|
||||
|
||||
AZStd::string_view Value::GetString() const
|
||||
{
|
||||
switch (m_value.index())
|
||||
@@ -861,6 +940,11 @@ namespace AZ::Dom
|
||||
const Object::ContainerType& object = GetObjectInternal();
|
||||
for (const Object::EntryType& entry : object)
|
||||
{
|
||||
result = visitor.Key(entry.first);
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
return;
|
||||
}
|
||||
result = entry.second.Accept(visitor, copyStrings);
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
@@ -896,6 +980,11 @@ namespace AZ::Dom
|
||||
const Object::ContainerType& object = GetObjectInternal();
|
||||
for (const Object::EntryType& entry : object)
|
||||
{
|
||||
result = visitor.Key(entry.first);
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
return;
|
||||
}
|
||||
result = entry.second.Accept(visitor, copyStrings);
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
@@ -932,6 +1021,16 @@ namespace AZ::Dom
|
||||
|
||||
bool Value::DeepCompareIsEqual(const Value& other) const
|
||||
{
|
||||
if (IsString() && other.IsString())
|
||||
{
|
||||
// If we both hold the same ref counted string we don't need to do a full comparison
|
||||
if (AZStd::holds_alternative<AZStd::shared_ptr<AZStd::string>>(m_value) && m_value == other.m_value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return GetString() == other.GetString();
|
||||
}
|
||||
|
||||
if (m_value.index() != other.m_value.index())
|
||||
{
|
||||
return false;
|
||||
@@ -1045,4 +1144,12 @@ namespace AZ::Dom
|
||||
},
|
||||
m_value);
|
||||
}
|
||||
|
||||
Value Value::DeepCopy(bool copyStrings) const
|
||||
{
|
||||
Value newValue;
|
||||
AZStd::unique_ptr<Visitor> writer = newValue.GetWriteHandler();
|
||||
Accept(*writer, copyStrings);
|
||||
return newValue;
|
||||
}
|
||||
} // namespace AZ::Dom
|
||||
|
||||
@@ -109,10 +109,15 @@ namespace AZ::Dom
|
||||
Value(Value&&) noexcept;
|
||||
Value(AZStd::string_view string, bool copy);
|
||||
|
||||
explicit Value(int64_t value);
|
||||
explicit Value(uint64_t value);
|
||||
explicit Value(double value);
|
||||
explicit Value(bool value);
|
||||
Value(int32_t value);
|
||||
Value(uint32_t value);
|
||||
Value(int64_t value);
|
||||
Value(uint64_t value);
|
||||
Value(float value);
|
||||
Value(double value);
|
||||
Value(bool value);
|
||||
|
||||
explicit Value(Type type);
|
||||
|
||||
static Value FromOpaqueValue(AZStd::any& value);
|
||||
|
||||
@@ -226,12 +231,16 @@ namespace AZ::Dom
|
||||
Value GetNodeValue() const;
|
||||
|
||||
// int API...
|
||||
int64_t GetInt() const;
|
||||
void SetInt(int64_t);
|
||||
int64_t GetInt64() const;
|
||||
void SetInt64(int64_t);
|
||||
int32_t GetInt32() const;
|
||||
void SetInt32(int32_t);
|
||||
|
||||
// uint API...
|
||||
uint64_t GetUint() const;
|
||||
void SetUint(uint64_t);
|
||||
uint64_t GetUint64() const;
|
||||
void SetUint64(uint64_t);
|
||||
uint32_t GetUint32() const;
|
||||
void SetUint32(uint32_t);
|
||||
|
||||
// bool API...
|
||||
bool GetBool() const;
|
||||
@@ -240,6 +249,8 @@ namespace AZ::Dom
|
||||
// double API...
|
||||
double GetDouble() const;
|
||||
void SetDouble(double);
|
||||
float GetFloat() const;
|
||||
void SetFloat(float);
|
||||
|
||||
// string API...
|
||||
AZStd::string_view GetString() const;
|
||||
@@ -264,6 +275,7 @@ namespace AZ::Dom
|
||||
AZStd::unique_ptr<Visitor> GetWriteHandler();
|
||||
|
||||
bool DeepCompareIsEqual(const Value& other) const;
|
||||
Value DeepCopy(bool copyStrings = true) const;
|
||||
|
||||
private:
|
||||
const Node& GetNodeInternal() const;
|
||||
|
||||
@@ -39,13 +39,13 @@ namespace AZ::Dom
|
||||
|
||||
Visitor::Result ValueWriter::Int64(AZ::s64 value)
|
||||
{
|
||||
CurrentValue().SetInt(value);
|
||||
CurrentValue().SetInt64(value);
|
||||
return FinishWrite();
|
||||
}
|
||||
|
||||
Visitor::Result ValueWriter::Uint64(AZ::u64 value)
|
||||
{
|
||||
CurrentValue().SetUint(value);
|
||||
CurrentValue().SetUint64(value);
|
||||
return FinishWrite();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/DOM/Backends/JSON/JsonBackend.h>
|
||||
#include <AzCore/DOM/Backends/JSON/JsonSerializationUtils.h>
|
||||
#include <AzCore/DOM/DomUtils.h>
|
||||
#include <AzCore/DOM/DomValue.h>
|
||||
#include <AzCore/Name/NameDictionary.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/JsonUtils.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
namespace AZ::Dom::Tests
|
||||
{
|
||||
class DomValueTests : public UnitTest::AllocatorsFixture
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
UnitTest::AllocatorsFixture::SetUp();
|
||||
NameDictionary::Create();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_value = Value();
|
||||
|
||||
NameDictionary::Destroy();
|
||||
UnitTest::AllocatorsFixture::TearDown();
|
||||
}
|
||||
|
||||
void PerformValueChecks()
|
||||
{
|
||||
Value shallowCopy = m_value;
|
||||
EXPECT_EQ(m_value, shallowCopy);
|
||||
EXPECT_TRUE(m_value.DeepCompareIsEqual(shallowCopy));
|
||||
|
||||
Value deepCopy = m_value.DeepCopy();
|
||||
EXPECT_TRUE(m_value.DeepCompareIsEqual(deepCopy));
|
||||
}
|
||||
|
||||
Value m_value;
|
||||
};
|
||||
|
||||
TEST_F(DomValueTests, EmptyArray)
|
||||
{
|
||||
m_value.SetArray();
|
||||
|
||||
EXPECT_TRUE(m_value.IsArray());
|
||||
EXPECT_EQ(m_value.Size(), 0);
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, SimpleArray)
|
||||
{
|
||||
m_value.SetArray();
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
m_value.PushBack(Value(i));
|
||||
EXPECT_EQ(m_value.Size(), i + 1);
|
||||
EXPECT_EQ(m_value[i].GetInt32(), i);
|
||||
}
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, NestedArrays)
|
||||
{
|
||||
m_value.SetArray();
|
||||
for (int j = 0; j < 5; ++j)
|
||||
{
|
||||
Value nestedArray(Type::ArrayType);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
nestedArray.PushBack(Value(i));
|
||||
}
|
||||
m_value.PushBack(AZStd::move(nestedArray));
|
||||
}
|
||||
|
||||
EXPECT_EQ(m_value.Size(), 5);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
EXPECT_EQ(m_value[i].Size(), 5);
|
||||
for (int j = 0; j < 5; ++j)
|
||||
{
|
||||
EXPECT_EQ(m_value[i][j].GetInt32(), j);
|
||||
}
|
||||
}
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, EmptyObject)
|
||||
{
|
||||
m_value.SetObject();
|
||||
EXPECT_EQ(m_value.MemberCount(), 0);
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, SimpleObject)
|
||||
{
|
||||
m_value.SetObject();
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
AZStd::string key = AZStd::string::format("Key%i", i);
|
||||
m_value.AddMember(key, Value(i));
|
||||
EXPECT_EQ(m_value.MemberCount(), i + 1);
|
||||
EXPECT_EQ(m_value[key].GetInt32(), i);
|
||||
}
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, NestedObjects)
|
||||
{
|
||||
m_value.SetObject();
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
Value nestedObject(Type::ObjectType);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
nestedObject.AddMember(AZStd::string::format("Key%i", i), Value(i));
|
||||
}
|
||||
m_value.AddMember(AZStd::string::format("Obj%i", j), AZStd::move(nestedObject));
|
||||
}
|
||||
|
||||
EXPECT_EQ(m_value.MemberCount(), 3);
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
const Value& nestedObject = m_value[AZStd::string::format("Obj%i", j)];
|
||||
EXPECT_EQ(nestedObject.MemberCount(), 5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
EXPECT_EQ(nestedObject[AZStd::string::format("Key%i", i)].GetInt32(), i);
|
||||
}
|
||||
}
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, EmptyNode)
|
||||
{
|
||||
m_value.SetNode("Test");
|
||||
EXPECT_EQ(m_value.GetNodeName(), AZ::Name("Test"));
|
||||
EXPECT_EQ(m_value.MemberCount(), 0);
|
||||
EXPECT_EQ(m_value.Size(), 0);
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, SimpleNode)
|
||||
{
|
||||
m_value.SetNode("Test");
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
m_value.PushBack(Value(i));
|
||||
EXPECT_EQ(m_value.Size(), i + 1);
|
||||
EXPECT_EQ(m_value[i].GetInt32(), i);
|
||||
|
||||
if (i < 5)
|
||||
{
|
||||
AZ::Name key = AZ::Name(AZStd::string::format("TwoTimes%i", i));
|
||||
m_value.AddMember(key, Value(i * 2));
|
||||
EXPECT_EQ(m_value.MemberCount(), i + 1);
|
||||
EXPECT_EQ(m_value[key].GetInt32(), i * 2);
|
||||
}
|
||||
}
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
|
||||
TEST_F(DomValueTests, NestedNodes)
|
||||
{
|
||||
m_value.SetNode("TopLevel");
|
||||
|
||||
const AZ::Name childNodeName("ChildNode");
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
Value childNode(Type::NodeType);
|
||||
childNode.SetNodeName(childNodeName);
|
||||
childNode.SetNodeValue(i);
|
||||
|
||||
childNode.AddMember("foo", i);
|
||||
childNode.AddMember("bar", Value("test", false));
|
||||
|
||||
m_value.PushBack(childNode);
|
||||
}
|
||||
|
||||
EXPECT_EQ(m_value.Size(), 5);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
const Value& childNode = m_value[i];
|
||||
EXPECT_EQ(childNode.GetNodeName(), childNodeName);
|
||||
EXPECT_EQ(childNode.GetNodeValue().GetInt32(), i);
|
||||
EXPECT_EQ(childNode["foo"].GetInt32(), i);
|
||||
EXPECT_EQ(childNode["bar"].GetString(), "test");
|
||||
}
|
||||
|
||||
PerformValueChecks();
|
||||
}
|
||||
} // namespace AZ::Dom::Tests
|
||||
@@ -215,6 +215,8 @@ set(FILES
|
||||
AZStd/VectorAndArray.cpp
|
||||
DOM/DomJsonTests.cpp
|
||||
DOM/DomJsonBenchmarks.cpp
|
||||
DOM/DomValueTests.cpp
|
||||
DOM/DomValueBenchmarks.cpp
|
||||
)
|
||||
|
||||
# Prevent the following files from being grouped in UNITY builds
|
||||
|
||||
Reference in New Issue
Block a user